Fix seekEvent() problem and augment TmfExperimentTest
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / widgets / Utils.java
1 /*****************************************************************************
2 * Copyright (c) 2007, 2008 Intel Corporation, 2009, 2012 Ericsson.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alvaro Sanchez-Leon - Udpated for TMF
12 * Patrick Tasse - Refactoring
13 *
14 *****************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
17
18 import java.text.SimpleDateFormat;
19 import java.util.Date;
20 import java.util.Iterator;
21
22 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;
23 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
24 import org.eclipse.swt.graphics.Color;
25 import org.eclipse.swt.graphics.Device;
26 import org.eclipse.swt.graphics.GC;
27 import org.eclipse.swt.graphics.Point;
28 import org.eclipse.swt.graphics.Rectangle;
29 import org.eclipse.swt.widgets.Display;
30
31 /**
32 * General utilities and definitions used by the time graph widget
33 *
34 * @version 1.0
35 * @author Alvaro Sanchez-Leon
36 * @author Patrick Tasse
37 */
38 public class Utils {
39
40 /** Time format for dates and timestamp */
41 public enum TimeFormat {
42 /** Relative to the start of the trace */
43 RELATIVE,
44 /** Absolute timestamp (ie, relative to the Unix epoch) */
45 ABSOLUTE
46 }
47
48 static public final int IMG_THREAD_RUNNING = 0;
49 static public final int IMG_THREAD_SUSPENDED = 1;
50 static public final int IMG_THREAD_STOPPED = 2;
51 static public final int IMG_METHOD_RUNNING = 3;
52 static public final int IMG_METHOD = 4;
53 static public final int IMG_NUM = 5;
54
55 static public final Object[] _empty = new Object[0];
56
57 public static enum Resolution {
58 SECONDS, MILLISEC, MICROSEC, NANOSEC
59 }
60
61 static private final SimpleDateFormat stimeformat = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
62 static private final SimpleDateFormat sdateformat = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
63
64 static Rectangle clone(Rectangle source) {
65 return new Rectangle(source.x, source.y, source.width, source.height);
66 }
67
68 /**
69 * Initialize a Rectangle object to default values (all equal to 0)
70 *
71 * @param rect
72 * The Rectangle to initialize
73 */
74 static public void init(Rectangle rect) {
75 rect.x = 0;
76 rect.y = 0;
77 rect.width = 0;
78 rect.height = 0;
79 }
80
81 /**
82 * Initialize a Rectangle object with all the given values
83 *
84 * @param rect
85 * The Rectangle object to initialize
86 * @param x
87 * The X coordinate
88 * @param y
89 * The Y coordinate
90 * @param width
91 * The width of the rectangle
92 * @param height
93 * The height of the rectangle
94 */
95 static public void init(Rectangle rect, int x, int y, int width, int height) {
96 rect.x = x;
97 rect.y = y;
98 rect.width = width;
99 rect.height = height;
100 }
101
102 /**
103 * Initialize a Rectangle object to another existing Rectangle's values.
104 *
105 * @param rect
106 * The Rectangle to initialize
107 * @param source
108 * The reference Rectangle to copy
109 */
110 static public void init(Rectangle rect, Rectangle source) {
111 rect.x = source.x;
112 rect.y = source.y;
113 rect.width = source.width;
114 rect.height = source.height;
115 }
116
117 /**
118 * Reduce the size of a given rectangle by the given amounts.
119 *
120 * @param rect
121 * The rectangle to modify
122 * @param x
123 * The reduction in width
124 * @param y
125 * The reduction in height
126 */
127 static public void deflate(Rectangle rect, int x, int y) {
128 rect.x += x;
129 rect.y += y;
130 rect.width -= x + x;
131 rect.height -= y + y;
132 }
133
134 /**
135 * Increase the size of a given rectangle by the given amounts.
136 *
137 * @param rect
138 * The rectangle to modify
139 * @param x
140 * The augmentation in width
141 * @param y
142 * The augmentation in height
143 */
144 static public void inflate(Rectangle rect, int x, int y) {
145 rect.x -= x;
146 rect.y -= y;
147 rect.width += x + x;
148 rect.height += y + y;
149 }
150
151 static void dispose(Color col) {
152 if (null != col) {
153 col.dispose();
154 }
155 }
156
157 /**
158 * Get the resulting color from a mix of two existing ones for a given
159 * display.
160 *
161 * @param display
162 * The display device (which might affect the color conversion)
163 * @param c1
164 * The first color
165 * @param c2
166 * The second color
167 * @param w1
168 * The gamma level for color 1
169 * @param w2
170 * The gamma level for color 2
171 * @return The resulting color
172 */
173 static public Color mixColors(Device display, Color c1, Color c2, int w1,
174 int w2) {
175 return new Color(display, (w1 * c1.getRed() + w2 * c2.getRed())
176 / (w1 + w2), (w1 * c1.getGreen() + w2 * c2.getGreen())
177 / (w1 + w2), (w1 * c1.getBlue() + w2 * c2.getBlue())
178 / (w1 + w2));
179 }
180
181 /**
182 * Get the system color with the given ID.
183 *
184 * @param id
185 * The color ID
186 * @return The resulting color
187 */
188 static public Color getSysColor(int id) {
189 Color col = Display.getCurrent().getSystemColor(id);
190 return new Color(col.getDevice(), col.getRGB());
191 }
192
193 /**
194 * Get the resulting color from a mix of two existing ones for the current
195 * display.
196 *
197 * @param col1
198 * The first color
199 * @param col2
200 * The second color
201 * @param w1
202 * The gamma level for color 1
203 * @param w2
204 * The gamma level for color 2
205 * @return The resulting color
206 */
207 static public Color mixColors(Color col1, Color col2, int w1, int w2) {
208 return mixColors(Display.getCurrent(), col1, col2, w1, w2);
209 }
210
211 /**
212 * Draw text in a rectangle.
213 *
214 * @param gc
215 * The SWT GC object
216 * @param text
217 * The text to draw
218 * @param rect
219 * The rectangle object which is being drawn
220 * @param transp
221 * Should we transpose the color
222 * @return The X coordinate where we have written
223 */
224 static public int drawText(GC gc, String text, Rectangle rect, boolean transp) {
225 Point size = gc.stringExtent(text);
226 gc.drawText(text, rect.x, rect.y, transp);
227 return size.x;
228 }
229
230 /**
231 * Draw text at a given location.
232 *
233 * @param gc
234 * The SWT GC object
235 * @param text
236 * The text to draw
237 * @param x
238 * The X coordinate of the starting point
239 * @param y
240 * the Y coordinate of the starting point
241 * @param transp
242 * Should we transpose the color
243 * @return The X coordinate where we have written
244 */
245 static public int drawText(GC gc, String text, int x, int y, boolean transp) {
246 Point size = gc.stringExtent(text);
247 gc.drawText(text, x, y, transp);
248 return size.x;
249 }
250
251 /**
252 * Formats time in format: MM:SS:NNN
253 *
254 * @param time time
255 * @param format 0: MMMM:ss:nnnnnnnnn, 1: HH:MM:ss MMM.mmmm.nnn
256 * @param resolution the resolution
257 * @return the formatted time
258 */
259 static public String formatTime(long time, TimeFormat format, Resolution resolution) {
260 // if format is absolute (Calendar)
261 if (format == TimeFormat.ABSOLUTE) {
262 return formatTimeAbs(time, resolution);
263 }
264
265 StringBuffer str = new StringBuffer();
266 boolean neg = time < 0;
267 if (neg) {
268 time = -time;
269 str.append('-');
270 }
271
272 long sec = (long) (time * 1E-9);
273 // TODO: Expand to make it possible to select the minute, second, nanosecond format
274 //printing minutes is suppressed just sec and ns
275 // if (sec / 60 < 10)
276 // str.append('0');
277 // str.append(sec / 60);
278 // str.append(':');
279 // sec %= 60;
280 // if (sec < 10)
281 // str.append('0');
282 str.append(sec);
283 String ns = formatNs(time, resolution);
284 if (!ns.equals("")) { //$NON-NLS-1$
285 str.append('.');
286 str.append(ns);
287 }
288
289 return str.toString();
290 }
291
292 /**
293 * From input time in nanoseconds, convert to Date format YYYY-MM-dd
294 *
295 * @param absTime
296 * The source time, in ns
297 * @return the formatted date
298 */
299 public static String formatDate(long absTime) {
300 String sdate = sdateformat.format(new Date((long) (absTime * 1E-6)));
301 return sdate;
302 }
303
304 /**
305 * Formats time in ns to Calendar format: HH:MM:SS MMM.mmm.nnn
306 *
307 * @param time
308 * The source time, in ns
309 * @param res
310 * The resolution to use
311 * @return the formatted time
312 */
313 static public String formatTimeAbs(long time, Resolution res) {
314 StringBuffer str = new StringBuffer();
315
316 // format time from nanoseconds to calendar time HH:MM:SS
317 String stime = stimeformat.format(new Date((long) (time * 1E-6)));
318 str.append(stime);
319 str.append('.');
320 // append the Milliseconds, MicroSeconds and NanoSeconds as specified in
321 // the Resolution
322 str.append(formatNs(time, res));
323 return str.toString();
324 }
325
326 /**
327 * Obtains the remainder fraction on unit Seconds of the entered value in
328 * nanoseconds. e.g. input: 1241207054171080214 ns The number of fraction
329 * seconds can be obtained by removing the last 9 digits: 1241207054 the
330 * fractional portion of seconds, expressed in ns is: 171080214
331 *
332 * @param time
333 * The source time in ns
334 * @param res
335 * The Resolution to use
336 * @return the formatted nanosec
337 */
338 public static String formatNs(long time, Resolution res) {
339 StringBuffer str = new StringBuffer();
340 boolean neg = time < 0;
341 if (neg) {
342 time = -time;
343 }
344
345 // The following approach could be used although performance
346 // decreases in half.
347 // String strVal = String.format("%09d", time);
348 // String tmp = strVal.substring(strVal.length() - 9);
349
350 long ns = time;
351 ns %= 1000000000;
352 if (ns < 10) {
353 str.append("00000000"); //$NON-NLS-1$
354 } else if (ns < 100) {
355 str.append("0000000"); //$NON-NLS-1$
356 } else if (ns < 1000) {
357 str.append("000000"); //$NON-NLS-1$
358 } else if (ns < 10000) {
359 str.append("00000"); //$NON-NLS-1$
360 } else if (ns < 100000) {
361 str.append("0000"); //$NON-NLS-1$
362 } else if (ns < 1000000) {
363 str.append("000"); //$NON-NLS-1$
364 } else if (ns < 10000000) {
365 str.append("00"); //$NON-NLS-1$
366 } else if (ns < 100000000) {
367 str.append("0"); //$NON-NLS-1$
368 }
369 str.append(ns);
370
371 if (res == Resolution.MILLISEC) {
372 return str.substring(0, 3);
373 } else if (res == Resolution.MICROSEC) {
374 return str.substring(0, 6);
375 } else if (res == Resolution.NANOSEC) {
376 return str.substring(0, 9);
377 }
378 return ""; //$NON-NLS-1$
379 }
380
381 /**
382 * FIXME Currently does nothing.
383 *
384 * @param opt
385 * The option name
386 * @param def
387 * The option value
388 * @param min
389 * The minimal accepted value
390 * @param max
391 * The maximal accepted value
392 * @return The value that was read
393 */
394 static public int loadIntOption(String opt, int def, int min, int max) {
395 // int val =
396 // TraceUIPlugin.getDefault().getPreferenceStore().getInt(opt);
397 // if (0 == val)
398 // val = def;
399 // if (val < min)
400 // val = min;
401 // if (val > max)
402 // val = max;
403 return def;
404 }
405
406 /**
407 * FIXME currently does nothing
408 *
409 * @param opt
410 * The option name
411 * @param val
412 * The option value
413 */
414 static public void saveIntOption(String opt, int val) {
415 // TraceUIPlugin.getDefault().getPreferenceStore().setValue(opt, val);
416 }
417
418 static ITimeEvent getFirstEvent(ITimeGraphEntry entry) {
419 if (null == entry || ! entry.hasTimeEvents()) {
420 return null;
421 }
422 Iterator<ITimeEvent> iterator = entry.getTimeEventsIterator();
423 if (iterator != null && iterator.hasNext()) {
424 return iterator.next();
425 }
426 return null;
427 }
428
429 /**
430 * N means: <list> <li>-1: Previous Event</li> <li>0: Current Event</li> <li>
431 * 1: Next Event</li> <li>2: Previous Event when located in a non Event Area
432 * </list>
433 *
434 * @param entry
435 * @param time
436 * @param n
437 * @return
438 */
439 static ITimeEvent findEvent(ITimeGraphEntry entry, long time, int n) {
440 if (null == entry || ! entry.hasTimeEvents()) {
441 return null;
442 }
443 Iterator<ITimeEvent> iterator = entry.getTimeEventsIterator();
444 if (iterator == null) {
445 return null;
446 }
447 ITimeEvent nextEvent = null;
448 ITimeEvent currEvent = null;
449 ITimeEvent prevEvent = null;
450
451 while (iterator.hasNext()) {
452 nextEvent = iterator.next();
453 long nextStartTime = nextEvent.getTime();
454
455 if (nextStartTime > time) {
456 break;
457 }
458
459 if (currEvent == null || currEvent.getTime() != nextStartTime) {
460 prevEvent = currEvent;
461 currEvent = nextEvent;
462 }
463 }
464
465 if (n == -1) { //previous
466 if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) {
467 return prevEvent;
468 }
469 return currEvent;
470 } else if (n == 0) { //current
471 if (currEvent != null && currEvent.getTime() + currEvent.getDuration() >= time) {
472 return currEvent;
473 }
474 return null;
475 } else if (n == 1) { //next
476 if (nextEvent != null && nextEvent.getTime() > time) {
477 return nextEvent;
478 }
479 return null;
480 } else if (n == 2) { //current or previous when in empty space
481 return currEvent;
482 }
483
484 return null;
485 }
486
487 /**
488 * Pretty-print a method signature.
489 *
490 * @param sig
491 * The original signature
492 * @return The pretty signature
493 */
494 static public String fixMethodSignature(String sig) {
495 int pos = sig.indexOf('(');
496 if (pos >= 0) {
497 String ret = sig.substring(0, pos);
498 sig = sig.substring(pos);
499 sig = sig + " " + ret; //$NON-NLS-1$
500 }
501 return sig;
502 }
503
504 /**
505 * Restore an original method signature from a pretty-printed one.
506 *
507 * @param sig
508 * The pretty-printed signature
509 * @return The original method signature
510 */
511 static public String restoreMethodSignature(String sig) {
512 String ret = ""; //$NON-NLS-1$
513 int pos = sig.indexOf('(');
514 if (pos >= 0) {
515 ret = sig.substring(0, pos);
516 sig = sig.substring(pos + 1);
517 }
518 pos = sig.indexOf(')');
519 if (pos >= 0) {
520 sig = sig.substring(0, pos);
521 }
522 String args[] = sig.split(","); //$NON-NLS-1$
523 StringBuffer result = new StringBuffer("("); //$NON-NLS-1$
524 for (int i = 0; i < args.length; i++) {
525 String arg = args[i].trim();
526 if (arg.length() == 0 && args.length == 1) {
527 break;
528 }
529 result.append(getTypeSignature(arg));
530 }
531 result.append(")").append(getTypeSignature(ret)); //$NON-NLS-1$
532 return result.toString();
533 }
534
535 /**
536 * Get the mangled type information from an array of types.
537 *
538 * @param type
539 * The types to convert. See method implementation for what it
540 * expects.
541 * @return The mangled string of types
542 */
543 @SuppressWarnings("nls")
544 static public String getTypeSignature(String type) {
545 int dim = 0;
546 for (int j = 0; j < type.length(); j++) {
547 if (type.charAt(j) == '[') {
548 dim++;
549 }
550 }
551 int pos = type.indexOf('[');
552 if (pos >= 0) {
553 type = type.substring(0, pos);
554 }
555 StringBuffer sig = new StringBuffer(""); //$NON-NLS-1$
556 for (int j = 0; j < dim; j++)
557 {
558 sig.append("["); //$NON-NLS-1$
559 }
560 if (type.equals("boolean")) { //$NON-NLS-1$
561 sig.append('Z');
562 } else if (type.equals("byte")) { //$NON-NLS-1$
563 sig.append('B');
564 } else if (type.equals("char")) { //$NON-NLS-1$
565 sig.append('C');
566 } else if (type.equals("short")) { //$NON-NLS-1$
567 sig.append('S');
568 } else if (type.equals("int")) { //$NON-NLS-1$
569 sig.append('I');
570 } else if (type.equals("long")) { //$NON-NLS-1$
571 sig.append('J');
572 } else if (type.equals("float")) { //$NON-NLS-1$
573 sig.append('F');
574 } else if (type.equals("double")) { //$NON-NLS-1$
575 sig.append('D');
576 } else if (type.equals("void")) { //$NON-NLS-1$
577 sig.append('V');
578 }
579 else {
580 sig.append('L').append(type.replace('.', '/')).append(';');
581 }
582 return sig.toString();
583 }
584
585 /**
586 * Compare two doubles together.
587 *
588 * @param d1
589 * First double
590 * @param d2
591 * Second double
592 * @return 1 if they are different, and 0 if they are *exactly* the same.
593 * Because of the way doubles are stored, it's possible for the
594 * same number obtained in two different ways to actually look
595 * different.
596 */
597 static public int compare(double d1, double d2) {
598 if (d1 > d2) {
599 return 1;
600 }
601 if (d1 < d2) {
602 return 1;
603 }
604 return 0;
605 }
606
607 /**
608 * Compare two character strings alphabetically. This is simply a wrapper
609 * around String.compareToIgnoreCase but that will handle cases where
610 * strings can be null
611 *
612 * @param s1
613 * The first string
614 * @param s2
615 * The second string
616 * @return A number below, equal, or greater than zero if the first string
617 * is smaller, equal, or bigger (alphabetically) than the second
618 * one.
619 */
620 static public int compare(String s1, String s2) {
621 if (s1 != null && s2 != null) {
622 return s1.compareToIgnoreCase(s2);
623 }
624 if (s1 != null) {
625 return 1;
626 }
627 if (s2 != null) {
628 return -1;
629 }
630 return 0;
631 }
632 }
This page took 0.04589 seconds and 6 git commands to generate.