ctf: make DeclarationScope.java more inline with coding style
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / widgets / TimeGraphScale.java
CommitLineData
8e1f81f1 1/*****************************************************************************
c8422608 2 * Copyright (c) 2007, 2013 Intel Corporation, Ericsson
8e1f81f1
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:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alvaro Sanchez-Leon - Updated for TMF
12 * Patrick Tasse - Refactoring
c1cd9635 13 * Marc-Andre Laperle - Add time zone preference
8e1f81f1
PT
14 *****************************************************************************/
15
16package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;
17
026664b7 18import java.text.NumberFormat;
8e1f81f1
PT
19import java.text.SimpleDateFormat;
20import java.util.Calendar;
21import java.util.Date;
c1cd9635 22import java.util.TimeZone;
8e1f81f1 23
c1cd9635
MAL
24import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
25import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
26import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal;
27import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences;
8e1f81f1 28import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
026664b7 29import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
8e1f81f1
PT
30import org.eclipse.swt.SWT;
31import org.eclipse.swt.events.MouseEvent;
32import org.eclipse.swt.events.MouseListener;
33import org.eclipse.swt.events.MouseMoveListener;
34import org.eclipse.swt.events.PaintEvent;
35import org.eclipse.swt.graphics.GC;
36import org.eclipse.swt.graphics.Point;
37import org.eclipse.swt.graphics.Rectangle;
38import org.eclipse.swt.widgets.Composite;
39
40/**
41 * Implementation of the scale for the time graph view.
42 *
43 * This goes above the "gantt chart" area.
44 *
45 * @version 1.0
46 * @author Alvaro Sanchez-Leon
47 * @author Patrick Tasse
48 */
49public class TimeGraphScale extends TimeGraphBaseControl implements
50 MouseListener, MouseMoveListener {
51
f1fae91f
PT
52 private static final long MICROSEC_IN_NS = 1000;
53 private static final long MILLISEC_IN_NS = 1000000;
8e1f81f1
PT
54 private static final long SEC_IN_NS = 1000000000;
55 private static final long MIN_IN_NS = 60 * SEC_IN_NS;
56 private static final long HOUR_IN_NS = 60 * MIN_IN_NS;
57 private static final long DAY_IN_NS = 24 * HOUR_IN_NS;
58 private static final long MONTH_IN_NS = 31 * DAY_IN_NS; // upper limit
59 private static final long YEAR_IN_NS = 366 * DAY_IN_NS; // upper limit
60
61 private static final double LOG10_1 = Math.log10(1);
62 private static final double LOG10_2 = Math.log10(2);
63 private static final double LOG10_3 = Math.log10(3);
64 private static final double LOG10_5 = Math.log10(5);
65
66 private static final Calendar GREGORIAN_CALENDAR = Calendar.getInstance();
67
f1fae91f
PT
68 private static final TimeDraw TIMEDRAW_NANOSEC = new TimeDrawNanosec();
69 private static final TimeDraw TIMEDRAW_MICROSEC = new TimeDrawMicrosec();
70 private static final TimeDraw TIMEDRAW_MILLISEC = new TimeDrawMillisec();
71 private static final TimeDraw TIMEDRAW_SEC = new TimeDrawSec();
72 private static final TimeDraw TIMEDRAW_ABS_NANOSEC = new TimeDrawAbsNanoSec();
73 private static final TimeDraw TIMEDRAW_ABS_MICROSEC = new TimeDrawAbsMicroSec();
74 private static final TimeDraw TIMEDRAW_ABS_MILLISEC = new TimeDrawAbsMillisec();
75 private static final TimeDraw TIMEDRAW_ABS_SEC = new TimeDrawAbsSec();
76 private static final TimeDraw TIMEDRAW_ABS_MIN = new TimeDrawAbsMin();
77 private static final TimeDraw TIMEDRAW_ABS_HRS = new TimeDrawAbsHrs();
78 private static final TimeDraw TIMEDRAW_ABS_DAY = new TimeDrawAbsDay();
79 private static final TimeDraw TIMEDRAW_ABS_MONTH = new TimeDrawAbsMonth();
80 private static final TimeDraw TIMEDRAW_ABS_YEAR = new TimeDrawAbsYear();
81 private static final TimeDraw TIMEDRAW_NUMBER = new TimeDrawNumber();
82
0fcf3b09 83 private static final int DRAG_EXTERNAL = -1;
f1fae91f
PT
84 private static final int NO_BUTTON = 0;
85 private static final int LEFT_BUTTON = 1;
f1fae91f
PT
86
87 private ITimeDataProvider fTimeProvider;
88 private int fDragState = NO_BUTTON;
89 private int fDragX0 = 0;
90 private int fDragX = 0;
91 private long fTime0bak;
92 private long fTime1bak;
93 private boolean fIsInUpdate;
94 private int fHeight;
95
96 /**
97 * Standard constructor
98 *
99 * @param parent
100 * The parent composite object
101 * @param colors
102 * The color scheme to use
103 */
104 public TimeGraphScale(Composite parent, TimeGraphColorScheme colors) {
105 super(parent, colors, SWT.NO_BACKGROUND | SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED);
c1cd9635 106 TmfSignalManager.register(this);
f1fae91f
PT
107 addMouseListener(this);
108 addMouseMoveListener(this);
c1cd9635
MAL
109 TimeDraw.updateTimeZone();
110 }
111
112 @Override
113 public void dispose() {
114 TmfSignalManager.deregister(this);
115 super.dispose();
f1fae91f 116 }
8e1f81f1
PT
117
118 /**
119 * Assign the time provider for this scale
120 *
121 * @param timeProvider
122 * The provider to use
123 */
124 public void setTimeProvider(ITimeDataProvider timeProvider) {
f1fae91f 125 fTimeProvider = timeProvider;
8e1f81f1
PT
126 }
127
8e1f81f1
PT
128 @Override
129 public Point computeSize(int wHint, int hHint, boolean changed) {
f1fae91f 130 return super.computeSize(wHint, fHeight, changed);
8e1f81f1
PT
131 }
132
133 /**
134 * Set the height of the scale
135 *
136 * @param height
137 * The height to use
138 */
139 public void setHeight(int height) {
f1fae91f 140 this.fHeight = height;
8e1f81f1
PT
141 }
142
0fcf3b09
PT
143 /**
144 * Set the drag range to paint decorators
145 *
146 * @param begin
147 * The begin x-coordinate
148 * @param end
149 * The end x-coordinate
4b121c48 150 * @since 2.1
0fcf3b09
PT
151 */
152 public void setDragRange(int begin, int end) {
153 if (NO_BUTTON == fDragState || DRAG_EXTERNAL == fDragState) {
154 fDragX0 = begin - fTimeProvider.getNameSpace();
155 fDragX = end - fTimeProvider.getNameSpace();
156 if (begin >= 0 || end >= 0) {
157 fDragState = DRAG_EXTERNAL;
158 } else {
159 fDragState = NO_BUTTON;
160 }
161 }
162 redraw();
163 }
164
f1fae91f
PT
165 private long calcTimeDelta(int width, double pixelsPerNanoSec) {
166 long timeDelta;
8e1f81f1
PT
167 double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec;
168 long unit = 1;
f1fae91f 169 if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) {
8e1f81f1
PT
170 if (minDelta > 6 * MONTH_IN_NS) {
171 unit = YEAR_IN_NS;
172 } else if (minDelta > 3 * MONTH_IN_NS) {
173 unit = 6 * MONTH_IN_NS;
174 } else if (minDelta > 10 * DAY_IN_NS) {
175 unit = MONTH_IN_NS;
176 } else if (minDelta > 12 * HOUR_IN_NS) {
177 unit = DAY_IN_NS;
178 } else if (minDelta > 3 * HOUR_IN_NS) {
179 unit = 6 * HOUR_IN_NS;
180 } else if (minDelta > 30 * MIN_IN_NS) {
181 unit = HOUR_IN_NS;
182 } else if (minDelta > 10 * MIN_IN_NS) {
183 unit = 15 * MIN_IN_NS;
184 } else if (minDelta > 30 * SEC_IN_NS) {
185 unit = MIN_IN_NS;
186 } else if (minDelta > 20 * SEC_IN_NS) {
187 unit = 30 * SEC_IN_NS;
188 } else if (minDelta <= 1) {
f1fae91f
PT
189 timeDelta = 1;
190 return timeDelta;
8e1f81f1
PT
191 }
192 }
193 double log = Math.log10(minDelta / unit);
194 long pow10 = (long) log;
195 double remainder = log - pow10;
196 if (remainder < LOG10_1) {
f1fae91f 197 timeDelta = (long) Math.pow(10, pow10) * unit;
8e1f81f1 198 } else if (remainder < LOG10_2) {
f1fae91f 199 timeDelta = 2 * (long) Math.pow(10, pow10) * unit;
8e1f81f1 200 } else if (remainder < LOG10_3 && unit >= HOUR_IN_NS && unit < YEAR_IN_NS) {
f1fae91f 201 timeDelta = 3 * (long) Math.pow(10, pow10) * unit;
8e1f81f1 202 } else if (remainder < LOG10_5) {
f1fae91f 203 timeDelta = 5 * (long) Math.pow(10, pow10) * unit;
8e1f81f1 204 } else {
f1fae91f 205 timeDelta = 10 * (long) Math.pow(10, pow10) * unit;
8e1f81f1 206 }
f1fae91f
PT
207 if (timeDelta <= 0) {
208 timeDelta = 1;
f85266f3 209 }
f1fae91f 210 return timeDelta;
8e1f81f1
PT
211 }
212
8e1f81f1
PT
213 TimeDraw getTimeDraw(long timeDelta) {
214 TimeDraw timeDraw;
f1fae91f 215 if (fTimeProvider != null) {
026664b7 216
f1fae91f 217 if (fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) {
026664b7
XR
218 if (timeDelta >= YEAR_IN_NS) {
219 timeDraw = TIMEDRAW_ABS_YEAR;
220 } else if (timeDelta >= MONTH_IN_NS) {
221 timeDraw = TIMEDRAW_ABS_MONTH;
222 } else if (timeDelta >= DAY_IN_NS) {
223 timeDraw = TIMEDRAW_ABS_DAY;
224 } else if (timeDelta >= HOUR_IN_NS) {
225 timeDraw = TIMEDRAW_ABS_HRS;
226 } else if (timeDelta >= MIN_IN_NS) {
227 timeDraw = TIMEDRAW_ABS_MIN;
228 } else if (timeDelta >= SEC_IN_NS) {
229 timeDraw = TIMEDRAW_ABS_SEC;
f1fae91f 230 } else if (timeDelta >= MILLISEC_IN_NS) {
026664b7 231 timeDraw = TIMEDRAW_ABS_MILLISEC;
f1fae91f 232 } else if (timeDelta >= MICROSEC_IN_NS) {
026664b7
XR
233 timeDraw = TIMEDRAW_ABS_MICROSEC;
234 } else {
235 timeDraw = TIMEDRAW_ABS_NANOSEC;
236 }
237 return timeDraw;
f1fae91f 238 } else if (fTimeProvider.getTimeFormat() == TimeFormat.NUMBER) {
026664b7
XR
239 timeDraw = TIMEDRAW_NUMBER;
240 return timeDraw;
8e1f81f1 241 }
026664b7 242
8e1f81f1 243 }
f1fae91f 244 if (timeDelta >= SEC_IN_NS) {
8e1f81f1 245 timeDraw = TIMEDRAW_SEC;
f1fae91f 246 } else if (timeDelta >= MILLISEC_IN_NS) {
8e1f81f1 247 timeDraw = TIMEDRAW_MILLISEC;
f1fae91f 248 } else if (timeDelta >= MICROSEC_IN_NS) {
8e1f81f1
PT
249 timeDraw = TIMEDRAW_MICROSEC;
250 } else {
251 timeDraw = TIMEDRAW_NANOSEC;
252 }
253 return timeDraw;
254 }
255
256 @Override
257 void paint(Rectangle rect, PaintEvent e) {
258
f1fae91f 259 if (fIsInUpdate || null == fTimeProvider) {
8e1f81f1
PT
260 return;
261 }
262
263 GC gc = e.gc;
264 gc.fillRectangle(rect);
265
f1fae91f
PT
266 long time0 = fTimeProvider.getTime0();
267 long time1 = fTimeProvider.getTime1();
f1fae91f
PT
268 int leftSpace = fTimeProvider.getNameSpace();
269 int timeSpace = fTimeProvider.getTimeSpace();
8e1f81f1 270
f1fae91f
PT
271 gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_BACKGROUND));
272 gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND));
273 Rectangle rect0 = new Rectangle(0, 0, 0, 0);
274 Utils.init(rect0, rect);
8e1f81f1
PT
275
276 // draw top left area
f1fae91f
PT
277 rect0.width = leftSpace;
278 rect0.x += 4;
279 rect0.width -= 4;
280 Rectangle absHeaderRect = new Rectangle(rect0.x, rect0.y, rect0.width, rect0.height);
281 rect0.x -= 4;
282 rect0.width += 4;
8e1f81f1
PT
283
284 // prepare and draw right rect of the timescale
f1fae91f
PT
285 rect0.x += leftSpace;
286 rect0.width = rect.width - leftSpace;
8e1f81f1
PT
287
288 // draw bottom border and erase all other area
289 gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1,
290 rect.y + rect.height - 1);
f1fae91f
PT
291 rect0.height--;
292 gc.fillRectangle(rect0);
8e1f81f1
PT
293
294 if (time1 <= time0 || timeSpace < 2) {
295 return;
296 }
297
298 int numDigits = calculateDigits(time0, time1);
299
300 int labelWidth = gc.getCharWidth('0') * numDigits;
301 double pixelsPerNanoSec = (timeSpace <= RIGHT_MARGIN) ? 0 :
302 (double) (timeSpace - RIGHT_MARGIN) / (time1 - time0);
f1fae91f 303 long timeDelta = calcTimeDelta(labelWidth, pixelsPerNanoSec);
8e1f81f1 304
f1fae91f 305 TimeDraw timeDraw = getTimeDraw(timeDelta);
8e1f81f1 306
0fcf3b09
PT
307 // draw range decorators
308 if (DRAG_EXTERNAL == fDragState) {
309 int x1 = leftSpace + Math.min(fDragX0, fDragX);
310 int x2 = leftSpace + Math.max(fDragX0, fDragX);
311 drawRangeDecorators(rect0, gc, x1, x2);
312 } else {
313 int x1;
314 int x2;
315 if (fTimeProvider instanceof ITimeDataProvider2) {
316 long selectionBegin = ((ITimeDataProvider2) fTimeProvider).getSelectionBegin();
317 long selectionEnd = ((ITimeDataProvider2) fTimeProvider).getSelectionEnd();
318 x1 = leftSpace + (int) ((selectionBegin - time0) * pixelsPerNanoSec);
319 x2 = leftSpace + (int) ((selectionEnd - time0) * pixelsPerNanoSec);
320 } else {
321 @SuppressWarnings("deprecation")
322 long selectedTime = fTimeProvider.getSelectedTime();
323 x1 = leftSpace + (int) ((selectedTime - time0) * pixelsPerNanoSec);
324 x2 = x1;
325 }
326 drawRangeDecorators(rect0, gc, x1, x2);
8e1f81f1
PT
327 }
328
f1fae91f 329 if (rect0.isEmpty()) {
8e1f81f1
PT
330 return;
331 }
332
8e1f81f1 333 // draw time scale ticks
f1fae91f
PT
334 rect0.y = rect.y;
335 rect0.height = rect.height - 4;
336 rect0.width = labelWidth;
8e1f81f1
PT
337
338 long time;
f1fae91f
PT
339 if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) {
340 time = floorToCalendar(time0, timeDelta);
8e1f81f1 341 } else {
f1fae91f 342 time = (time0 / timeDelta) * timeDelta;
8e1f81f1 343 if (time != time0) {
f1fae91f 344 time += timeDelta;
8e1f81f1
PT
345 }
346 }
347
f1fae91f 348 int y = rect0.y + rect0.height;
8e1f81f1 349
f1fae91f 350 if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) {
8e1f81f1
PT
351 timeDraw.drawAbsHeader(gc, time, absHeaderRect);
352 }
353
354 while (true) {
0fcf3b09 355 int x = rect.x + leftSpace + (int) (Math.floor((time - time0) * pixelsPerNanoSec));
f1fae91f 356 if (x >= rect.x + leftSpace + rect.width - rect0.width) {
8e1f81f1
PT
357 break;
358 }
359 if (x >= rect.x + leftSpace) {
360 gc.drawLine(x, y, x, y + 4);
f1fae91f
PT
361 rect0.x = x;
362 if (x + rect0.width <= rect.x + rect.width) {
363 timeDraw.draw(gc, time, rect0);
8e1f81f1
PT
364 }
365 }
f1fae91f 366 if (pixelsPerNanoSec == 0 || time > Long.MAX_VALUE - timeDelta || timeDelta == 0) {
8e1f81f1
PT
367 break;
368 }
f1fae91f
PT
369 if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) {
370 if (timeDelta >= YEAR_IN_NS) {
371 long millis = time / MILLISEC_IN_NS;
8e1f81f1 372 GREGORIAN_CALENDAR.setTime(new Date(millis));
f1fae91f 373 GREGORIAN_CALENDAR.add(Calendar.YEAR, (int) (timeDelta / YEAR_IN_NS));
8e1f81f1 374 millis = GREGORIAN_CALENDAR.getTimeInMillis();
f1fae91f
PT
375 time = millis * MILLISEC_IN_NS;
376 } else if (timeDelta >= MONTH_IN_NS) {
377 long millis = time / MILLISEC_IN_NS;
8e1f81f1 378 GREGORIAN_CALENDAR.setTime(new Date(millis));
f1fae91f 379 GREGORIAN_CALENDAR.add(Calendar.MONTH, (int) (timeDelta / MONTH_IN_NS));
8e1f81f1 380 millis = GREGORIAN_CALENDAR.getTimeInMillis();
f1fae91f
PT
381 time = millis * MILLISEC_IN_NS;
382 } else if (timeDelta >= DAY_IN_NS) {
383 long millis = time / MILLISEC_IN_NS;
8e1f81f1 384 GREGORIAN_CALENDAR.setTime(new Date(millis));
f1fae91f 385 GREGORIAN_CALENDAR.add(Calendar.DAY_OF_MONTH, (int) (timeDelta / DAY_IN_NS));
8e1f81f1 386 millis = GREGORIAN_CALENDAR.getTimeInMillis();
f1fae91f 387 time = millis * MILLISEC_IN_NS;
8e1f81f1 388 } else {
f1fae91f 389 time += timeDelta;
8e1f81f1
PT
390 }
391 } else {
f1fae91f 392 time += timeDelta;
8e1f81f1
PT
393 }
394 }
395 }
396
0fcf3b09
PT
397 private static void drawRangeDecorators(Rectangle rect, GC gc, int x1, int x2) {
398 int y1 = rect.y + rect.height - 9;
399 int y2 = rect.y + rect.height - 5;
400 int ym = (y1 + y2) / 2;
401 if (x1 >= rect.x) {
402 // T1
403 gc.drawLine(x1 - 3, y1, x1 - 3, y2);
404 gc.drawLine(x1 - 4, y1, x1 - 2, y1);
405 gc.drawLine(x1, y1, x1, y2);
406 }
407 if (x2 >= rect.x && x2 - x1 > 3) {
408 // T2
409 gc.drawLine(x2 - 2, y1, x2 - 2, y2);
410 gc.drawLine(x2 - 3, y1, x2 - 1, y1);
411 }
412 if (x2 >= rect.x && x2 - x1 > 0) {
413 gc.drawLine(x2 + 1, y1, x2 + 3, y1);
414 gc.drawLine(x2 + 3, y1, x2 + 3, ym);
415 gc.drawLine(x2 + 1, ym, x2 + 3, ym);
416 gc.drawLine(x2 + 1, ym, x2 + 1, y2);
417 gc.drawLine(x2 + 1, y2, x2 + 3, y2);
418 }
419 }
420
f1fae91f 421 private static long floorToCalendar(long time, long timeDelta) {
41b5c37f
AM
422 long ret = time;
423
f1fae91f
PT
424 if (timeDelta >= YEAR_IN_NS) {
425 GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS));
8e1f81f1
PT
426 int year = GREGORIAN_CALENDAR.get(Calendar.YEAR);
427 int yearDelta = (int) (timeDelta / YEAR_IN_NS);
428 year = (year / yearDelta) * yearDelta;
429 GREGORIAN_CALENDAR.set(Calendar.YEAR, year);
430 GREGORIAN_CALENDAR.set(Calendar.MONTH, 0); // January 1st of year
431 GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1);
432 GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0);
433 GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0);
434 GREGORIAN_CALENDAR.set(Calendar.SECOND, 0);
435 GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0);
f1fae91f
PT
436 ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS;
437 } else if (timeDelta >= MONTH_IN_NS) {
438 GREGORIAN_CALENDAR.setTime(new Date(ret / MILLISEC_IN_NS));
8e1f81f1
PT
439 int month = GREGORIAN_CALENDAR.get(Calendar.MONTH);
440 int monthDelta = (int) (timeDelta / MONTH_IN_NS);
441 month = (month / monthDelta) * monthDelta;
442 GREGORIAN_CALENDAR.set(Calendar.MONTH, month);
443 GREGORIAN_CALENDAR.set(Calendar.DAY_OF_MONTH, 1); // 1st of month
444 GREGORIAN_CALENDAR.set(Calendar.HOUR_OF_DAY, 0);
445 GREGORIAN_CALENDAR.set(Calendar.MINUTE, 0);
446 GREGORIAN_CALENDAR.set(Calendar.SECOND, 0);
447 GREGORIAN_CALENDAR.set(Calendar.MILLISECOND, 0);
f1fae91f 448 ret = GREGORIAN_CALENDAR.getTimeInMillis() * MILLISEC_IN_NS;
8e1f81f1 449 } else {
f1fae91f 450 long offset = GREGORIAN_CALENDAR.getTimeZone().getOffset(ret / MILLISEC_IN_NS) * MILLISEC_IN_NS;
41b5c37f
AM
451 ret += offset;
452 ret = (ret / timeDelta) * timeDelta;
453 ret -= offset;
8e1f81f1 454 }
41b5c37f 455 return ret;
8e1f81f1
PT
456 }
457
458 private int calculateDigits(long time0, long time1) {
459 int numDigits = 5;
460 long timeRange = time1 - time0;
461
f1fae91f 462 if (fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) {
8e1f81f1
PT
463 // Calculate the number of digits to represent the minutes provided
464 // 11:222
465 // HH:mm:ss
466 numDigits += 8;
467 if (timeRange < 10000) {
468 // HH:11:222:333:444__
469 numDigits += 10;
470 } else if (timeRange < 10000000) {
471 // HH:11:222:333__
472 numDigits += 6;
473 }
474 } else {
f1fae91f 475 long sec = time1 / SEC_IN_NS;
8e1f81f1
PT
476 numDigits = Long.toString(sec).length();
477 int thousandGroups = (numDigits - 1) / 3;
478 numDigits += thousandGroups;
479 numDigits += 12; // .000 000 000
480 }
481
482 return numDigits;
483 }
484
485 @Override
486 public void mouseDown(MouseEvent e) {
487 getParent().setFocus();
f1fae91f
PT
488 if (fDragState == NO_BUTTON && null != fTimeProvider) {
489 int x = e.x - fTimeProvider.getNameSpace();
490 if (LEFT_BUTTON == e.button && x > 0) {
8e1f81f1 491 setCapture(true);
f1fae91f 492 fDragState = LEFT_BUTTON;
8e1f81f1
PT
493 }
494 if (x < 0) {
495 x = 0;
f1fae91f
PT
496 } else if (x > getSize().x - fTimeProvider.getNameSpace()) {
497 x = getSize().x - fTimeProvider.getNameSpace();
8e1f81f1 498 }
f1fae91f
PT
499 fDragX = x;
500 fDragX0 = x;
501 fTime0bak = fTimeProvider.getTime0();
502 fTime1bak = fTimeProvider.getTime1();
8e1f81f1
PT
503 }
504 }
505
506 @Override
507 public void mouseUp(MouseEvent e) {
f1fae91f 508 if (e.button == LEFT_BUTTON && fDragState == LEFT_BUTTON) {
8e1f81f1 509 setCapture(false);
f1fae91f 510 fDragState = NO_BUTTON;
8e1f81f1
PT
511
512 // Notify time provider to check the need for listener notification
f1fae91f
PT
513 if (fDragX != fDragX0 && fTimeProvider.getTime0() != fTimeProvider.getTime1()) {
514 fTimeProvider.setStartFinishTimeNotify(fTimeProvider.getTime0(), fTimeProvider.getTime1());
8e1f81f1 515 }
8e1f81f1
PT
516 }
517 }
518
519 @Override
520 public void mouseMove(MouseEvent e) {
f1fae91f 521 if (fDragX0 < 0 || fDragState == NO_BUTTON || fTimeProvider == null) {
8e1f81f1
PT
522 return;
523 }
524 Point size = getSize();
f1fae91f 525 int leftSpace = fTimeProvider.getNameSpace();
8e1f81f1 526 int x = e.x - leftSpace;
f1fae91f
PT
527 if (LEFT_BUTTON == fDragState) {
528 if (x > 0 && size.x > leftSpace && fDragX != x) {
529 fDragX = x;
530 if (fTimeProvider.getTime0() == fTimeProvider.getTime1()) {
8e1f81f1
PT
531 return;
532 }
f1fae91f 533 long interval = (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX));
8e1f81f1 534 if (interval == Long.MAX_VALUE) {
f1fae91f 535 fTimeProvider.setStartFinishTime(fTime0bak, Long.MAX_VALUE);
8e1f81f1 536 } else {
f1fae91f
PT
537 long time1 = fTime0bak + (long) ((fTime1bak - fTime0bak) * ((double) fDragX0 / fDragX));
538 fTimeProvider.setStartFinishTime(fTime0bak, time1);
8e1f81f1
PT
539 }
540 }
8e1f81f1
PT
541 }
542 }
543
544 @Override
545 public void mouseDoubleClick(MouseEvent e) {
f1fae91f
PT
546 if (e.button == 1 && null != fTimeProvider && fTimeProvider.getTime0() != fTimeProvider.getTime1() && (e.stateMask & SWT.BUTTON_MASK) == 0) {
547 fTimeProvider.resetStartFinishTime();
548 fTimeProvider.notifyStartFinishTime();
549 fTime0bak = fTimeProvider.getTime0();
550 fTime1bak = fTimeProvider.getTime1();
8e1f81f1
PT
551 }
552 }
c1cd9635
MAL
553
554 /**
555 * Update the display to use the updated timestamp format
556 *
557 * @param signal the incoming signal
4b121c48 558 * @since 2.1
c1cd9635
MAL
559 */
560 @TmfSignalHandler
561 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
562 TimeDraw.updateTimeZone();
563 Utils.updateTimeZone();
564 redraw();
565 }
8e1f81f1
PT
566}
567
568abstract class TimeDraw {
f1fae91f
PT
569 protected static final long MICROSEC_IN_NS = 1000;
570 protected static final long MILLISEC_IN_NS = 1000000;
571 protected static final long MILLISEC_IN_US = 1000;
572 protected static final long SEC_IN_NS = 1000000000;
573 protected static final long SEC_IN_MS = 1000;
574 private static final String S = "" ; //$NON-NLS-1$
575 private static final String S0 = "0" ; //$NON-NLS-1$
576 private static final String S00 = "00"; //$NON-NLS-1$
577 protected static final long PAD_1000 = 1000;
578 protected static final SimpleDateFormat SEC_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
579 protected static final SimpleDateFormat SEC_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$
580 protected static final SimpleDateFormat MIN_FORMAT_HEADER = new SimpleDateFormat("yyyy MMM dd"); //$NON-NLS-1$
581 protected static final SimpleDateFormat MIN_FORMAT = new SimpleDateFormat("HH:mm"); //$NON-NLS-1$
582 protected static final SimpleDateFormat HOURS_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
583 protected static final SimpleDateFormat HOURS_FORMAT = new SimpleDateFormat("MMM dd HH:mm"); //$NON-NLS-1$
584 protected static final SimpleDateFormat DAY_FORMAT_HEADER = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
585 protected static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("MMM dd"); //$NON-NLS-1$
586 protected static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyy MMM"); //$NON-NLS-1$
587 protected static final SimpleDateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy"); //$NON-NLS-1$
8e1f81f1 588
c1cd9635
MAL
589 protected static final SimpleDateFormat formatArray[] = {
590 SEC_FORMAT, SEC_FORMAT_HEADER, MIN_FORMAT, MIN_FORMAT_HEADER,
591 HOURS_FORMAT, HOURS_FORMAT_HEADER, DAY_FORMAT, DAY_FORMAT_HEADER, MONTH_FORMAT, YEAR_FORMAT
592 };
593
594 /**
595 * Updates the timezone using the preferences.
596 */
597 public static void updateTimeZone() {
598 final TimeZone timeZone = TmfTimePreferences.getInstance().getTimeZone();
599 for (SimpleDateFormat sdf : formatArray) {
600 sdf.setTimeZone(timeZone);
601 }
602 }
603
8e1f81f1
PT
604 static String sep(long n) {
605 StringBuilder retVal = new StringBuilder();
606 String s = Long.toString(n);
607 for (int i = 0; i < s.length(); i++) {
608 int pos = s.length() - i - 1;
609 retVal.append(s.charAt(i));
610 if (pos % 3 == 0 && pos != 0) {
611 retVal.append(' ');
612 }
613 }
614 return retVal.toString();
615 }
616
617 static String pad(long n) {
618 String s;
619 if (n < 10) {
620 s = S00;
621 } else if (n < 100) {
622 s = S0;
623 } else {
624 s = S;
625 }
626 return s + n;
627 }
628
629 public abstract void draw(GC gc, long time, Rectangle rect);
630
a0a88f65 631 /**
f1fae91f 632 * Override to draw absolute time header. This is for the time information
a0a88f65
AM
633 * not shown in the draw of each tick
634 *
635 * @param gc
636 * Graphics context
f1fae91f
PT
637 * @param nanosec
638 * time in nanosec
a0a88f65
AM
639 * @param absHeaderRect
640 * Header rectangle
641 */
f1fae91f 642 public void drawAbsHeader(GC gc, long nanosec, Rectangle absHeaderRect) {
8e1f81f1 643 }
8e1f81f1
PT
644}
645
646class TimeDrawSec extends TimeDraw {
8e1f81f1 647 @Override
f1fae91f
PT
648 public void draw(GC gc, long nanosec, Rectangle rect) {
649 long sec = nanosec / SEC_IN_NS;
650 Utils.drawText(gc, sep(sec), rect, true);
8e1f81f1
PT
651 }
652}
653
654class TimeDrawMillisec extends TimeDraw {
8e1f81f1 655 @Override
f1fae91f
PT
656 public void draw(GC gc, long nanosec, Rectangle rect) {
657 long millisec = nanosec / MILLISEC_IN_NS;
658 long ms = millisec % PAD_1000;
659 long sec = millisec / SEC_IN_MS;
660 Utils.drawText(gc, sep(sec) + "." + pad(ms), rect, true); //$NON-NLS-1$
8e1f81f1
PT
661 }
662}
663
664class TimeDrawMicrosec extends TimeDraw {
8e1f81f1 665 @Override
f1fae91f
PT
666 public void draw(GC gc, long nanosec, Rectangle rect) {
667 long microsec = nanosec / MICROSEC_IN_NS;
668 long us = microsec % PAD_1000;
669 long millisec = microsec / MILLISEC_IN_US;
670 long ms = millisec % PAD_1000;
671 long sec = millisec / SEC_IN_MS;
672 Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us), rect, true); //$NON-NLS-1$ //$NON-NLS-2$
8e1f81f1
PT
673 }
674}
675
676class TimeDrawNanosec extends TimeDraw {
8e1f81f1 677 @Override
f1fae91f
PT
678 public void draw(GC gc, long nanosec, Rectangle rect) {
679 long ns = nanosec % PAD_1000;
680 long microsec = nanosec / MICROSEC_IN_NS;
681 long us = microsec % PAD_1000;
682 long millisec = microsec / MILLISEC_IN_US;
683 long ms = millisec % PAD_1000;
684 long sec = millisec / SEC_IN_MS;
685 Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
8e1f81f1
PT
686 }
687}
688
689class TimeDrawAbsYear extends TimeDraw {
8e1f81f1 690 @Override
f1fae91f
PT
691 public void draw(GC gc, long nanosec, Rectangle rect) {
692 String stime = YEAR_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
693 Utils.drawText(gc, stime, rect, true);
694 }
8e1f81f1
PT
695}
696
697class TimeDrawAbsMonth extends TimeDraw {
8e1f81f1 698 @Override
f1fae91f
PT
699 public void draw(GC gc, long nanosec, Rectangle rect) {
700 String stime = MONTH_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
701 Utils.drawText(gc, stime, rect, true);
702 }
8e1f81f1
PT
703}
704
705class TimeDrawAbsDay extends TimeDraw {
8e1f81f1 706 @Override
f1fae91f
PT
707 public void draw(GC gc, long nanosec, Rectangle rect) {
708 String stime = DAY_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
709 Utils.drawText(gc, stime, rect, true);
710 }
711
712 @Override
f1fae91f
PT
713 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
714 String header = DAY_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
715 int headerwidth = gc.stringExtent(header).x + 4;
716 if (headerwidth <= rect.width) {
717 rect.x += (rect.width - headerwidth);
718 Utils.drawText(gc, header, rect, true);
719 }
720 }
8e1f81f1
PT
721}
722
723class TimeDrawAbsHrs extends TimeDraw {
8e1f81f1 724 @Override
f1fae91f
PT
725 public void draw(GC gc, long nanosec, Rectangle rect) {
726 String stime = HOURS_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
727 Utils.drawText(gc, stime, rect, true);
728 }
729
730 @Override
f1fae91f
PT
731 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
732 String header = HOURS_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
733 int headerwidth = gc.stringExtent(header).x + 4;
734 if (headerwidth <= rect.width) {
735 rect.x += (rect.width - headerwidth);
736 Utils.drawText(gc, header, rect, true);
737 }
738 }
8e1f81f1
PT
739}
740
741class TimeDrawAbsMin extends TimeDraw {
8e1f81f1 742 @Override
f1fae91f
PT
743 public void draw(GC gc, long nanosec, Rectangle rect) {
744 String stime = MIN_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
745 Utils.drawText(gc, stime, rect, true);
746 }
747
748 @Override
f1fae91f
PT
749 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
750 String header = MIN_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
751 int headerwidth = gc.stringExtent(header).x + 4;
752 if (headerwidth <= rect.width) {
753 rect.x += (rect.width - headerwidth);
754 Utils.drawText(gc, header, rect, true);
755 }
756 }
8e1f81f1
PT
757}
758
759class TimeDrawAbsSec extends TimeDraw {
8e1f81f1 760 @Override
f1fae91f
PT
761 public void draw(GC gc, long nanosec, Rectangle rect) {
762 String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
763 Utils.drawText(gc, stime, rect, true);
764 }
765
766 @Override
f1fae91f
PT
767 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
768 String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
769 int headerwidth = gc.stringExtent(header).x + 4;
770 if (headerwidth <= rect.width) {
771 rect.x += (rect.width - headerwidth);
772 Utils.drawText(gc, header, rect, true);
773 }
774 }
8e1f81f1
PT
775}
776
777class TimeDrawAbsMillisec extends TimeDraw {
8e1f81f1 778 @Override
f1fae91f
PT
779 public void draw(GC gc, long nanosec, Rectangle rect) {
780 String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
781 String ns = Utils.formatNs(nanosec, Resolution.MILLISEC);
8e1f81f1
PT
782
783 Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$
784 }
785
786 @Override
f1fae91f
PT
787 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
788 String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
789 int headerwidth = gc.stringExtent(header).x + 4;
790 if (headerwidth <= rect.width) {
791 rect.x += (rect.width - headerwidth);
792 Utils.drawText(gc, header, rect, true);
793 }
794 }
8e1f81f1
PT
795}
796
797class TimeDrawAbsMicroSec extends TimeDraw {
8e1f81f1 798 @Override
f1fae91f
PT
799 public void draw(GC gc, long nanosec, Rectangle rect) {
800 String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
801 String micr = Utils.formatNs(nanosec, Resolution.MICROSEC);
8e1f81f1
PT
802 Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$
803 }
804
805 @Override
f1fae91f
PT
806 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
807 String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
808 int headerwidth = gc.stringExtent(header).x + 4;
809 if (headerwidth <= rect.width) {
810 rect.x += (rect.width - headerwidth);
811 Utils.drawText(gc, header, rect, true);
812 }
813 }
8e1f81f1
PT
814}
815
816class TimeDrawAbsNanoSec extends TimeDraw {
8e1f81f1 817 @Override
f1fae91f
PT
818 public void draw(GC gc, long nanosec, Rectangle rect) {
819 String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS));
820 String ns = Utils.formatNs(nanosec, Resolution.NANOSEC);
8e1f81f1
PT
821 Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$
822 }
823
824 @Override
f1fae91f
PT
825 public void drawAbsHeader(GC gc, long nanosec, Rectangle rect) {
826 String header = SEC_FORMAT_HEADER.format(new Date(nanosec / MILLISEC_IN_NS));
8e1f81f1
PT
827 int headerwidth = gc.stringExtent(header).x + 4;
828 if (headerwidth <= rect.width) {
829 rect.x += (rect.width - headerwidth);
830 Utils.drawText(gc, header, rect, true);
831 }
832 }
8e1f81f1 833}
026664b7 834
026664b7 835class TimeDrawNumber extends TimeDraw {
026664b7
XR
836 @Override
837 public void draw(GC gc, long time, Rectangle rect) {
838 String stime = NumberFormat.getInstance().format(time);
839 Utils.drawText(gc, stime, rect, true);
840 }
026664b7 841}
This page took 0.077813 seconds and 5 git commands to generate.