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