1 /*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Florian Wininger - Initial API and implementation
11 * Geneviève Bastien - Review of the initial implementation
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.views
.timegraph
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Collections
;
18 import java
.util
.HashMap
;
19 import java
.util
.List
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.swt
.graphics
.GC
;
24 import org
.eclipse
.swt
.graphics
.RGB
;
25 import org
.eclipse
.swt
.graphics
.Rectangle
;
26 import org
.eclipse
.swt
.widgets
.Display
;
27 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.module
.XmlUtils
;
28 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.core
.stateprovider
.TmfXmlStrings
;
29 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.TmfXmlUiStrings
;
30 import org
.eclipse
.tracecompass
.internal
.tmf
.analysis
.xml
.ui
.views
.timegraph
.XmlEntry
.EntryDisplayType
;
31 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.StateItem
;
32 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
33 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
34 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
35 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.TimeEvent
;
36 import org
.w3c
.dom
.Element
;
39 * Presentation provider for the XML view, based on the generic TMF presentation
42 * TODO: This should support colors/states defined for each entry element in the
45 * @author Florian Wininger
47 public class XmlPresentationProvider
extends TimeGraphPresentationProvider
{
49 private static final long[] COLOR_SEED
= { 0x0000ff, 0xff0000, 0x00ff00,
50 0xff00ff, 0x00ffff, 0xffff00, 0x000000, 0xf07300
53 private static final int COLOR_MASK
= 0xffffff;
55 private List
<StateItem
> stateValues
= new ArrayList
<>();
57 * Maps the value of an event with the corresponding index in the
60 private Map
<Integer
, Integer
> stateIndex
= new HashMap
<>();
63 public int getStateTableIndex(ITimeEvent event
) {
64 if (event
instanceof TimeEvent
&& ((TimeEvent
) event
).hasValue()) {
65 TimeEvent tcEvent
= (TimeEvent
) event
;
67 XmlEntry entry
= (XmlEntry
) event
.getEntry();
68 int value
= tcEvent
.getValue();
70 if (entry
.getType() == EntryDisplayType
.DISPLAY
) {
71 // Draw state only if state is already known
72 Integer index
= stateIndex
.get(value
);
82 public StateItem
[] getStateTable() {
83 return stateValues
.toArray(new StateItem
[stateValues
.size()]);
87 public String
getEventName(ITimeEvent event
) {
88 if (event
instanceof TimeEvent
&& ((TimeEvent
) event
).hasValue()) {
89 TimeEvent tcEvent
= (TimeEvent
) event
;
91 XmlEntry entry
= (XmlEntry
) event
.getEntry();
92 int value
= tcEvent
.getValue();
94 if (entry
.getType() == EntryDisplayType
.DISPLAY
) {
95 Integer index
= stateIndex
.get(value
);
97 String rgb
= stateValues
.get(index
.intValue()).getStateString();
103 return Messages
.XmlPresentationProvider_MultipleStates
;
107 public Map
<String
, String
> getEventHoverToolTipInfo(ITimeEvent event
, long hoverTime
) {
109 * TODO: Add the XML elements to support adding extra information in the
110 * tooltips and implement this
112 return Collections
.EMPTY_MAP
;
116 public void postDrawEvent(ITimeEvent event
, Rectangle bounds
, GC gc
) {
118 * TODO Add the XML elements to support texts in intervals and implement
124 public void postDrawEntry(ITimeGraphEntry entry
, Rectangle bounds
, GC gc
) {
128 * Loads the states from a {@link TmfXmlUiStrings#TIME_GRAPH_VIEW} XML
132 * The XML view element
134 public synchronized void loadNewStates(@NonNull Element viewElement
) {
137 List
<Element
> states
= XmlUtils
.getChildElements(viewElement
, TmfXmlStrings
.DEFINED_VALUE
);
139 for (Element state
: states
) {
140 int value
= Integer
.parseInt(state
.getAttribute(TmfXmlStrings
.VALUE
));
141 String name
= state
.getAttribute(TmfXmlStrings
.NAME
);
142 String color
= state
.getAttribute(TmfXmlStrings
.COLOR
);
144 addOrUpdateState(value
, name
, color
);
146 Display
.getDefault().asyncExec(new Runnable() {
149 fireColorSettingsChanged();
155 * Add a new state in the time graph view. This allow to define at runtime
156 * new states that cannot be known at the conception of this analysis.
159 * The string associated with the state
160 * @return the value for this state
162 public synchronized int addState(String name
) {
163 // Find a value for this name, start at 10000
165 while (stateIndex
.get(value
) != null) {
168 addOrUpdateState(value
, name
, ""); //$NON-NLS-1$
169 Display
.getDefault().asyncExec(new Runnable() {
172 fireColorSettingsChanged();
178 private synchronized void addOrUpdateState(int value
, String name
, String color
) {
179 // FIXME Allow this case
184 final RGB colorRGB
= (color
.startsWith(TmfXmlStrings
.COLOR_PREFIX
)) ?
parseColor(color
) : calcColor(name
);
186 StateItem item
= new StateItem(colorRGB
, name
);
188 Integer index
= stateIndex
.get(value
);
190 /* Add the new state value */
191 stateIndex
.put(value
, stateValues
.size());
192 stateValues
.add(item
);
194 /* Override a previous state value */
195 stateValues
.set(index
, item
);
199 private static RGB
parseColor(String color
) {
201 Integer hex
= Integer
.parseInt(color
.substring(1), 16);
202 int hex1
= hex
.intValue() % 256;
203 int hex2
= (hex
.intValue() / 256) % 256;
204 int hex3
= (hex
.intValue() / (256 * 256)) % 256;
205 colorRGB
= new RGB(hex3
, hex2
, hex1
);
210 * This method will always return the same color for a same name, no matter
211 * the value, so that different traces with the same XML analysis will
212 * display identically states with the same name.
214 private static RGB
calcColor(String name
) {
215 int hash
= name
.hashCode();
216 long base
= COLOR_SEED
[Math
.abs(hash
) % COLOR_SEED
.length
];
217 int x
= (int) ((hash
& COLOR_MASK
) ^ base
);
218 final int r
= (x
>> 16) & 0xff;
219 final int g
= (x
>> 8) & 0xff;
220 final int b
= x
& 0xff;
221 return new RGB(r
, g
, b
);