*******************************************************************************/\r
package org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.test.stub.model;\r
\r
+import java.util.Iterator;\r
import java.util.Vector;\r
\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
-import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.TimeEvent;\r
\r
@SuppressWarnings("nls")\r
public class TraceImpl implements ITmfTimeAnalysisEntry {\r
private long stopTime = 1;\r
private String groupName = "defaultGroupName";\r
private String className = "defaultClassName";\r
- private Vector<TimeEvent> traceEvents = new Vector<TimeEvent>();\r
+ private Vector<ITimeEvent> traceEvents = new Vector<ITimeEvent>();\r
\r
// ========================================================================\r
// Constructor\r
}\r
\r
@Override\r
- @SuppressWarnings("unchecked")\r
- public Vector<TimeEvent> getTraceEvents() {\r
+ @Deprecated public Vector<ITimeEvent> getTraceEvents() {\r
return traceEvents;\r
}\r
+ \r
+ @Override\r
+ public Iterator<ITimeEvent> getTraceEventsIterator() {\r
+ return traceEvents.iterator();\r
+ }\r
+\r
+ @Override\r
+ public Iterator<ITimeEvent> getTraceEventsIterator(long startTime, long stopTime, long maxDuration) {\r
+ return traceEvents.iterator();\r
+ }\r
+\r
+ @Override\r
+ public void addTraceEvent(ITimeEvent event) {\r
+ traceEvents.add(event);\r
+ }\r
\r
}\r
\r
event = new EventImpl(eventTime, trace, getEventType(i%16));\r
event.setDuration(duration);\r
- trace.getTraceEvents().add(event);\r
+ trace.addTraceEvent(event);\r
}\r
}\r
\r
// duration = i + (long) ((i % 4));\r
event = new EventImpl(eventTime, trace, getEventType(i));\r
event.setDuration(duration);\r
- trace.getTraceEvents().add(event);\r
+ trace.addTraceEvent(event);\r
}\r
}\r
\r
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewerFactory;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer;
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeSelectionListener;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
-import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
import org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.test.stub.adaption.TsfImplProvider;
import org.eclipse.linuxtools.tmf.ui.widgets.timeAnalysis.test.stub.model.EventImpl;
viewer.getControl().setFocus();
}
- @Override
+ @SuppressWarnings("deprecation")
+ @Override
public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {
Object source = event.getSource();
if (source == null || !(source instanceof ITimeAnalysisViewer)) {
org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.widgets,
org.eclipse.linuxtools.tmf.ui.views,
org.eclipse.linuxtools.tmf.ui.views.project,
+ org.eclipse.linuxtools.tmf.ui.views.timechart,
org.eclipse.linuxtools.tmf.ui.widgets
Bundle-Localization: plugin
views.category.name = TMF
project.view.name = Projects
events.view.name = Events
+timechart.view.name = Time Chart
events.editor.name = Events
wizard.category.name = TMF
name="%events.view.name"\r
restorable="true">\r
</view>\r
+ <view\r
+ category="org.eclipse.linuxtools.tmf.ui.views.category"\r
+ class="org.eclipse.linuxtools.tmf.ui.views.timechart.TimeChartView"\r
+ icon="icons/eview16/timechart_view.gif"\r
+ id="org.eclipse.linuxtools.tmf.ui.views.timechart"\r
+ name="%timechart.view.name"\r
+ restorable="true">\r
+ </view>\r
</extension>\r
<extension\r
point="org.eclipse.ui.editors">\r
<extension\r
point="org.eclipse.core.contenttype.contentTypes">\r
<content-type\r
- file-extensions="log"\r
id="org.eclipse.linuxtools.tmf.ui.content-type.trace"\r
name="%contenttype.trace"\r
priority="normal">\r
\r
public void setItemHeight(int rowHeight);\r
\r
+ public void setMinimumItemWidth(int width);\r
+\r
public void resizeControls();\r
\r
public void setSelectedTrace(ITmfTimeAnalysisEntry trace);\r
\r
package org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis;\r
\r
-import java.util.List;\r
import java.util.Map;\r
\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
-import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.TimeEvent;\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.widgets.TraceColorScheme;\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.graphics.GC;\r
if (threadClass != null && threadClass.length() > 0) {\r
name += " [" + threadClass + "]"; //$NON-NLS-1$ //$NON-NLS-2$\r
}\r
+ /*\r
+ * Check if this is still necessary!\r
if (inclState) {\r
List<TimeEvent> list = trace.getTraceEvents();\r
if (null != list && list.size() > 0) {\r
name += " (" + getEventName(event, false, true) + ")"; //$NON-NLS-1$ //$NON-NLS-2$\r
}\r
}\r
+ */\r
return name;\r
}\r
\r
package org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis;\r
\r
import java.util.Iterator;\r
-import java.util.List;\r
import java.util.Vector;\r
\r
import org.eclipse.jface.viewers.ISelection;\r
// called from the display order in the API\r
public void modelUpdate(ITmfTimeAnalysisEntry[] traces) {\r
if (null != _stateCtrl) {\r
- loadOptions();\r
+ //loadOptions();\r
updateInternalData(traces);\r
_stateCtrl.redraw();\r
_timeScaleCtrl.redraw();\r
public void modelUpdate(ITmfTimeAnalysisEntry[] traces, long start,\r
long end, boolean updateTimeBounds) {\r
if (null != _stateCtrl) {\r
- loadOptions();\r
+ //loadOptions();\r
updateInternalData(traces, start, end);\r
if (updateTimeBounds) {\r
_timeRangeFixed = true;\r
void setTimeRange(Object traces[]) {\r
_endTime = 0;\r
_beginTime = -1;\r
- ITimeEvent event;\r
+// ITimeEvent event;\r
for (int i = 0; i < traces.length; i++) {\r
ITmfTimeAnalysisEntry entry = (ITmfTimeAnalysisEntry) traces[i];\r
if (entry.getStopTime() >= entry.getStartTime() && entry.getStopTime() > 0) {\r
_endTime = entry.getStopTime();\r
}\r
}\r
+ /*\r
+ * This is not needed if entry startTime and stopTime are properly set!\r
List<TimeEvent> list = entry.getTraceEvents();\r
int len = list.size();\r
if (len > 0) {\r
_endTime = eventEndTime;\r
}\r
}\r
+ */\r
}\r
\r
if (_beginTime < 0)\r
_selectedTime = _endTime;\r
if (_selectedTime < _beginTime)\r
_selectedTime = _beginTime;\r
+ long time0 = _time0;\r
+ long time1 = _time1;\r
if (ensureVisible) {\r
double timeSpace = (_time1 - _time0) * .02;\r
double timeMid = (_time1 - _time0) * .1;\r
_stateCtrl.adjustScrolls();\r
_stateCtrl.redraw();\r
_timeScaleCtrl.redraw();\r
+ if (time0 != _time0 || time1 != _time1) {\r
+ notifyStartFinishTimeSelectionListeners(_time0, _time1);\r
+ }\r
}\r
\r
@Override\r
}\r
}\r
\r
+ @Override\r
+ public void setMinimumItemWidth(int width) {\r
+ if (_stateCtrl != null) {\r
+ _stateCtrl.setMinimumItemWidth(width);\r
+ }\r
+ }\r
+ \r
@Override\r
public boolean isVisibleVerticalScroll() {\r
if (_stateCtrl != null) {\r
\r
package org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model;\r
\r
+import java.util.Iterator;\r
import java.util.Vector;\r
\r
public interface ITmfTimeAnalysisEntry {\r
\r
public long getStopTime();\r
\r
- public <T extends ITimeEvent> Vector<T> getTraceEvents();\r
+ /**\r
+ * Get a vector containing all events\r
+ * @deprecated replaced by {@link #getTraceEventsIterator()}\r
+ */\r
+ @Deprecated public <T extends ITimeEvent> Vector<T> getTraceEvents();\r
+ \r
+ /**\r
+ * Get an iterator which returns all events\r
+ */\r
+ public <T extends ITimeEvent> Iterator<T> getTraceEventsIterator();\r
+ \r
+ /**\r
+ * Get an iterator which only returns events that fall within the start time and the stop time.\r
+ * The visible duration is the event duration below which further detail is not discernible.\r
+ * If no such iterator is implemented, provide a basic iterator which returns all events.\r
+ * \r
+ * @param startTime start time in nanoseconds\r
+ * @param stopTime stop time in nanoseconds\r
+ * @param visibleDuration duration of one pixel in nanoseconds\r
+ */\r
+ public <T extends ITimeEvent> Iterator<T> getTraceEventsIterator(long startTime, long stopTime, long visibleDuration);\r
+ \r
+ public <T extends ITimeEvent> void addTraceEvent(T event);\r
}\r
unit = MIN_IN_NS;\r
} else if (minDelta > 20 * SEC_IN_NS) {\r
unit = 30 * SEC_IN_NS;\r
+ } else if (minDelta <= 1) {\r
+ _timeDelta = 1;\r
+ return;\r
}\r
}\r
double log = Math.log10((double) minDelta / unit);\r
*/\r
public class TmfTimeStatesCtrl extends TraceCtrl implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider {\r
\r
+ private static final int DRAG_NONE = 0;\r
+ private static final int DRAG_TRACE_ITEM = 1;\r
+ private static final int DRAG_GROUP_ITEM = 2;\r
+ private static final int DRAG_SPLIT_LINE = 3;\r
public static final boolean DEFAULT_DRAW_THREAD_JOIN = true;\r
public static final boolean DEFAULT_DRAW_THREAD_WAIT = true;\r
public static final boolean DEFAULT_DRAW_THREAD_RELEASE = true;\r
private boolean _mouseHover = false;\r
private int _itemHeightDefault = 19;\r
private int _itemHeight = _itemHeightDefault;\r
+ private int _minimumItemWidth = 0;\r
private int _topItem = 0;\r
- private int _dragState = 0;\r
+ private int _dragState = DRAG_NONE;\r
private int _hitIdx = 0;\r
private int _dragX0 = 0;\r
private int _dragX = 0;\r
if (scrollHor != null) {\r
scrollHor.addSelectionListener(this);\r
}\r
- mouseScrollFilterListener = new Listener() {\r
- // This filter is used to prevent scrolling of the view when the\r
- // mouse wheel is used to zoom\r
- @Override\r
- public void handleEvent(Event event) {\r
- event.doit = false;\r
- }\r
- };\r
\r
_dragCursor3 = new Cursor(super.getDisplay(), SWT.CURSOR_SIZEWE);\r
_WaitCursor = new Cursor(super.getDisplay(), SWT.CURSOR_WAIT);\r
if (zoomIn) {\r
newInterval = Math.max(Math.round((double) interval * 0.8), _timeProvider.getMinTimeInterval());\r
} else {\r
- newInterval = Math.round((double) interval * 1.25);\r
+ newInterval = (long) Math.ceil((double) interval * 1.25);\r
}\r
long center = time0 + Math.round(((double) (xPos - nameSpace) / timeSpace * interval));\r
long newTime0 = center - Math.round((double) newInterval * (center - time0) / interval);\r
return idx >= 0 ? (Item) _data._items[idx] : null;\r
}\r
\r
- long hitTimeTest(int x, int y) {\r
+ long hitTimeTest(int x) {\r
if (null == _timeProvider)\r
return -1;\r
long hitTime = -1;\r
}\r
\r
void selectItem(int idx, boolean addSelection) {\r
+ boolean changed = false;\r
if (addSelection) {\r
if (idx >= 0 && idx < _data._items.length) {\r
Item item = (Item) _data._items[idx];\r
+ changed = (item._selected == false);\r
item._selected = true;\r
}\r
} else {\r
for (int i = 0; i < _data._items.length; i++) {\r
Item item = (Item) _data._items[i];\r
+ if (i == idx && item._selected == false) {\r
+ changed = true;\r
+ }\r
item._selected = i == idx;\r
}\r
}\r
- boolean changed = ensureVisibleItem(idx, true);\r
- if (!changed)\r
+ changed |= ensureVisibleItem(idx, true);\r
+ if (changed)\r
redraw();\r
}\r
\r
public void selectItem(ITmfTimeAnalysisEntry trace, boolean addSelection) {\r
Integer idx = _data.findTraceItemIndex(trace);\r
- selectItem(idx, addSelection);\r
+ if (idx != null) {\r
+ selectItem(idx, addSelection);\r
+ }\r
}\r
\r
public int countPerPage() {\r
if (drawTracesInteraction)\r
drawTraceInteractions(bound, e.gc);\r
\r
+ // draw empty name space background\r
+ if (_itemHeight * items.length < bound.height) {\r
+ gc.setBackground(_colors.getBkColor(false, false, true));\r
+ drawBackground(gc, bound.x, _itemHeight * items.length, nameWidth, bound.height - _itemHeight * items.length);\r
+ }\r
+\r
// draw drag line, no line if name space is 0.\r
- if (3 == _dragState) {\r
+ if (DRAG_SPLIT_LINE == _dragState) {\r
gc.setForeground(_colors.getColor(TraceColorScheme.BLACK));\r
gc.drawLine(bound.x + nameWidth, bound.y, bound.x + nameWidth, bound.y + bound.height - 1);\r
- } else if (0 == _dragState && _mouseHover && _timeProvider.getNameSpace() > 0) {\r
+ } else if (DRAG_NONE == _dragState && _mouseHover && _timeProvider.getNameSpace() > 0) {\r
gc.setForeground(_colors.getColor(TraceColorScheme.RED));\r
gc.drawLine(bound.x + nameWidth, bound.y, bound.x + nameWidth, bound.y + bound.height - 1);\r
}\r
ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
\r
int x0 = rect.x;\r
- List<TimeEvent> list = trace.getTraceEvents();\r
- // Iterator it = list.iterator();\r
- int count = list.size();\r
+ Iterator<ITimeEvent> iterator = trace.getTraceEventsIterator();\r
ITimeEvent lastEvent = null;\r
- if (count > 0) {\r
- ITimeEvent currEvent = list.get(0);\r
+ if (iterator.hasNext()) {\r
+ ITimeEvent currEvent = iterator.next();\r
ITimeEvent nextEvent = null;\r
long currEventTime = currEvent.getTime();\r
long nextEventTime = currEventTime;\r
// reduce rect\r
_rect1.y += 3;\r
_rect1.height -= 6;\r
- fillSpace(rect, gc, selected, _rect1.x, x0, xEnd);\r
+ fillSpace(rect, gc, selected);\r
\r
// draw event states\r
while (x0 <= xEnd && null != currEvent) {\r
boolean stopped = false;// currEvent instanceof\r
// TsfTmTraceDeadEvent;\r
- if (idx < count) {\r
- nextEvent = list.get(idx);\r
+ if (iterator.hasNext()) {\r
+ nextEvent = iterator.next();\r
nextEventTime = nextEvent.getTime();\r
idx++;\r
} else if (stopped) {\r
gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
gc.setLineWidth(lw);\r
}\r
-\r
- // draw focus ares\r
- Utils.init(_rect1, rect);\r
- gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
- int y = _rect1.y;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y = _rect1.y + _rect1.height - 1;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
}\r
\r
// draw selected time\r
ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
\r
double x0 = rect.x;\r
- List<TimeEvent> list = trace.getTraceEvents();\r
- // Iterator it = list.iterator();\r
- int count = list.size();\r
+ Iterator<ITimeEvent> iterator = trace.getTraceEventsIterator();\r
ITimeEvent lastEvent = null;\r
// Trace.debug("count is: " + count);\r
- if (count > 0) {\r
- ITimeEvent currEvent = list.get(0);\r
+ if (iterator.hasNext()) {\r
+ ITimeEvent currEvent = iterator.next();\r
ITimeEvent nextEvent = null;\r
long currEventTime = currEvent.getTime();\r
long nextEventTime = currEventTime;\r
double xEnd = rect.x + (double) ((time1 - time0) * pixelsPerNanoSec);\r
double x1 = -1;\r
int idx = 1;\r
- double xNext = 0;\r
+ //double xNext = 0;\r
\r
// Drawing rectangle is smaller than reserved space\r
_rect1.y += 3;\r
_rect1.height -= 6;\r
\r
// Clean up to empty line to draw on top\r
- fillSpace(rect, gc, selected, _rect1.x, xEnd, xEnd);\r
+ fillSpace(rect, gc, selected);\r
// draw event states\r
while (x0 <= xEnd && null != currEvent) {\r
boolean stopped = false;// currEvent instanceof\r
// TsfTmTraceDeadEvent;\r
- if (idx < count) {\r
- nextEvent = list.get(idx);\r
+ if (iterator.hasNext()) {\r
+ nextEvent = iterator.next();\r
nextEventTime = nextEvent.getTime();\r
idx++;\r
} else if (stopped) {\r
// with space until next event\r
_rect1.x += _rect1.width;\r
x0 = x1;\r
- xNext = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
+ //xNext = rect.x + (double) ((nextEventTime - time0) * pixelsPerNanoSec);\r
}\r
// Fill space till next event\r
- fillSpace(rect, gc, selected, x0, xNext, xEnd);\r
+ fillSpace(rect, gc, selected);\r
\r
lastEvent = currEvent;\r
currEvent = nextEvent;\r
gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
gc.setLineWidth(lw);\r
}\r
-\r
- // draw focus area\r
- Utils.init(_rect1, rect);\r
- gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
- int y = _rect1.y;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y = _rect1.y + _rect1.height - 1;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
}\r
\r
// draw selected time\r
ITmfTimeAnalysisEntry trace = ((TraceItem) item)._trace;\r
\r
double x0 = rect.x;\r
- @SuppressWarnings("unchecked")\r
- List<TimeEvent> list = (List<TimeEvent>) trace.getTraceEvents().clone();\r
- // Iterator it = list.iterator();\r
- int count = list.size();\r
+ long maxDuration = (_timeProvider.getTimeSpace() == 0) ? Long.MAX_VALUE : 1 * (_timeProvider.getTime1() - _timeProvider.getTime0()) / _timeProvider.getTimeSpace();\r
+ Iterator<ITimeEvent> iterator = trace.getTraceEventsIterator(_timeProvider.getTime0(), _timeProvider.getTime1(), maxDuration);\r
// ITimeEvent lastEvent = null;\r
// if (Trace.isDEBUG()) {\r
// Trace.debug("\n\t\t\tTrace: " + trace.getName()\r
\r
// Clean up to empty line to draw on top\r
int xEnd = rect.x + rect.width;\r
- fillSpace(rect, gc, selected, _rect1.x, xEnd, xEnd);\r
- if (count > 0) {\r
- ITimeEvent currEvent = list.get(0);\r
+ fillSpace(rect, gc, selected);\r
+ if (iterator.hasNext()) {\r
+ ITimeEvent currEvent = iterator.next();\r
ITimeEvent nextEvent = null;\r
long currEventTime = currEvent.getTime();\r
long currEventDuration = currEvent.getDuration();\r
// refresh current event duration as the loop moves\r
currEventDuration = currEvent.getDuration();\r
// TsfTmTraceDeadEvent;\r
- if (idx < count) {\r
- nextEvent = list.get(idx);\r
+ if (iterator.hasNext()) {\r
+ nextEvent = iterator.next();\r
nextEventTime = nextEvent.getTime();\r
idx++;\r
} else if (stopped) {\r
if (x1 >= rect.x && x0 <= xEnd) {\r
if (currEventDuration != 0) {\r
x0 = (double) (x0 >= rect.x ? x0 : rect.x);\r
- _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);\r
+ _rect1.width = (int) Math.ceil(x1 <= xEnd ? x1 : xEnd) - (int) x0;\r
} else {\r
- _rect1.width = 2; // make punctual events 2 pixels\r
- // wide\r
+ _rect1.width = 1;\r
}\r
+ _rect1.width = Math.max(_minimumItemWidth, _rect1.width);\r
_rect1.x = (int) x0;\r
boolean timeSelected = currEventTime <= selectedTime && selectedTime < nextEventTime;\r
utilImpl.drawState(_colors, currEvent, _rect1, gc, selected, false, timeSelected);\r
// + K + " = " + x0);\r
}\r
}\r
-\r
- // draw focus area\r
- Utils.init(_rect1, rect);\r
- gc.setForeground(_colors.getBkColor(selected, _isInFocus, false));\r
- int y = _rect1.y;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y++;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y = _rect1.y + _rect1.height - 1;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
- y--;\r
- gc.drawLine(_rect1.x, y, _rect1.x + _rect1.width, y);\r
}\r
\r
// draw selected time\r
}\r
}\r
\r
- private void fillSpace(Rectangle rect, GC gc, boolean selected, double x0, double x1, double xEnd) {\r
- // fill space before first event\r
- if (x0 >= rect.x && x0 < xEnd) {\r
- // _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);\r
- // Trace.debug("Drawing Space: " + _rect1.x + "," + _rect1.y + ","\r
- // + _rect1.height + ", " + _rect1.width + "--> "\r
- // + ((int) _rect1.x + (int) _rect1.width));\r
-\r
- // if (_rect1.width < 0) {\r
- // Trace.debug("Incorrect width:" + _rect1.width);\r
- // }\r
- gc.setBackground(_colors.getBkColor(selected, _isInFocus, false));\r
- gc.fillRectangle(_rect1);\r
- // draw middle line\r
- gc.setForeground(_colors.getColor(TraceColorScheme.MID_LINE));\r
- int midy = _rect1.y + _rect1.height / 2;\r
- gc.drawLine(_rect1.x, midy, _rect1.x + _rect1.width, midy);\r
- } else {\r
- // Trace.debug("No space added since, x0 is out of range " + x0\r
- // + " rect.x: " + rect.x + " xEnd: " + xEnd);\r
- }\r
+ private void fillSpace(Rectangle rect, GC gc, boolean selected) {\r
+ gc.setBackground(_colors.getBkColor(selected, _isInFocus, false));\r
+ gc.fillRectangle(rect);\r
+ // draw middle line\r
+ gc.setForeground(_colors.getColor(TraceColorScheme.MID_LINE));\r
+ int midy = rect.y + rect.height / 2;\r
+ gc.drawLine(rect.x, midy, rect.x + rect.width, midy);\r
}\r
\r
@Override\r
public void focusGained(FocusEvent e) {\r
_isInFocus = true;\r
redraw();\r
- getDisplay().addFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
+ if (mouseScrollFilterListener == null) {\r
+ mouseScrollFilterListener = new Listener() {\r
+ // This filter is used to prevent scrolling of the view when the\r
+ // mouse wheel is used to zoom\r
+ @Override\r
+ public void handleEvent(Event event) {\r
+ event.doit = false;\r
+ }\r
+ };\r
+ getDisplay().addFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
+ }\r
}\r
\r
@Override\r
public void focusLost(FocusEvent e) {\r
_isInFocus = false;\r
- if (0 != _dragState) {\r
+ if (DRAG_NONE != _dragState) {\r
setCapture(false);\r
- _dragState = 0;\r
+ _dragState = DRAG_NONE;\r
}\r
redraw();\r
- getDisplay().removeFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
+ if (mouseScrollFilterListener != null) {\r
+ getDisplay().removeFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
+ mouseScrollFilterListener = null;\r
+ }\r
}\r
\r
public boolean isInFocus() {\r
if (null == _timeProvider)\r
return;\r
Point size = getCtrlSize();\r
- if (1 == _dragState) {\r
+ if (DRAG_TRACE_ITEM == _dragState) {\r
int nameWidth = _timeProvider.getNameSpace();\r
int x = e.x - nameWidth;\r
if (x > 0 && size.x > nameWidth && _dragX != x) {\r
}\r
_timeProvider.setStartFinishTime(time0, time1);\r
}\r
- } else if (3 == _dragState) {\r
+ } else if (DRAG_SPLIT_LINE == _dragState) {\r
_dragX = e.x;\r
_timeProvider.setNameSpace(_hitIdx + _dragX - _dragX0);\r
- } else if (0 == _dragState) {\r
+ } else if (DRAG_NONE == _dragState) {\r
boolean mouseHover = hitSplitTest(e.x, e.y) > 0;\r
if (_mouseHover != mouseHover)\r
redraw();\r
if (namewidth != 0) {\r
idx = hitSplitTest(e.x, e.y);\r
if (idx > 0) {\r
- _dragState = 3;\r
+ _dragState = DRAG_SPLIT_LINE;\r
_dragX = _dragX0 = e.x;\r
_hitIdx = _timeProvider.getNameSpace();\r
;\r
idx = hitTest(e.x, e.y);\r
if (idx >= 0) {\r
if (_data._items[idx] instanceof TraceItem) {\r
- long hitTime = hitTimeTest(e.x, e.y);\r
+ long hitTime = hitTimeTest(e.x);\r
if (hitTime >= 0) {\r
- _timeProvider.setSelectedTimeInt(hitTime, false);\r
+ // _timeProvider.setSelectedTimeInt(hitTime, false);\r
setCapture(true);\r
- _dragState = 1;\r
+ _dragState = DRAG_TRACE_ITEM;\r
_dragX = _dragX0 = e.x - _timeProvider.getNameSpace();\r
+ _hitIdx = idx;\r
_time0bak = _timeProvider.getTime0();\r
_time1bak = _timeProvider.getTime1();\r
+ return;\r
}\r
} else if (_data._items[idx] instanceof GroupItem) {\r
- _hitIdx = idx;\r
- _dragState = 2;\r
+ _dragX0 = e.x;\r
+ _dragState = DRAG_GROUP_ITEM;\r
}\r
selectItem(idx, false);\r
fireSelectionChanged();\r
} else {\r
selectItem(idx, false); // clear selection\r
+ redraw();\r
}\r
}\r
}\r
\r
@Override\r
public void mouseUp(MouseEvent e) {\r
- if (0 != _dragState) {\r
+ if (DRAG_NONE != _dragState) {\r
setCapture(false);\r
- if (1 == _dragState) {\r
+ if (DRAG_TRACE_ITEM == _dragState) {\r
// Notify time provider to check the need for listener\r
// notification\r
_timeProvider.notifyStartFinishTime();\r
- } else if (2 == _dragState) {\r
- if (hitTest(e.x, e.y) == _hitIdx)\r
+ if (_dragX == _dragX0) { // click without drag\r
+ long time = hitTimeTest(e.x);\r
+ _timeProvider.setSelectedTimeInt(time, false);\r
+ selectItem(_hitIdx, false);\r
+ fireSelectionChanged();\r
+ }\r
+ } else if (DRAG_GROUP_ITEM == _dragState) {\r
+ if (e.x == _dragX0) // click without drag\r
toggle(_hitIdx);\r
- } else if (3 == _dragState) {\r
+ } else if (DRAG_SPLIT_LINE == _dragState) {\r
redraw();\r
}\r
- _dragState = 0;\r
+ _dragState = DRAG_NONE;\r
}\r
}\r
\r
\r
@Override\r
public void mouseScrolled(MouseEvent e) {\r
- if (!_isInFocus)\r
+ if (!_isInFocus || _dragState != DRAG_NONE)\r
return;\r
if (e.count > 0) {\r
zoom(true);\r
this._itemHeight = rowHeight;\r
}\r
\r
+ public void setMinimumItemWidth(int width) {\r
+ this._minimumItemWidth = width;\r
+ }\r
+\r
public Vector<ITmfTimeAnalysisEntry> getFilteredOut() {\r
return _data.getFilteredOut();\r
}\r
if (trace == null)\r
return null;\r
\r
- int traceId = trace.getId();\r
-\r
- Integer idx = null;\r
for (int i = 0; i < _items.length; i++) {\r
- idx = i;\r
Object item = _items[i];\r
if (item instanceof TraceItem) {\r
TraceItem ti = (TraceItem) item;\r
- if (ti._trace.getId() == traceId) {\r
- break;\r
+ if (ti._trace == trace) {\r
+ return i;\r
}\r
}\r
}\r
\r
- return idx;\r
+ return null;\r
}\r
\r
public void updateItems() {\r
*/\r
public void refreshPartial(ITmfTimeAnalysisEntry parent, TimeEvent childItem) {\r
// Find the Trace item within the current list\r
- TraceItem item = findTraceItem(parent);\r
+// TraceItem item = findTraceItem(parent);\r
\r
// This method is not used (yet) so this code can be commented out for\r
// now\r
// item = findTraceItem(parent);\r
// }\r
\r
+ /*\r
+ * Check if this is still needed!\r
ITmfTimeAnalysisEntry localTraceItem = item._trace;\r
// Local trace found\r
Vector<TimeEvent> children = localTraceItem.getTraceEvents();\r
}\r
// Add the new item\r
children.add(childItem);\r
+ */\r
\r
}\r
\r
Item item) {\r
if (item instanceof TraceItem) {\r
ITmfTimeAnalysisEntry thrd = ((TraceItem) item)._trace;\r
- ITimeEvent threadEvent = Utils.findEvent(thrd, threadStates\r
- .hitTimeTest(pt.x, pt.y), 2);\r
- ITimeEvent nextEvent = Utils.findEvent(thrd, threadStates\r
- .hitTimeTest(pt.x, pt.y), 1);\r
+ ITimeEvent threadEvent = Utils.findEvent(thrd, threadStates.hitTimeTest(pt.x), 2);\r
+ ITimeEvent nextEvent = Utils.findEvent(thrd, threadStates.hitTimeTest(pt.x), 1);\r
// thread name\r
addItem(Messages.TmfTimeTipHandler_TRACE_NAME, thrd.getName());\r
// class name\r
// This block receives a\r
// list of <String, String> values to be added to the tip\r
// table\r
- Map<String, String> eventAddOns = _utilImp\r
- .getEventHoverToolTipInfo(threadEvent);\r
- for (Iterator<String> iter = eventAddOns.keySet()\r
- .iterator(); iter.hasNext();) {\r
- String message = (String) iter.next();\r
- addItem(message, eventAddOns.get(message));\r
+ Map<String, String> eventAddOns = _utilImp.getEventHoverToolTipInfo(threadEvent);\r
+ if (eventAddOns != null) {\r
+ for (Iterator<String> iter = eventAddOns.keySet().iterator(); iter.hasNext();) {\r
+ String message = (String) iter.next();\r
+ addItem(message, eventAddOns.get(message));\r
+ }\r
}\r
\r
long eventStartTime = -1;\r
import java.text.SimpleDateFormat;\r
import java.util.Date;\r
import java.util.Iterator;\r
-import java.util.List;\r
import java.util.TimeZone;\r
-import java.util.Vector;\r
\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer.TimeFormat;\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
-import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.TimeEvent;\r
import org.eclipse.swt.graphics.Color;\r
import org.eclipse.swt.graphics.Device;\r
import org.eclipse.swt.graphics.GC;\r
static ITimeEvent getFirstEvent(ITmfTimeAnalysisEntry thread) {\r
if (null == thread)\r
return null;\r
- Vector<TimeEvent> list = thread.getTraceEvents();\r
- ITimeEvent event = null;\r
- if (!list.isEmpty())\r
- event = (ITimeEvent) list.get(0);\r
- return event;\r
+ Iterator<ITimeEvent> iterator = thread.getTraceEventsIterator();\r
+ if (iterator.hasNext()) {\r
+ return iterator.next();\r
+ } else {\r
+ return null;\r
+ }\r
}\r
\r
/**\r
static ITimeEvent findEvent(ITmfTimeAnalysisEntry thread, long time, int n) {\r
if (null == thread)\r
return null;\r
- List<TimeEvent> list = thread.getTraceEvents();\r
- Iterator<TimeEvent> it = list.iterator();\r
+ Iterator<ITimeEvent> iterator = thread.getTraceEventsIterator();\r
ITimeEvent nextEvent = null;\r
ITimeEvent currEvent = null;\r
ITimeEvent prevEvent = null;\r
\r
- while (it.hasNext()) {\r
- nextEvent = (ITimeEvent) it.next();\r
+ while (iterator.hasNext()) {\r
+ nextEvent = (ITimeEvent) iterator.next();\r
long nextStartTime = nextEvent.getTime();\r
\r
if (nextStartTime > time) {\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ * Patrick Tasse - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.tmf.ui.views.timechart;\r
+\r
+import java.util.Iterator;\r
+import java.util.NoSuchElementException;\r
+import java.util.Vector;\r
+\r
+import org.eclipse.linuxtools.tmf.trace.ITmfTrace;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+\r
+public class TimeChartAnalysisEntry implements ITmfTimeAnalysisEntry {\r
+\r
+ private ITmfTrace fTrace;\r
+ private String fGroup;\r
+ private Vector<TimeChartEvent> fTraceEvents;\r
+ private int fPower = 0; // 2^fPower nanoseconds per vector position\r
+ private long fReferenceTime = -1; // time corresponding to beginning of index 0\r
+ private long fStartTime = -1; // time of first event\r
+ private long fStopTime = -1; // time of last event\r
+ private long fLastRank = -1; // rank of last processed trace event\r
+\r
+ TimeChartAnalysisEntry(ITmfTrace trace, int modelSize) {\r
+ fTrace = trace;\r
+ fTraceEvents = new Vector<TimeChartEvent>(modelSize);\r
+ }\r
+ \r
+ TimeChartAnalysisEntry(ITmfTrace trace, String group, int modelSize) {\r
+ fTrace = trace;\r
+ fTraceEvents = new Vector<TimeChartEvent>(modelSize);\r
+ fGroup = group;\r
+ }\r
+ \r
+ @Override\r
+ public String getGroupName() {\r
+ return fGroup;\r
+ }\r
+\r
+ @Override\r
+ public int getId() {\r
+ // TODO Auto-generated method stub\r
+ return 0;\r
+ }\r
+\r
+ @Override\r
+ public String getName() {\r
+ return fTrace.getName();\r
+ }\r
+\r
+ @Override\r
+ public long getStartTime() {\r
+ return fStartTime;\r
+ }\r
+\r
+ @Override\r
+ public long getStopTime() {\r
+ return fStopTime;\r
+ }\r
+\r
+ @Override\r
+ @Deprecated public <T extends ITimeEvent> Vector<T> getTraceEvents() {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public Iterator<ITimeEvent> getTraceEventsIterator() {\r
+ return new EntryIterator(0, Long.MAX_VALUE, 0);\r
+ }\r
+ \r
+ @Override\r
+ public Iterator<ITimeEvent> getTraceEventsIterator(long startTime, long stopTime, long maxDuration) {\r
+ return new EntryIterator(startTime, stopTime, maxDuration);\r
+ }\r
+ \r
+ private class EntryIterator implements Iterator<ITimeEvent> {\r
+ private final long fIteratorStartTime;\r
+ private final long fIteratorStopTime;\r
+ private final long fIteratorMaxDuration;\r
+ private long lastTime = -1;\r
+ private TimeChartEvent next = null;\r
+ private Iterator<ITimeEvent> nestedIterator = null;\r
+ \r
+ public EntryIterator(long startTime, long stopTime, long maxDuration) {\r
+ fIteratorStartTime = startTime;\r
+ fIteratorStopTime = stopTime;\r
+ fIteratorMaxDuration = maxDuration;\r
+ }\r
+ \r
+ @Override\r
+ public boolean hasNext() {\r
+ synchronized (fTraceEvents) {\r
+ if (next != null) return true;\r
+ if (nestedIterator != null) {\r
+ if (nestedIterator.hasNext()) {\r
+ return true;\r
+ } else {\r
+ nestedIterator = null;\r
+ }\r
+ }\r
+ long time = (lastTime == -1) ? fStartTime : lastTime;\r
+ int index = (fReferenceTime == -1) ? 0 : (int) ((time - fReferenceTime) >> fPower);\r
+ while (index < fTraceEvents.size()) {\r
+ TimeChartEvent event = fTraceEvents.get(index++);\r
+ if (event != null && (lastTime == -1 || event.getTime() > time)) {\r
+ if (event.getTime() + event.getDuration() >= fIteratorStartTime && event.getTime() <= fIteratorStopTime) {\r
+ if (event.getItemizedEntry() == null || event.getDuration() <= fIteratorMaxDuration) {\r
+ lastTime = event.getTime() + event.getDuration();\r
+ next = event;\r
+ return true;\r
+ } else {\r
+ nestedIterator = event.getItemizedEntry().getTraceEventsIterator(fIteratorStartTime, fIteratorStopTime, fIteratorMaxDuration);\r
+ return nestedIterator.hasNext();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public TimeChartEvent next() {\r
+ synchronized (fTraceEvents) {\r
+ if (nestedIterator != null) {\r
+ TimeChartEvent event = (TimeChartEvent) nestedIterator.next();\r
+ lastTime = event.getTime() + event.getDuration();\r
+ return event; \r
+ }\r
+ if (hasNext()) {\r
+ TimeChartEvent event = next;\r
+ next = null;\r
+ return event;\r
+ }\r
+ throw new NoSuchElementException();\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void remove() {\r
+ throw new UnsupportedOperationException();\r
+ }\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addTraceEvent(ITimeEvent timeEvent) {\r
+ long time = timeEvent.getTime();\r
+ synchronized (fTraceEvents) {\r
+ long index = (fReferenceTime == -1) ? 0 : (time - fReferenceTime) >> fPower;\r
+ if (index < 0) {\r
+ if (fTraceEvents.capacity() - fTraceEvents.size() < -index) {\r
+ int powershift = (-index + fTraceEvents.size() <= 2 * fTraceEvents.capacity()) ? 1 :\r
+ (int) Math.ceil(Math.log((double) (-index + fTraceEvents.size()) / fTraceEvents.capacity()) / Math.log(2));\r
+ merge(powershift);\r
+ index = (int) ((time - fReferenceTime) >> fPower);\r
+ }\r
+ shift((int) -index);\r
+ index = 0;\r
+ fTraceEvents.set(0, (TimeChartEvent) timeEvent);\r
+ } else if (index < fTraceEvents.capacity()) {\r
+ if (index >= fTraceEvents.size()) {\r
+ fTraceEvents.setSize((int) index + 1);\r
+ }\r
+ } else {\r
+ int powershift = (index < 2 * fTraceEvents.capacity()) ? 1 :\r
+ (int) Math.ceil(Math.log((double) (index + 1) / fTraceEvents.capacity()) / Math.log(2));\r
+ merge(powershift);\r
+ index = (int) ((time - fReferenceTime) >> fPower);\r
+ fTraceEvents.setSize((int) index + 1);\r
+ }\r
+ TimeChartEvent event = (TimeChartEvent) fTraceEvents.get((int) index);\r
+ if (event == null) {\r
+ fTraceEvents.set((int) index, (TimeChartEvent) timeEvent);\r
+ } else {\r
+ if (event.getItemizedEntry() == null) {\r
+ event.merge((TimeChartEvent) timeEvent);\r
+ } else {\r
+ event.mergeDecorations((TimeChartEvent) timeEvent);\r
+ event.getItemizedEntry().addTraceEvent(timeEvent);\r
+ }\r
+ }\r
+ if (fReferenceTime == -1 || time < fReferenceTime) {\r
+ fReferenceTime = (time >> fPower) << fPower;\r
+ }\r
+ if (fStartTime == -1 || time < fStartTime) {\r
+ fStartTime = time;\r
+ }\r
+ if (fStopTime == -1 || time > fStopTime) {\r
+ fStopTime = time;\r
+ }\r
+ }\r
+ }\r
+\r
+ private void merge(int powershift) {\r
+ fPower += powershift;\r
+ fReferenceTime = (fReferenceTime >> fPower) << fPower;\r
+ int index = 0;\r
+ for (int i = 0; i < fTraceEvents.size(); i++) {\r
+ TimeChartEvent event = fTraceEvents.get(i);\r
+ if (event != null) {\r
+ index = (int) ((event.getTime() - fReferenceTime) >> fPower);\r
+ TimeChartEvent mergedEvent = (TimeChartEvent) fTraceEvents.get(index);\r
+ if (mergedEvent == null) {\r
+ fTraceEvents.set(index, event);\r
+ } else {\r
+ mergedEvent.merge(event);\r
+ }\r
+ if (i != index) {\r
+ fTraceEvents.set(i, null);\r
+ }\r
+ }\r
+ }\r
+ fTraceEvents.setSize(index + 1);\r
+ }\r
+\r
+ private void shift(int indexshift) {\r
+ int oldSize = fTraceEvents.size();\r
+ fTraceEvents.setSize(oldSize + indexshift);\r
+ for (int i = oldSize - 1; i >= 0; i--) {\r
+ fTraceEvents.set(i + indexshift, fTraceEvents.get(i));\r
+ }\r
+ for (int i = 0; i < indexshift; i++) {\r
+ fTraceEvents.set(i, null);\r
+ }\r
+ }\r
+ \r
+ public ITmfTrace getTrace() {\r
+ return fTrace;\r
+ }\r
+ \r
+ public void setLastRank(long rank) {\r
+ fLastRank = rank;\r
+ }\r
+ \r
+ public long getLastRank() {\r
+ return fLastRank;\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ * Patrick Tasse - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.tmf.ui.views.timechart;\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeAnalysisProvider;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.widgets.TraceColorScheme;\r
+import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.graphics.Color;\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Rectangle;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+public class TimeChartAnalysisProvider extends TmfTimeAnalysisProvider {\r
+\r
+ private static final Color BOOKMARK_INNER_COLOR = new Color(Display.getDefault(), 115, 165, 224);\r
+ private static final Color BOOKMARK_OUTER_COLOR = new Color(Display.getDefault(), 2, 70, 140);\r
+ private static final Color SEARCH_MATCH_COLOR = new Color(Display.getDefault(), 177, 118, 14);\r
+ \r
+ private int lastX = Integer.MIN_VALUE;\r
+ private int currX = Integer.MIN_VALUE;\r
+ private int lastPriority;\r
+ private int lastBookmarkX = Integer.MIN_VALUE;\r
+ \r
+ @Override\r
+ public StateColor getEventColor(ITimeEvent event) {\r
+ return StateColor.BLACK;\r
+ }\r
+\r
+ @Override\r
+ public int getEventColorVal(ITimeEvent event) {\r
+ int priority = ((TimeChartEvent) event).getColorSettingPriority();\r
+ if (currX == lastX) {\r
+ priority = Math.min(priority, lastPriority);\r
+ }\r
+ lastPriority = priority;\r
+ return ColorSettingsManager.getColorSetting(priority).getTickColorIndex();\r
+ }\r
+\r
+ @Override\r
+ public String getTraceClassName(ITmfTimeAnalysisEntry entry) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public String getEventName(ITimeEvent event, boolean upper, boolean extInfo) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public Map<String, String> getEventHoverToolTipInfo(ITimeEvent event) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public String getStateName(StateColor color) {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public void drawState(TraceColorScheme colors, ITimeEvent event, Rectangle rect, GC gc, boolean selected, boolean rectBound, boolean timeSelected) {\r
+ if (! ((TimeChartEvent) event).isVisible()) {\r
+ return;\r
+ }\r
+ lastX = currX;\r
+ currX = rect.x;\r
+ super.drawState(colors, event, rect, gc, selected, rectBound, timeSelected);\r
+ if (lastBookmarkX == rect.x || ((TimeChartEvent) event).isBookmarked()) {\r
+ drawBookmark(rect, gc);\r
+ lastBookmarkX = rect.x;\r
+ } else if (lastBookmarkX == rect.x - 1) {\r
+ Rectangle r = new Rectangle(lastBookmarkX, rect.y, rect.width, rect.height);\r
+ drawBookmark(r, gc);\r
+ } else {\r
+ lastBookmarkX = Integer.MIN_VALUE;\r
+ }\r
+ if (((TimeChartEvent) event).isSearchMatch()) {\r
+ drawSearchMatch(rect, gc);\r
+ }\r
+ }\r
+\r
+ private void drawBookmark(Rectangle r, GC gc) {\r
+ gc.setForeground(BOOKMARK_OUTER_COLOR);\r
+ gc.drawLine(r.x - 1, r.y - 2, r.x - 1, r.y + 2);\r
+ gc.drawLine(r.x + 1, r.y - 2, r.x + 1, r.y + 2);\r
+ gc.drawPoint(r.x, r.y - 2);\r
+ gc.setForeground(BOOKMARK_INNER_COLOR);\r
+ gc.drawLine(r.x, r.y - 1, r.x, r.y + 1);\r
+ gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));\r
+ gc.drawPoint(r.x - 1, r.y + 3);\r
+ gc.drawPoint(r.x, r.y + 2);\r
+ gc.drawPoint(r.x + 1, r.y + 3);\r
+ }\r
+ \r
+ private void drawSearchMatch(Rectangle r, GC gc) {\r
+ gc.setForeground(SEARCH_MATCH_COLOR);\r
+ gc.drawPoint(r.x, r.y + r.height);\r
+ gc.drawLine(r.x - 1, r.y + r.height + 1, r.x + 1, r.y + r.height + 1);\r
+ gc.drawLine(r.x - 2, r.y + r.height + 2, r.x + 2, r.y + r.height + 2);\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ * Patrick Tasse - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.tmf.ui.views.timechart;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.eclipse.core.resources.IMarker;\r
+import org.eclipse.core.resources.IResource;\r
+import org.eclipse.core.runtime.CoreException;\r
+import org.eclipse.linuxtools.tmf.event.TmfEvent;\r
+import org.eclipse.linuxtools.tmf.filter.ITmfFilter;\r
+\r
+public class TimeChartDecorationProvider {\r
+\r
+ private IResource fResource;\r
+ private Set<Long> fBookmarksSet = new HashSet<Long>();\r
+ private ITmfFilter fFilterFilter;\r
+ private ITmfFilter fSearchFilter;\r
+\r
+ public TimeChartDecorationProvider(IResource resource) {\r
+ fResource = resource;\r
+ refreshBookmarks();\r
+ }\r
+\r
+ public IResource getResource() {\r
+ return fResource;\r
+ }\r
+ \r
+ public boolean isBookmark(long rank) {\r
+ return fBookmarksSet.contains(rank);\r
+ }\r
+ \r
+ public void refreshBookmarks() {\r
+ try {\r
+ fBookmarksSet.clear();\r
+ for (IMarker bookmark : fResource.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO)) {\r
+ int location = bookmark.getAttribute(IMarker.LOCATION, -1);\r
+ if (location != -1) {\r
+ Long rank = (long) location;\r
+ fBookmarksSet.add(rank);\r
+ }\r
+ }\r
+ } catch (CoreException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+\r
+ public void filterApplied(ITmfFilter filter) {\r
+ fFilterFilter = filter;\r
+ }\r
+\r
+ public boolean isVisible(TmfEvent event) {\r
+ if (fFilterFilter != null) {\r
+ return fFilterFilter.matches(event);\r
+ }\r
+ return true;\r
+ }\r
+ \r
+ public void searchApplied(ITmfFilter filter) {\r
+ fSearchFilter = filter;\r
+ }\r
+ \r
+ public boolean isSearchMatch(TmfEvent event) {\r
+ if (fSearchFilter != null) {\r
+ return fSearchFilter.matches(event);\r
+ }\r
+ return false;\r
+ }\r
+ \r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ * Patrick Tasse - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.tmf.ui.views.timechart;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+\r
+import org.eclipse.linuxtools.tmf.event.TmfEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager;\r
+\r
+public class TimeChartEvent implements ITimeEvent {\r
+\r
+ private static final byte TIMESTAMP_SCALE = -9;\r
+ \r
+ private TimeChartAnalysisEntry fParentEntry;\r
+ private long fTime;\r
+ private long fDuration;\r
+ private long fFirstRank;\r
+ private long fLastRank;\r
+ private RankRangeList fRankRangeList;\r
+ private long fNbEvents;\r
+ private int fColorSettingPriority;\r
+ private boolean fIsBookmark;\r
+ private boolean fIsVisible;\r
+ private boolean fIsSearchMatch;\r
+ private TimeChartAnalysisEntry fItemizedEntry;\r
+ private boolean fItemizing;\r
+\r
+ public TimeChartEvent(TimeChartAnalysisEntry parentEntry, TmfEvent event, long rank, TimeChartDecorationProvider decorationProvider) {\r
+ fParentEntry = parentEntry;\r
+ fTime = event.getTimestamp().synchronize((long) 0, TIMESTAMP_SCALE).getValue();\r
+ fDuration = 0;\r
+ fFirstRank = fLastRank = rank;\r
+ fRankRangeList = new RankRangeList(rank);\r
+ fNbEvents = 1;\r
+ fColorSettingPriority = ColorSettingsManager.getColorSettingPriority(event);\r
+ fIsBookmark = decorationProvider.isBookmark(rank);\r
+ fIsVisible = decorationProvider.isVisible(event);\r
+ fIsSearchMatch = decorationProvider.isSearchMatch(event);\r
+ }\r
+\r
+ @Override\r
+ public ITmfTimeAnalysisEntry getEntry() {\r
+ return fParentEntry;\r
+ }\r
+\r
+ @Override\r
+ public long getTime() {\r
+ return fTime;\r
+ }\r
+\r
+ @Override\r
+ public long getDuration() {\r
+ return fDuration;\r
+ }\r
+\r
+ public long getFirstRank() {\r
+ return fFirstRank;\r
+ }\r
+ \r
+ public long getLastRank() {\r
+ return fLastRank;\r
+ }\r
+ \r
+ public RankRangeList getRankRangeList() {\r
+ return fRankRangeList;\r
+ }\r
+ \r
+ public void merge(TimeChartEvent event) {\r
+ mergeDecorations(event);\r
+ if (fTime == event.getTime() && fDuration == event.getDuration()) return;\r
+ long endTime = Math.max(fTime + fDuration, event.getTime() + event.getDuration());\r
+ fTime = Math.min(fTime, event.getTime());\r
+ fDuration = endTime - fTime;\r
+ fFirstRank = Math.min(fFirstRank, event.fFirstRank);\r
+ fLastRank = Math.max(fLastRank, event.fLastRank);\r
+ fNbEvents += event.fNbEvents;\r
+ fItemizedEntry = null;\r
+ synchronized (fRankRangeList) {\r
+ fRankRangeList.merge(event.getRankRangeList());\r
+ }\r
+ }\r
+\r
+ public void mergeDecorations(TimeChartEvent event) {\r
+ fColorSettingPriority = Math.min(fColorSettingPriority, event.getColorSettingPriority());\r
+ fIsBookmark |= event.fIsBookmark;\r
+ fIsVisible |= event.fIsVisible;\r
+ fIsSearchMatch |= event.fIsSearchMatch;\r
+ }\r
+ \r
+ public long getNbEvents() {\r
+ return fNbEvents;\r
+ }\r
+\r
+ public int getColorSettingPriority() {\r
+ return fColorSettingPriority;\r
+ }\r
+ \r
+ public void setColorSettingPriority(int priority) {\r
+ fColorSettingPriority = priority;\r
+ }\r
+ \r
+ public boolean isBookmarked() {\r
+ return fIsBookmark;\r
+ }\r
+\r
+ public void setIsBookmarked(boolean isBookmarked) {\r
+ fIsBookmark = isBookmarked;\r
+ }\r
+ \r
+ public boolean isVisible() {\r
+ return fIsVisible;\r
+ }\r
+\r
+ public void setIsVisible(boolean isVisible) {\r
+ fIsVisible = isVisible;\r
+ }\r
+ \r
+ public boolean isSearchMatch() {\r
+ return fIsSearchMatch;\r
+ }\r
+\r
+ public void setIsSearchMatch(boolean isSearchMatch) {\r
+ fIsSearchMatch = isSearchMatch;\r
+ }\r
+ \r
+ public void setItemizedEntry(TimeChartAnalysisEntry timeAnalysisEntry) {\r
+ fItemizedEntry = timeAnalysisEntry;\r
+ }\r
+\r
+ public TimeChartAnalysisEntry getItemizedEntry() {\r
+ return fItemizedEntry;\r
+ }\r
+\r
+ public boolean isItemizing() {\r
+ return fItemizing;\r
+ }\r
+\r
+ public void setItemizing(boolean itemizing) {\r
+ fItemizing = itemizing;\r
+ }\r
+\r
+ public class RankRange {\r
+ private long firstRank;\r
+ private long lastRank;\r
+ \r
+ public RankRange(long firstRank, long lastRank) {\r
+ this.firstRank = firstRank;\r
+ this.lastRank = lastRank;\r
+ }\r
+\r
+ public long getFirstRank() {\r
+ return firstRank;\r
+ }\r
+\r
+ public long getLastRank() {\r
+ return lastRank;\r
+ }\r
+\r
+ public long distanceFrom(RankRange range) {\r
+ if (range.lastRank < fFirstRank) {\r
+ return fFirstRank - range.lastRank;\r
+ } else if (range.firstRank > fLastRank) {\r
+ return range.firstRank - fLastRank;\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return "["+firstRank+","+lastRank+"]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$\r
+ }\r
+ }\r
+ \r
+ private class RankRangeList extends ArrayList<RankRange> {\r
+ \r
+ private static final long serialVersionUID = 6060485531208535986L;\r
+\r
+ public RankRangeList(long rank) {\r
+ super(1);\r
+ add(new RankRange(rank, rank));\r
+ }\r
+ \r
+ public void merge(RankRangeList rankRangeList) {\r
+ long threshold = fParentEntry.getTrace().getCacheSize();\r
+ for (RankRange newRange : rankRangeList) {\r
+ boolean merged = false;\r
+ for (RankRange oldRange : fRankRangeList) {\r
+ if (newRange.distanceFrom(oldRange) <= threshold) {\r
+ oldRange.firstRank = Math.min(oldRange.firstRank, newRange.firstRank);\r
+ oldRange.lastRank = Math.max(oldRange.lastRank, newRange.lastRank);\r
+ merged = true;\r
+ break;\r
+ }\r
+ }\r
+ if (!merged) {\r
+ add(newRange);\r
+ }\r
+ }\r
+ Iterator<RankRange> iterator = fRankRangeList.iterator();\r
+ RankRange previous = null;\r
+ while (iterator.hasNext()) {\r
+ RankRange range = iterator.next();\r
+ if (previous != null && range.distanceFrom(previous) <= threshold) {\r
+ previous.firstRank = Math.min(previous.firstRank, range.firstRank);\r
+ previous.lastRank = Math.max(previous.lastRank, range.lastRank);\r
+ iterator.remove();\r
+ }\r
+ previous = range;\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2010 Ericsson\r
+ * \r
+ * All rights reserved. This program and the accompanying materials are\r
+ * made available under the terms of the Eclipse Public License v1.0 which\r
+ * accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ * \r
+ * Contributors:\r
+ * Patrick Tasse - Initial API and implementation\r
+ *******************************************************************************/\r
+\r
+package org.eclipse.linuxtools.tmf.ui.views.timechart;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.resources.IMarker;\r
+import org.eclipse.core.resources.IMarkerDelta;\r
+import org.eclipse.core.resources.IResource;\r
+import org.eclipse.core.resources.IResourceChangeEvent;\r
+import org.eclipse.core.resources.IResourceChangeListener;\r
+import org.eclipse.core.resources.IResourceDelta;\r
+import org.eclipse.core.resources.ResourcesPlugin;\r
+import org.eclipse.linuxtools.tmf.event.TmfEvent;\r
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;\r
+import org.eclipse.linuxtools.tmf.filter.ITmfFilter;\r
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;\r
+import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;\r
+import org.eclipse.linuxtools.tmf.signal.TmfTraceSelectedSignal;\r
+import org.eclipse.linuxtools.tmf.signal.TmfTraceUpdatedSignal;\r
+import org.eclipse.linuxtools.tmf.trace.ITmfTrace;\r
+import org.eclipse.linuxtools.tmf.trace.TmfContext;\r
+import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;\r
+import org.eclipse.linuxtools.tmf.ui.signal.TmfTraceClosedSignal;\r
+import org.eclipse.linuxtools.tmf.ui.signal.TmfTraceOpenedSignal;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewerFactory;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.events.ITmfEventsFilterListener;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.events.ITmfEventsFilterProvider;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeSelectionListener;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITimeEvent;\r
+import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;\r
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;\r
+import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting;\r
+import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager;\r
+import org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener;\r
+import org.eclipse.linuxtools.tmf.ui.views.timechart.TimeChartEvent.RankRange;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.layout.GridLayout;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Display;\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IEditorReference;\r
+\r
+\r
+public class TimeChartView extends TmfView implements ITmfTimeScaleSelectionListener, ITmfTimeSelectionListener, IColorSettingsListener, IResourceChangeListener, ITmfEventsFilterListener {\r
+\r
+ public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.timechart"; //$NON-NLS-1$\r
+\r
+ private static final byte TIMESTAMP_SCALE = -9;\r
+ \r
+ private int fDisplayWidth;\r
+ private Composite fComposite;\r
+ private ITimeAnalysisViewer fViewer;\r
+ private ArrayList<TimeChartAnalysisEntry> fTimeAnalysisEntries = new ArrayList<TimeChartAnalysisEntry>();\r
+ private Map<ITmfTrace, TimeChartDecorationProvider> fDecorationProviders = new HashMap<ITmfTrace, TimeChartDecorationProvider>();\r
+ private ArrayList<DecorateThread> fDecorateThreads;\r
+ private long fStartTime = 0;\r
+ private long fStopTime = Long.MAX_VALUE;\r
+\r
+ public TimeChartView() {\r
+ super("Time Chart"); //$NON-NLS-1$\r
+ fDisplayWidth = Display.getDefault().getBounds().width;\r
+ }\r
+\r
+ @Override\r
+ public void createPartControl(Composite parent) {\r
+ fComposite = new Composite(parent, SWT.NONE);\r
+ GridLayout gl = new GridLayout();\r
+ gl.marginWidth = 0;\r
+ gl.marginHeight = 0;\r
+ fComposite.setLayout(gl);\r
+ \r
+ fViewer = TmfViewerFactory.createViewer(fComposite, new TimeChartAnalysisProvider());\r
+ fViewer.groupTraces(false);\r
+ fViewer.setTimeCalendarFormat(true);\r
+ fViewer.setAcceptSelectionAPIcalls(true);\r
+ fViewer.addWidgetTimeScaleSelectionListner(this);\r
+ fViewer.addWidgetSelectionListner(this);\r
+ fViewer.setMinimumItemWidth(1);\r
+ \r
+ IEditorReference[] editorReferences = getSite().getPage().getEditorReferences();\r
+ for (IEditorReference editorReference : editorReferences) {\r
+ IEditorPart editor = editorReference.getEditor(false);\r
+ if (editor instanceof ITmfTraceEditor) {\r
+ ITmfTrace trace = ((ITmfTraceEditor) editor).getTrace();\r
+ if (trace != null) {\r
+ IResource resource = ((ITmfTraceEditor) editor).getResource();\r
+ TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2);\r
+ fTimeAnalysisEntries.add(timeAnalysisEntry);\r
+ fDecorationProviders.put(trace, new TimeChartDecorationProvider(resource));\r
+ Thread thread = new ProcessTraceThread(timeAnalysisEntry);\r
+ thread.start();\r
+ }\r
+ }\r
+ }\r
+ fViewer.display(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));\r
+ \r
+ fDecorateThreads = new ArrayList<DecorateThread>();\r
+ ColorSettingsManager.addColorSettingsListener(this);\r
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);\r
+ for (DecorateThread thread : fDecorateThreads) {\r
+ thread.cancel();\r
+ }\r
+ ColorSettingsManager.removeColorSettingsListener(this);\r
+ super.dispose();\r
+ }\r
+\r
+ @Override\r
+ public void setFocus() {\r
+ super.setFocus();\r
+ fViewer.setFocus();\r
+ }\r
+ \r
+ private class ProcessTraceThread extends Thread {\r
+\r
+ private TimeChartAnalysisEntry fTimeAnalysisEntry;\r
+\r
+ public ProcessTraceThread(TimeChartAnalysisEntry timeAnalysisEntry) {\r
+ super("ProcessTraceJob:"+timeAnalysisEntry.getName()); //$NON-NLS-1$\r
+ fTimeAnalysisEntry = timeAnalysisEntry;\r
+ }\r
+\r
+ @Override\r
+ public void run() {\r
+ updateTraceEntry(fTimeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE);\r
+ }\r
+ }\r
+ \r
+ private void updateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, long stopRank, long startTime, long stopTime) {\r
+ ITmfTrace trace = timeAnalysisEntry.getTrace();\r
+ TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace);\r
+ if (decorationProvider == null) {\r
+ return; // the trace has been closed\r
+ }\r
+ TmfContext context = null;\r
+ //TmfTimestamp lastTimestamp = null;\r
+ boolean done = false;\r
+ while (!done) {\r
+ synchronized (timeAnalysisEntry) {\r
+ if (timeAnalysisEntry.getLastRank() >= trace.getNbEvents()) {\r
+ done = true;\r
+ break;\r
+ }\r
+ if (context == null || context.getRank() != timeAnalysisEntry.getLastRank()) {\r
+ if (timeAnalysisEntry.getLastRank() != -1) {\r
+ context = trace.seekEvent(timeAnalysisEntry.getLastRank());\r
+ } else {\r
+ //context = trace.seekLocation(null);\r
+ context = trace.seekEvent(0);\r
+ }\r
+ }\r
+ while (true) {\r
+ long rank = context.getRank();\r
+ TmfEvent event = trace.getNextEvent(context);\r
+ if (event == null) {\r
+ done = true;\r
+ break;\r
+ }\r
+ //if (!event.getTimestamp().equals(lastTimestamp)) {\r
+ TimeChartEvent timeEvent = new TimeChartEvent(timeAnalysisEntry, event, rank, decorationProvider);\r
+ if (timeEvent.getTime() >= startTime && timeEvent.getTime() <= stopTime) {\r
+ timeAnalysisEntry.addTraceEvent(timeEvent);\r
+ }\r
+ //lastTimestamp = event.getTimestamp();\r
+ //} *** commented out so that color setting priority gets set even if the event has same time\r
+ if (context.getRank() == trace.getNbEvents() || context.getRank() == stopRank) {\r
+ done = true;\r
+ break;\r
+ }\r
+ if (context.getRank() % trace.getCacheSize() == 1) {\r
+ // break for UI refresh\r
+ break;\r
+ }\r
+ }\r
+ //timeAnalysisEntry.setLastRank(Math.min(trace.getNbEvents(), stopRank));\r
+ timeAnalysisEntry.setLastRank(context.getRank());\r
+ }\r
+ refreshViewer(false);\r
+ }\r
+ }\r
+\r
+ private void refreshViewer(boolean resetTimeIntervals) {\r
+ if (fComposite == null) {\r
+ return;\r
+ }\r
+ final boolean reset = resetTimeIntervals;\r
+ // Perform the refresh on the UI thread\r
+ Display.getDefault().asyncExec(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ if (!fComposite.isDisposed()) {\r
+ fViewer.display(fTimeAnalysisEntries.toArray(new TimeChartAnalysisEntry[0]));\r
+ if (reset) {\r
+ fViewer.resetStartFinishTime();\r
+ }\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ private void itemize(long startTime, long stopTime) {\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ Thread thread = new ItemizeThread(fTimeAnalysisEntries.get(i), startTime, stopTime);\r
+ thread.start();\r
+ }\r
+ }\r
+ \r
+ private class ItemizeThread extends Thread {\r
+\r
+ private TimeChartAnalysisEntry fTimeAnalysisEntry;\r
+ private long fStartTime;\r
+ private long fStopTime;\r
+ private long fMaxDuration;\r
+ \r
+ private ItemizeThread(TimeChartAnalysisEntry timeAnalysisEntry, long startTime, long stopTime) {\r
+ super("Itemize Thread:"+timeAnalysisEntry.getName()); //$NON-NLS-1$\r
+ fTimeAnalysisEntry = timeAnalysisEntry;\r
+ fStartTime = startTime;\r
+ fStopTime = stopTime;\r
+ fMaxDuration = 3 * (fStopTime - fStartTime) / fDisplayWidth;\r
+ }\r
+ \r
+ @Override\r
+ public void run() {\r
+ itemizeTraceEntry(fTimeAnalysisEntry);\r
+ }\r
+\r
+ public void itemizeTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) {\r
+ Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTraceEventsIterator();\r
+ TimeChartEvent event = null;\r
+ boolean hasNext = true;\r
+ while (hasNext) {\r
+ synchronized (timeAnalysisEntry) {\r
+ while (hasNext = iterator.hasNext()) {\r
+ event = (TimeChartEvent) iterator.next();\r
+ if (event.getTime() + event.getDuration() > fStartTime &&\r
+ event.getTime() < fStopTime &&\r
+ event.getDuration() > fMaxDuration &&\r
+ event.getNbEvents() > 1) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (hasNext) {\r
+ if (event.getItemizedEntry() == null) {\r
+ itemizeEvent(event);\r
+ } else {\r
+ itemizeTraceEntry(event.getItemizedEntry());\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ public void itemizeEvent(TimeChartEvent event) {\r
+ synchronized (event) {\r
+ if (event.isItemizing()) {\r
+ return;\r
+ }\r
+ event.setItemizing(true);\r
+ }\r
+ TimeChartAnalysisEntry timeAnalysisEntry = new TimeChartAnalysisEntry(fTimeAnalysisEntry.getTrace(),\r
+ (int) Math.min(event.getNbEvents() + 1, fDisplayWidth * 2));\r
+ synchronized (event.getRankRangeList()) {\r
+ for (RankRange range : event.getRankRangeList()) {\r
+ timeAnalysisEntry.setLastRank(range.getFirstRank());\r
+ updateTraceEntry(timeAnalysisEntry, range.getLastRank() + 1, event.getTime(), event.getTime() + event.getDuration());\r
+ }\r
+ }\r
+ event.setItemizedEntry(timeAnalysisEntry);\r
+ refreshViewer(false);\r
+ itemizeTraceEntry(timeAnalysisEntry);\r
+ synchronized (event) {\r
+ event.setItemizing(false);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void redecorate() {\r
+ synchronized (fDecorateThreads) {\r
+ for (DecorateThread thread : fDecorateThreads) {\r
+ thread.cancel();\r
+ }\r
+ fDecorateThreads.clear();\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ DecorateThread thread = new DecorateThread(fTimeAnalysisEntries.get(i));\r
+ thread.start();\r
+ fDecorateThreads.add(thread);\r
+ }\r
+ }\r
+ }\r
+ \r
+ private class DecorateThread extends Thread {\r
+ private volatile boolean interrupted = false;\r
+ private TimeChartAnalysisEntry fTimeAnalysisEntry;\r
+ private TimeChartDecorationProvider fDecorationProvider;\r
+ private TmfContext fContext;\r
+ private int fCount = 0;\r
+ \r
+ private DecorateThread(TimeChartAnalysisEntry timeAnalysisEntry) {\r
+ super("Decorate Thread:"+timeAnalysisEntry.getName()); //$NON-NLS-1$\r
+ fTimeAnalysisEntry = timeAnalysisEntry;\r
+ fDecorationProvider = fDecorationProviders.get(timeAnalysisEntry.getTrace());\r
+ }\r
+ \r
+ @Override\r
+ public void run() {\r
+ resetTraceEntry(fTimeAnalysisEntry);\r
+ refreshViewer(false);\r
+ decorateTraceEntry(fTimeAnalysisEntry, null);\r
+ refreshViewer(false);\r
+ synchronized (fDecorateThreads) {\r
+ fDecorateThreads.remove(this);\r
+ }\r
+ }\r
+\r
+ public void resetTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry) {\r
+ Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTraceEventsIterator();\r
+ TimeChartEvent event = null;\r
+ boolean hasNext = true;\r
+ while (!interrupted && hasNext) {\r
+ synchronized (timeAnalysisEntry) {\r
+ while (hasNext = iterator.hasNext()) {\r
+ event = (TimeChartEvent) iterator.next();\r
+ break;\r
+ }\r
+ }\r
+ if (hasNext) {\r
+ // TODO possible concurrency problem here with ItemizeJob\r
+ event.setColorSettingPriority(ColorSettingsManager.PRIORITY_NONE);\r
+ if (event.getItemizedEntry() != null) {\r
+ resetTraceEntry(event.getItemizedEntry());\r
+ }\r
+ }\r
+ }\r
+ }\r
+ \r
+ public void decorateTraceEntry(TimeChartAnalysisEntry timeAnalysisEntry, TimeChartEvent parentEvent) {\r
+ // Set max duration high to ensure iterator does not consider itemized events\r
+ Iterator<ITimeEvent> iterator = timeAnalysisEntry.getTraceEventsIterator(0, Long.MAX_VALUE, Long.MAX_VALUE);\r
+ TimeChartEvent event = null;\r
+ int entryPriority = ColorSettingsManager.PRIORITY_NONE;\r
+ boolean entryIsBookmarked = false;\r
+ boolean entryIsVisible = false;\r
+ boolean entryIsSearchMatch = false;\r
+ boolean hasNext = true;\r
+ while (!interrupted && hasNext) {\r
+ synchronized (timeAnalysisEntry) {\r
+ while (hasNext = iterator.hasNext()) {\r
+ event = (TimeChartEvent) iterator.next();\r
+ break;\r
+ }\r
+ }\r
+ if (hasNext) {\r
+ // TODO possible concurrency problem here with ItemizeJob\r
+ if (event.getItemizedEntry() == null) {\r
+ decorateEvent(event);\r
+ } else {\r
+ decorateTraceEntry(event.getItemizedEntry(), event);\r
+ }\r
+ entryPriority = Math.min(entryPriority, event.getColorSettingPriority());\r
+ entryIsBookmarked |= event.isBookmarked();\r
+ entryIsVisible |= event.isVisible();\r
+ entryIsSearchMatch |= event.isSearchMatch();\r
+ if (++fCount % timeAnalysisEntry.getTrace().getCacheSize() == 0) {\r
+ refreshViewer(false);\r
+ }\r
+ }\r
+ }\r
+ if (parentEvent != null) {\r
+ parentEvent.setColorSettingPriority(entryPriority);\r
+ parentEvent.setIsBookmarked(entryIsBookmarked);\r
+ parentEvent.setIsVisible(entryIsVisible);\r
+ parentEvent.setIsSearchMatch(entryIsSearchMatch);\r
+ }\r
+ }\r
+\r
+ public void decorateEvent(TimeChartEvent timeChartEvent) {\r
+ // TODO possible concurrency problem here with ItemizeJob\r
+ TimeChartAnalysisEntry timeAnalysisEntry = (TimeChartAnalysisEntry) timeChartEvent.getEntry();\r
+ ITmfTrace trace = timeAnalysisEntry.getTrace();\r
+ int priority = ColorSettingsManager.PRIORITY_NONE;\r
+ boolean isBookmarked = false;\r
+ boolean isVisible = false;\r
+ boolean isSearchMatch = false;\r
+ synchronized (timeChartEvent.getRankRangeList()) {\r
+ for (RankRange range : timeChartEvent.getRankRangeList()) {\r
+ if (interrupted) return;\r
+ if (fContext == null || fContext.getRank() != range.getFirstRank()) {\r
+ fContext = trace.seekEvent(range.getFirstRank());\r
+ fContext.setRank(range.getFirstRank());\r
+ }\r
+ while (true) {\r
+ if (interrupted) return;\r
+ long rank = fContext.getRank();\r
+ TmfEvent event = trace.getNextEvent(fContext);\r
+ if (event == null) {\r
+ break;\r
+ }\r
+ long eventTime = event.getTimestamp().synchronize(0, (byte) -9).getValue();\r
+ if (eventTime >= timeChartEvent.getTime() && eventTime <= timeChartEvent.getTime() + timeChartEvent.getDuration()) {\r
+ priority = Math.min(priority, ColorSettingsManager.getColorSettingPriority(event));\r
+ }\r
+ isBookmarked |= fDecorationProvider.isBookmark(rank); \r
+ isVisible |= fDecorationProvider.isVisible(event); \r
+ isSearchMatch |= fDecorationProvider.isSearchMatch(event); \r
+ if (fContext.getRank() > range.getLastRank()) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ timeChartEvent.setColorSettingPriority(priority);\r
+ timeChartEvent.setIsBookmarked(isBookmarked);\r
+ timeChartEvent.setIsVisible(isVisible);\r
+ timeChartEvent.setIsSearchMatch(isSearchMatch);\r
+ }\r
+ \r
+ public void cancel() {\r
+ interrupted = true;\r
+ }\r
+ }\r
+\r
+ // ------------------------------------------------------------------------\r
+ // Listeners\r
+ // ------------------------------------------------------------------------\r
+ \r
+ @Override\r
+ public void tsfTmProcessTimeScaleEvent(TmfTimeScaleSelectionEvent event) {\r
+ fStartTime = event.getTime0();\r
+ fStopTime = event.getTime1();\r
+ itemize(fStartTime, fStopTime);\r
+ }\r
+\r
+ @Override\r
+ public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {\r
+ ITmfTimeAnalysisEntry timeAnalysisEntry = null;\r
+ if (event.getSelection() instanceof TimeChartAnalysisEntry) {\r
+ timeAnalysisEntry = (TimeChartAnalysisEntry) event.getSelection();\r
+ } else if (event.getSelection() instanceof TimeChartEvent) {\r
+ timeAnalysisEntry = ((TimeChartEvent) event.getSelection()).getEntry();\r
+ }\r
+ if (timeAnalysisEntry instanceof TimeChartAnalysisEntry) {\r
+ broadcast(new TmfTraceSelectedSignal(this, ((TimeChartAnalysisEntry) timeAnalysisEntry).getTrace()));\r
+ }\r
+ broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(event.getSelectedTime(), TIMESTAMP_SCALE)));\r
+ }\r
+\r
+ @Override\r
+ public void colorSettingsChanged(ColorSetting[] colorSettings) {\r
+ redecorate();\r
+ }\r
+\r
+ @Override\r
+ public void resourceChanged(IResourceChangeEvent event) {\r
+ for (IMarkerDelta delta : event.findMarkerDeltas(IMarker.BOOKMARK, false)) {\r
+ for (TimeChartDecorationProvider provider : fDecorationProviders.values()) {\r
+ if (delta.getResource().equals(provider.getResource())) {\r
+ if (delta.getKind() == IResourceDelta.CHANGED && delta.getMarker().getAttribute(IMarker.LOCATION, -1) != -1) {\r
+ provider.refreshBookmarks();\r
+ } else if (delta.getKind() == IResourceDelta.REMOVED) {\r
+ provider.refreshBookmarks();\r
+ }\r
+ }\r
+ }\r
+ }\r
+ redecorate();\r
+ }\r
+ \r
+ @Override\r
+ public void filterApplied(ITmfFilter filter, ITmfTrace trace) {\r
+ TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace);\r
+ decorationProvider.filterApplied(filter);\r
+ redecorate();\r
+ }\r
+\r
+ @Override\r
+ public void searchApplied(ITmfFilter filter, ITmfTrace trace) {\r
+ TimeChartDecorationProvider decorationProvider = fDecorationProviders.get(trace);\r
+ decorationProvider.searchApplied(filter);\r
+ redecorate();\r
+ }\r
+\r
+ // ------------------------------------------------------------------------\r
+ // Signal handlers\r
+ // ------------------------------------------------------------------------\r
+ \r
+ @TmfSignalHandler\r
+ public void traceOpened(TmfTraceOpenedSignal signal) {\r
+ if (fTimeAnalysisEntries == null) return;\r
+ final ITmfTrace trace = signal.getTrace();\r
+ final IResource resource = signal.getResource();\r
+ final ITmfEventsFilterProvider eventsFilterProvider = signal.getEventsFilterProvider();\r
+ TimeChartAnalysisEntry timeAnalysisEntry = null;\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {\r
+ timeAnalysisEntry = fTimeAnalysisEntries.get(i);\r
+ break;\r
+ }\r
+ }\r
+ if (timeAnalysisEntry == null) {\r
+ timeAnalysisEntry = new TimeChartAnalysisEntry(trace, fDisplayWidth * 2); \r
+ fTimeAnalysisEntries.add(timeAnalysisEntry);\r
+ fDecorationProviders.put(trace, new TimeChartDecorationProvider(resource));\r
+ Thread thread = new ProcessTraceThread(timeAnalysisEntry);\r
+ thread.start();\r
+ }\r
+ refreshViewer(true);\r
+ if (eventsFilterProvider != null) {\r
+ eventsFilterProvider.addEventsFilterListener(this);\r
+ }\r
+ }\r
+ \r
+ @TmfSignalHandler\r
+ public void traceClosed(TmfTraceClosedSignal signal) {\r
+ if (fTimeAnalysisEntries == null) return;\r
+ final ITmfTrace trace = signal.getTrace();\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {\r
+ fTimeAnalysisEntries.remove(i);\r
+ fDecorationProviders.remove(trace);\r
+ refreshViewer(true);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ \r
+ @TmfSignalHandler\r
+ public void traceSelected(TmfTraceSelectedSignal signal) {\r
+ if (signal.getSource() != this && fTimeAnalysisEntries != null) {\r
+ ITmfTrace trace = signal.getTrace();\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ if (fTimeAnalysisEntries.get(i).getTrace().equals(trace)) {\r
+ fViewer.setSelectedTrace(fTimeAnalysisEntries.get(i));\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ @TmfSignalHandler\r
+ public void traceUpdated(TmfTraceUpdatedSignal signal) {\r
+ if (fTimeAnalysisEntries == null) return;\r
+ final ITmfTrace trace = signal.getTrace();\r
+ for (int i = 0; i < fTimeAnalysisEntries.size(); i++) {\r
+ TimeChartAnalysisEntry timeAnalysisEntry = fTimeAnalysisEntries.get(i);\r
+ if (timeAnalysisEntry.getTrace().equals(trace)) {\r
+ updateTraceEntry(timeAnalysisEntry, Long.MAX_VALUE, 0, Long.MAX_VALUE);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ @TmfSignalHandler\r
+ public void currentTimeUpdated(TmfTimeSynchSignal signal) {\r
+ long time = signal.getCurrentTime().synchronize(0, TIMESTAMP_SCALE).getValue();\r
+ fViewer.setSelectedTime(time, true, this);\r
+ }\r
+\r
+}\r