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