1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package de.jaret.util.ui.timebars;
21
22 import java.awt.Cursor;
23 import java.awt.Point;
24 import java.awt.Rectangle;
25 import java.awt.event.InputEvent;
26 import java.awt.event.KeyEvent;
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.Vector;
36
37 import de.jaret.util.date.Interval;
38 import de.jaret.util.date.IntervalImpl;
39 import de.jaret.util.date.JaretDate;
40 import de.jaret.util.misc.Pair;
41 import de.jaret.util.ui.timebars.TimeBarViewerInterface.Orientation;
42 import de.jaret.util.ui.timebars.mod.IIntervalModificator;
43 import de.jaret.util.ui.timebars.mod.IntervalModificator;
44 import de.jaret.util.ui.timebars.model.DefaultRowHeader;
45 import de.jaret.util.ui.timebars.model.DefaultTimeBarNode;
46 import de.jaret.util.ui.timebars.model.DefaultTimeBarViewState;
47 import de.jaret.util.ui.timebars.model.FocussedIntervalListener;
48 import de.jaret.util.ui.timebars.model.HierarchicalTimeBarModel;
49 import de.jaret.util.ui.timebars.model.HierarchicalViewState;
50 import de.jaret.util.ui.timebars.model.HierarchicalViewStateImpl;
51 import de.jaret.util.ui.timebars.model.IIntervalRelation;
52 import de.jaret.util.ui.timebars.model.ISelectionRectListener;
53 import de.jaret.util.ui.timebars.model.ITimeBarChangeListener;
54 import de.jaret.util.ui.timebars.model.ITimeBarViewState;
55 import de.jaret.util.ui.timebars.model.ITimeBarViewStateListener;
56 import de.jaret.util.ui.timebars.model.PPSInterval;
57 import de.jaret.util.ui.timebars.model.StdHierarchicalTimeBarModel;
58 import de.jaret.util.ui.timebars.model.TBRect;
59 import de.jaret.util.ui.timebars.model.TimeBarModel;
60 import de.jaret.util.ui.timebars.model.TimeBarModelListener;
61 import de.jaret.util.ui.timebars.model.TimeBarNode;
62 import de.jaret.util.ui.timebars.model.TimeBarRow;
63 import de.jaret.util.ui.timebars.model.TimeBarRowHeader;
64 import de.jaret.util.ui.timebars.model.TimeBarRowListener;
65 import de.jaret.util.ui.timebars.model.TimeBarSelectionListener;
66 import de.jaret.util.ui.timebars.model.TimeBarSelectionModel;
67 import de.jaret.util.ui.timebars.model.TimeBarSelectionModelImpl;
68 import de.jaret.util.ui.timebars.strategy.DefaultIntervalSelectionStrategy;
69 import de.jaret.util.ui.timebars.strategy.DefaultOverlapStrategy;
70 import de.jaret.util.ui.timebars.strategy.IIntervalSelectionStrategy;
71 import de.jaret.util.ui.timebars.strategy.IOverlapStrategy;
72 import de.jaret.util.ui.timebars.strategy.OverlapInfo;
73
74
75
76
77
78
79
80
81
82 public class TimeBarViewerDelegate implements TimeBarModelListener, TimeBarSelectionListener, TimeBarMarkerListener,
83 PropertyChangeListener {
84
85
86 private static final double DEFAULT_PIXEL_PER_SECOND = 2000.0 / (24.0 * 60 * 60);
87
88
89
90
91 private static final int PADDING_PIXEL = 30;
92
93
94
95
96 private static final int MIN_DRAG_HIERARCHY_WIDTH = 2;
97
98
99
100 private static final int MIN_DRAG_HEADER_WIDTH = 2;
101
102
103 private static final int MIN_ROW_HEIGHT = 10;
104
105
106 private static final double MILLISCALING = 1000.0;
107
108
109 private static final int DEFAULT_SEL_DELTA = 2;
110
111
112 private int _selectionDelta = DEFAULT_SEL_DELTA;
113
114
115 protected final TimeBarViewerInterface _tbvi;
116
117
118 protected double _pixelPerSeconds = DEFAULT_PIXEL_PER_SECOND;
119
120
121 protected boolean _variableXScale = false;
122
123
124
125 protected TimeBarNode _xScalePPSIntervalRow;
126
127
128
129
130 protected boolean _milliAccuracy = false;
131
132
133 protected int _xAxisHeight = TimeBarViewerInterface.DEFAULT_XAXISHEIGHT;
134
135
136 protected int _yAxisWidth = TimeBarViewerInterface.DEFAULT_YAXISWIDTH;
137
138
139 protected int _hierarchyWidth = 0;
140
141
142 protected boolean _lineDraggingAllowed = true;
143
144
145 protected Orientation _orientation = Orientation.HORIZONTAL;
146
147
148 protected TimeBarModel _model;
149
150 protected HierarchicalTimeBarModel _hierarchicalModel;
151
152
153 protected ITimeBarViewState _timeBarViewState;
154
155
156 protected HierarchicalViewState _hierarchicalViewState;
157
158
159 protected String _title;
160
161
162 protected int _firstRow = 0;
163
164
165 protected int _firstRowPixelOffset = 0;
166
167
168 protected List<TimeBarRow> _rowList = new ArrayList<TimeBarRow>();
169
170
171
172
173
174 protected boolean _adjustMinMaxDatesByModel = true;
175
176
177 protected boolean _optimizeScrolling = true;
178
179
180 protected JaretDate _startDate = new JaretDate();
181
182
183 protected JaretDate _endDate = new JaretDate();
184
185
186 protected JaretDate _minDate;
187
188
189 protected JaretDate _maxDate;
190
191
192 protected JaretDate _lastStartDate;
193
194
195 protected TimeBarRowFilter _rowFilter;
196
197 protected TimeBarRowSorter _rowSorter;
198
199 protected TimeBarIntervalFilter _intervalFilter;
200
201
202 protected TimeBarSelectionModel _selectionModel = new TimeBarSelectionModelImpl();
203
204
205 protected List<TimeBarMarker> _markers;
206
207
208 protected boolean _drawGrid = true;
209
210
211 protected boolean _drawRowGrid = false;
212
213
214 private boolean _useUniformHeight = false;
215
216
217
218
219 protected int _timeScalePosition = TimeBarViewerInterface.TIMESCALE_POSITION_BOTTOM;
220
221
222 protected Rectangle _diagramRect = new Rectangle(0, 0, 0, 0);
223
224
225 protected Rectangle _xAxisRect = new Rectangle();;
226
227
228 protected Rectangle _yAxisRect = new Rectangle();
229
230
231 protected Rectangle _titleRect = new Rectangle();;
232
233
234 protected Rectangle _hierarchyRect = new Rectangle();;
235
236
237 protected int _offsetTop;
238
239 protected int _offsetLeft;
240
241
242 private boolean _rectSelectionEnabled = true;
243
244
245 protected TimeBarMarker _draggedMarker;
246
247
248 protected Interval _changingInterval;
249
250
251 protected boolean _draggedInterval;
252
253
254 protected boolean _draggedIntervalEdgeLeft;
255
256
257 protected static final int DEFAULT_AUTOSCROLL_DELTA = 10;
258
259 protected int _autoscrollDelta = DEFAULT_AUTOSCROLL_DELTA;
260
261
262 protected boolean _dragAllSelectedIntervals = false;
263
264
265 protected boolean _hierarchyLineDragging = false;
266
267 protected boolean _headerLineDragging = false;
268
269 protected boolean _rowHeightDraggingAllowed = false;
270
271
272 protected TimeBarRow _heightDraggedRow = null;
273
274
275 protected boolean _autoscroll = true;
276
277
278 protected Rectangle _selectionRect = null;
279
280
281 protected Rectangle _lastSelRect;
282
283
284 protected TimeBarRow _highlightedRow;
285
286
287 private String _name;
288
289
290 protected boolean _drawOverlapping = false;
291
292
293 protected int _keyboardChangeDelta = 60 * 60;
294
295
296 protected boolean _scrollOnFocus = true;
297
298
299
300
301 protected Interval _focussedInterval;
302
303
304
305
306 protected TimeBarRow _focussedRow;
307
308
309 private TimeBarRowListener _repaintingRowListener;
310
311
312 private int _autoScaleRows = -1;
313
314
315 protected List<FocussedIntervalListener> _focussedIntervalListeners;
316
317
318 protected List<ITimeBarChangeListener> _timeBarChangeListeners = new Vector<ITimeBarChangeListener>();
319
320
321 protected List<ISelectionRectListener> _selectionRectListeners = new Vector<ISelectionRectListener>();
322
323
324 protected List<IntervalModificator> _intervalModificators = new ArrayList<IntervalModificator>(2);
325
326
327
328
329
330 protected boolean _strictClipTimeCheck = false;
331
332
333 protected int _scrollLookBackMinutes = 120;
334
335 protected int _scrollLookForwardMinutes = 120;
336
337
338 protected double _timeFactor = 1.0;
339
340
341 protected IOverlapStrategy _overlapStrategy = new DefaultOverlapStrategy(this);
342
343
344 protected boolean _hideRoot = false;
345
346
347 protected IIntervalSelectionStrategy _intervalSelectionStrategy = new DefaultIntervalSelectionStrategy();
348
349
350 protected boolean _regionRectEnabled = false;
351
352
353 protected TBRect _regionSelection = null;
354
355 protected TBRect _lastRegionSelection = null;
356
357 protected JaretDate _regionStartDate;
358
359 protected TimeBarRow _regionStartRow;
360
361
362
363
364
365
366 public TimeBarViewerDelegate(TimeBarViewerInterface tbvi) {
367 _tbvi = tbvi;
368
369 _selectionModel.addTimeBarSelectionListener(this);
370
371
372 _timeBarViewState = new DefaultTimeBarViewState(this);
373 _timeBarViewState.setDefaultRowHeight(TimeBarViewerInterface.DEFAULT_ROWHEIGHT);
374
375
376 _timeBarViewState.addTimeBarViewStateListener(new ITimeBarViewStateListener() {
377 public void rowHeightChanged(TimeBarRow row, int newHeight) {
378 if (_tbvi != null) {
379 updateRowScrollBar();
380 _tbvi.repaint();
381 }
382 }
383
384 public void viewStateChanged() {
385 if (_tbvi != null) {
386 updateRowScrollBar();
387 _tbvi.repaint();
388 }
389 }
390 });
391
392 }
393
394
395
396
397
398 public void dispose() {
399 if (_model != null) {
400 _model.remTimeBarModelListener(this);
401 }
402 if (_selectionModel != null) {
403 _selectionModel.remTimeBarSelectionListener(this);
404 }
405 if (_markers != null) {
406 for (TimeBarMarker marker : _markers) {
407 marker.remTimeBarMarkerListener(this);
408 }
409 }
410 if (_rowFilter != null) {
411 _rowFilter.removePropertyChangeListener(this);
412 }
413 if (_rowSorter != null) {
414 _rowSorter.removePropertyChangeListener(this);
415 }
416 if (_focussedIntervalListeners != null) {
417 _focussedIntervalListeners.clear();
418 }
419 if (_selectionRectListeners != null) {
420 _selectionRectListeners.clear();
421 }
422 if (_timeBarChangeListeners != null) {
423 _timeBarChangeListeners.clear();
424 }
425 }
426
427
428
429
430
431
432
433 public boolean isDisplayed(JaretDate date) {
434 return _startDate.compareTo(date) <= 0 && (_endDate == null || _endDate.compareTo(date) >= 0);
435 }
436
437
438
439
440
441
442 public void setRowFilter(TimeBarRowFilter rowFilter) {
443 if ((_rowFilter == null && rowFilter != null) || (_rowFilter != null && !_rowFilter.equals(rowFilter))) {
444 TimeBarRowFilter oldFilter = _rowFilter;
445 if (oldFilter != null) {
446 oldFilter.removePropertyChangeListener(this);
447 }
448 _rowFilter = rowFilter;
449 if (_rowFilter != null) {
450 _rowFilter.addPropertyChangeListener(this);
451 }
452 updateRowList();
453 if (_tbvi != null) {
454 _tbvi.repaint();
455 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_ROWFILTER, oldFilter, rowFilter);
456 }
457 }
458 }
459
460
461
462
463 public TimeBarRowFilter getRowFilter() {
464 return _rowFilter;
465 }
466
467
468
469
470
471
472
473 public boolean isFiltered(TimeBarRow row) {
474 if (_rowFilter == null) {
475 return false;
476 }
477 return (!_rowFilter.isInResult(row));
478 }
479
480
481
482
483
484
485 public void setRowSorter(TimeBarRowSorter rowSorter) {
486 if ((_rowSorter == null && rowSorter != null) || (_rowSorter != null && !_rowSorter.equals(rowSorter))) {
487 TimeBarRowSorter oldSorter = _rowSorter;
488 if (oldSorter != null) {
489 oldSorter.removePropertyChangeListener(this);
490 }
491 _rowSorter = rowSorter;
492 if (_rowSorter != null) {
493 _rowSorter.addPropertyChangeListener(this);
494 }
495 updateRowList();
496 if (_tbvi != null) {
497 _tbvi.repaint();
498 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_ROWSORTER, oldSorter, rowSorter);
499 }
500 }
501 }
502
503
504
505
506 public TimeBarRowSorter getRowSorter() {
507 return _rowSorter;
508 }
509
510
511
512
513
514
515
516 public void setIntervalFilter(TimeBarIntervalFilter intervalFilter) {
517 if ((_intervalFilter == null && intervalFilter != null)
518 || (_intervalFilter != null && !_intervalFilter.equals(intervalFilter))) {
519 TimeBarIntervalFilter oldFilter = _intervalFilter;
520 if (oldFilter != null) {
521 oldFilter.removePropertyChangeListener(this);
522 }
523 _intervalFilter = intervalFilter;
524 if (_intervalFilter != null) {
525 _intervalFilter.addPropertyChangeListener(this);
526
527 _overlapStrategy.clearCachedData();
528 }
529 _tbvi.repaint();
530 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_INTERVALFILTER, oldFilter, intervalFilter);
531 }
532 }
533
534
535
536
537 public TimeBarIntervalFilter getIntervalFilter() {
538 return _intervalFilter;
539 }
540
541
542
543
544
545
546
547 public boolean isFiltered(Interval interval) {
548 if (_intervalFilter == null) {
549 return false;
550 }
551 return !_intervalFilter.isInResult(interval);
552 }
553
554
555
556
557
558 public void updateRowList() {
559 if (_model != null) {
560 int oldRowCount = _rowList != null ? _rowList.size() : 0;
561 List<TimeBarRow> newRowList = new ArrayList<TimeBarRow>();
562
563 for (int r = 0; r < _model.getRowCount(); r++) {
564 if (_rowFilter != null) {
565
566 if (_rowFilter.isInResult(_model.getRow(r))) {
567 newRowList.add(_model.getRow(r));
568 }
569 } else {
570 newRowList.add(_model.getRow(r));
571 }
572 }
573
574 if (_rowSorter != null) {
575 Collections.sort(newRowList, _rowSorter);
576 }
577
578
579 _rowList = newRowList;
580
581
582 if (_firstRow >= newRowList.size())
583 setLastRow(Math.max(0, newRowList.size() - 1));
584
585 if (getRowCount() != oldRowCount && _tbvi != null) {
586 updateRowScrollBar();
587 }
588 }
589 }
590
591
592
593
594
595
596
597 public TimeBarRow getRow(int idx) {
598 return _rowList.get(idx);
599 }
600
601
602
603
604
605
606
607 public int getRowIndex(TimeBarRow row) {
608 return _rowList.indexOf(row);
609 }
610
611
612
613
614
615
616 public int getRowCount() {
617 return _rowList != null ? _rowList.size() : 0;
618 }
619
620
621
622
623
624
625
626 public long getTotalSeconds() {
627 if (getMaxDate() == null || getMinDate() == null) {
628 return 0;
629 }
630 return getMaxDate().diffSecondsL(getMinDate());
631 }
632
633
634
635
636
637
638 public long getTotalMilliSeconds() {
639 return getMaxDate().diffMilliSeconds(getMinDate());
640 }
641
642
643
644
645
646
647 public int getSecondsDisplayed() {
648 if (_orientation == Orientation.HORIZONTAL) {
649 if (!_variableXScale) {
650 return (int) ((double) (_diagramRect.width) / _pixelPerSeconds);
651 } else {
652 int endx = _diagramRect.width;
653 JaretDate endDate = dateForCoord(endx);
654 return endDate.diffSeconds(_startDate);
655 }
656 } else {
657 if (!_variableXScale) {
658 return (int) ((double) (_diagramRect.height) / _pixelPerSeconds);
659 } else {
660 int endy = _diagramRect.height;
661 JaretDate endDate = dateForCoord(endy);
662 return endDate.diffSeconds(_startDate);
663 }
664 }
665 }
666
667
668
669
670
671
672 public long getMilliSecondsDisplayed() {
673 if (_orientation == Orientation.HORIZONTAL) {
674 if (!_variableXScale) {
675 return (int) ((double) _diagramRect.width / getPixelPerMilliSecond());
676 } else {
677 int endx = _diagramRect.width;
678 JaretDate endDate = dateForX(endx);
679 return endDate.diffMilliSeconds(_startDate);
680 }
681 } else {
682 if (!_variableXScale) {
683 return (int) ((double) _diagramRect.height / getPixelPerMilliSecond());
684 } else {
685 int endx = _diagramRect.height;
686 JaretDate endDate = dateForX(endx);
687 return endDate.diffMilliSeconds(_startDate);
688 }
689 }
690 }
691
692
693
694
695 public TimeBarSelectionModel getSelectionModel() {
696 return _selectionModel;
697 }
698
699
700
701
702 public void setSelectionModel(TimeBarSelectionModel selectionModel) {
703 if (_selectionModel != null) {
704 _selectionModel.remTimeBarSelectionListener(this);
705 }
706 _selectionModel = selectionModel;
707 _selectionModel.addTimeBarSelectionListener(this);
708 _tbvi.repaint();
709 }
710
711
712
713
714 public boolean getAdjustMinMaxDatesByModel() {
715 return _adjustMinMaxDatesByModel;
716 }
717
718
719
720
721 public void setAdjustMinMaxDatesByModel(boolean adjustMinMaxDatesByModel) {
722 _adjustMinMaxDatesByModel = adjustMinMaxDatesByModel;
723 }
724
725
726
727
728 public JaretDate getMaxDate() {
729 return _maxDate;
730 }
731
732
733
734
735
736
737 public void setMaxDate(JaretDate maxDate) {
738
739
740 long milliseconds = (int) ((double) PADDING_PIXEL / (_pixelPerSeconds * MILLISCALING));
741 JaretDate oldVal = _maxDate;
742 _maxDate = maxDate.copy();
743 _maxDate.advanceMillis(milliseconds);
744 if (oldVal == null || !oldVal.equals(maxDate)) {
745 updateTimeScrollBar();
746 if (_tbvi != null) {
747 _tbvi.repaint();
748 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_MAXDATE, oldVal, maxDate);
749 }
750 }
751 }
752
753
754
755
756 public JaretDate getMinDate() {
757 return _minDate;
758 }
759
760
761
762
763 public void setMinDate(JaretDate minDate) {
764
765
766 long milliseconds = (int) ((double) PADDING_PIXEL / (_pixelPerSeconds * MILLISCALING));
767 JaretDate oldVal = _minDate;
768 _minDate = minDate.copy();
769 _minDate.advanceMillis(-milliseconds);
770 if (oldVal == null || !oldVal.equals(minDate)) {
771 updateTimeScrollBar();
772 if (_tbvi != null) {
773 _tbvi.repaint();
774 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_MINDATE, oldVal, minDate);
775 }
776 }
777 }
778
779
780
781
782
783
784 public synchronized JaretDate getStartDate() {
785 return _startDate;
786 }
787
788
789
790
791
792
793 public synchronized void setStartDate(JaretDate startDate) {
794 _lastStartDate = _startDate;
795 JaretDate oldVal = _startDate;
796 _startDate = startDate.copy();
797
798
799
800 if ((oldVal == null || !oldVal.equals(_startDate)) && _tbvi != null) {
801 if (_diagramRect != null) {
802 _endDate = dateForCoord(_diagramRect.x + _diagramRect.width);
803 }
804 updateTimeScrollBar();
805 _tbvi.repaint();
806 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_STARTDATE, oldVal, _startDate);
807 }
808 }
809
810
811
812
813
814
815 protected void scrollTo(JaretDate startDate) {
816 if (!_optimizeScrolling || _tbvi == null) {
817 setStartDate(startDate);
818 } else {
819 try {
820 _lastStartDate = _startDate;
821 JaretDate oldVal = _startDate;
822 int oldx = xForDateAbs(_startDate);
823
824 int newx = xForDateAbs(startDate);
825
826
827 JaretDate newStartDate = dateForCoordAbs(newx);
828
829 int diff = newx - oldx;
830 int comp;
831 if (_orientation.equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
832 comp = _tbvi.getWidth();
833 } else {
834 comp = _tbvi.getHeight();
835 }
836 if (Math.abs(diff) > comp / 2) {
837 setStartDate(startDate);
838 return;
839 }
840
841
842
843 if (_orientation == Orientation.HORIZONTAL) {
844 _tbvi.doScrollHorizontal(diff);
845 } else {
846 _tbvi.doScrollVertical(diff);
847 }
848 _startDate = newStartDate;
849
850
851
852 if ((oldVal == null || !oldVal.equals(_startDate)) && _tbvi != null) {
853 if (_diagramRect != null) {
854 _endDate = dateForCoord(_diagramRect.x + _diagramRect.width);
855 }
856 updateTimeScrollBar();
857 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_STARTDATE, oldVal, _startDate);
858 }
859 } catch (Exception e) {
860 e.printStackTrace();
861 }
862 }
863 }
864
865
866
867
868
869
870 public TimeBarModel getModel() {
871 return _model;
872 }
873
874
875
876
877
878
879 public void setModel(TimeBarModel model) {
880 if (_model != null) {
881 _model.remTimeBarModelListener(this);
882 }
883 _model = model;
884 if (model != null) {
885
886 if (_adjustMinMaxDatesByModel) {
887
888 _minDate = _model.getMinDate();
889 _maxDate = _model.getMaxDate();
890
891 setMinDate(_model.getMinDate());
892 setMaxDate(_model.getMaxDate());
893
894 setStartDate(_model.getMinDate().copy());
895 setMinDate(_model.getMinDate());
896 setMaxDate(_model.getMaxDate());
897 } else {
898 _minDate = new JaretDate();
899 _maxDate = new JaretDate();
900 setStartDate(new JaretDate());
901 }
902
903 if (_hierarchicalModel == null) {
904
905 _hierarchicalViewState = null;
906 }
907
908 _model.addTimeBarModelListener(this);
909 } else {
910
911
912 _hierarchicalViewState = null;
913 }
914 updateRowList();
915 if (_tbvi != null) {
916 updateScrollBars();
917 _tbvi.repaint();
918 }
919 }
920
921
922
923
924
925
926 public void setModel(HierarchicalTimeBarModel hModel) {
927 _hierarchicalViewState = new HierarchicalViewStateImpl();
928 _hierarchicalModel = hModel;
929 TimeBarModel model = null;
930 if (hModel != null) {
931 model = new StdHierarchicalTimeBarModel(hModel, _hierarchicalViewState);
932 }
933 setModel(model);
934 }
935
936
937
938
939
940
941 public HierarchicalTimeBarModel getHierarchicalModel() {
942 return _hierarchicalModel;
943 }
944
945
946
947
948 private void checkAndAdjustMinMax() {
949 if (_adjustMinMaxDatesByModel) {
950 setMinDate(_model.getMinDate().copy());
951 setMaxDate(_model.getMaxDate().copy());
952 }
953 }
954
955
956
957
958
959
960
961
962 public void setPixelPerSecond(double pixelPerSecond) {
963 setPixelPerSecond(pixelPerSecond, true);
964 }
965
966
967
968
969
970
971
972 protected void setPixelPerSecond(double pixelPerSecond, boolean repaint) {
973 if (pixelPerSecond != _pixelPerSeconds) {
974
975
976 double oldValue = _pixelPerSeconds;
977 _pixelPerSeconds = pixelPerSecond;
978 if (_variableXScale) {
979 updateTimeScaleBreaks();
980 }
981 if (_tbvi != null) {
982 updateTimeScrollBar();
983 if (repaint) {
984 _tbvi.repaint();
985 }
986 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_PIXELPERSECOND, oldValue, pixelPerSecond);
987 }
988 }
989 }
990
991
992
993
994 private void updateTimeScaleBreaks() {
995 for (Interval ppsInterval : getPpsRow().getIntervals()) {
996 PPSInterval pi = (PPSInterval) ppsInterval;
997 if (pi.isBreak()) {
998 long millis = pi.getEnd().diffMilliSeconds(pi.getBegin());
999 double width = (double) pi.getBreakDisplayWidth();
1000 double targetPPS = width / ((double) millis / MILLISCALING);
1001 pi.setPps(targetPPS);
1002 }
1003 }
1004 }
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014 public void setSecondsDisplayed(int seconds, boolean center) {
1015 if (_orientation.equals(Orientation.HORIZONTAL)) {
1016 if (_diagramRect != null && _diagramRect.width > 1) {
1017 double pps = (double) _diagramRect.width / (double) seconds;
1018 if (!center) {
1019 setPixelPerSecond(pps);
1020 } else {
1021 int oldSeconds = getSecondsDisplayed();
1022 setPixelPerSecond(pps, false);
1023 int newSeconds = getSecondsDisplayed();
1024 setStartDate(getStartDate().copy().advanceSeconds((oldSeconds - newSeconds) / 2.0));
1025 }
1026 } else {
1027
1028 setInitialDisplayRange(getStartDate(), seconds);
1029 }
1030 } else {
1031 if (_diagramRect != null && _diagramRect.height > 1) {
1032 double pps = (double) _diagramRect.height / (double) seconds;
1033 if (!center) {
1034 setPixelPerSecond(pps);
1035 } else {
1036 int oldSeconds = getSecondsDisplayed();
1037 setPixelPerSecond(pps, false);
1038 int newSeconds = getSecondsDisplayed();
1039 setStartDate(getStartDate().copy().advanceSeconds((oldSeconds - newSeconds) / 2.0));
1040 }
1041 } else {
1042
1043 setInitialDisplayRange(getStartDate(), seconds);
1044 }
1045 }
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 public void setSecondsDisplayed(int seconds, JaretDate centerDate) {
1057 if (!isDisplayed(centerDate)) {
1058 setSecondsDisplayed(seconds, true);
1059 } else {
1060 if (_orientation.equals(Orientation.HORIZONTAL)) {
1061 if (_diagramRect != null && _diagramRect.width > 1) {
1062 double pps = (double) _diagramRect.width / (double) seconds;
1063 if (centerDate == null) {
1064 setPixelPerSecond(pps);
1065 } else {
1066
1067 boolean optimizeScrolling = _optimizeScrolling;
1068 _optimizeScrolling = false;
1069
1070 int oldx = xForDate(centerDate);
1071
1072 setPixelPerSecond(pps, false);
1073 JaretDate dateAtOldPos = dateForCoord(oldx);
1074 long diffmsec = centerDate.diffMilliSeconds(dateAtOldPos);
1075
1076 setStartDate(getStartDate().copy().advanceMillis(diffmsec));
1077 _optimizeScrolling = optimizeScrolling;
1078 }
1079 } else {
1080
1081 setInitialDisplayRange(getStartDate(), seconds);
1082 }
1083 } else {
1084 if (_diagramRect != null && _diagramRect.height > 1) {
1085 double pps = (double) _diagramRect.height / (double) seconds;
1086 if (centerDate == null) {
1087 setPixelPerSecond(pps);
1088 } else {
1089
1090 boolean optimizeScrolling = _optimizeScrolling;
1091 _optimizeScrolling = false;
1092
1093 int oldx = xForDate(centerDate);
1094
1095 setPixelPerSecond(pps, false);
1096 JaretDate dateAtOldPos = dateForCoord(oldx);
1097 long diffmsec = centerDate.diffMilliSeconds(dateAtOldPos);
1098
1099 setStartDate(getStartDate().copy().advanceMillis(diffmsec));
1100 _optimizeScrolling = optimizeScrolling;
1101 }
1102 } else {
1103
1104 setInitialDisplayRange(getStartDate(), seconds);
1105 }
1106 }
1107 }
1108 }
1109
1110
1111
1112
1113
1114
1115 public double getPixelPerSecond() {
1116 return _pixelPerSeconds;
1117 }
1118
1119
1120
1121
1122
1123
1124 protected double getPixelPerMilliSecond() {
1125 return _pixelPerSeconds / MILLISCALING;
1126 }
1127
1128 protected JaretDate _initialStartDate;
1129 protected int _initialSecondsDisplayed;
1130
1131
1132
1133
1134
1135
1136
1137 public void setInitialDisplayRange(JaretDate startDate, int secondsDisplayed) {
1138 _initialStartDate = startDate;
1139 _initialSecondsDisplayed = secondsDisplayed;
1140 }
1141
1142
1143
1144
1145
1146
1147
1148
1149 public void setRowHeight(int rowHeight) {
1150 if (rowHeight != _timeBarViewState.getDefaultRowHeight()) {
1151 int oldVal = _timeBarViewState.getDefaultRowHeight();
1152 _timeBarViewState.setDefaultRowHeight(rowHeight);
1153 if (_tbvi != null) {
1154 _tbvi.repaint();
1155 updateRowScrollBar();
1156 if (_tbvi != null) {
1157 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_ROWHEIGHT, oldVal, rowHeight);
1158 }
1159 }
1160 }
1161 }
1162
1163
1164
1165
1166
1167
1168
1169 public int getRowHeight() {
1170 return _timeBarViewState.getDefaultRowHeight();
1171 }
1172
1173
1174
1175
1176
1177
1178 public JaretDate getEndDate() {
1179 return _endDate;
1180 }
1181
1182
1183
1184
1185
1186
1187 public void addMarker(TimeBarMarker marker) {
1188 if (_markers == null) {
1189 _markers = new ArrayList<TimeBarMarker>();
1190 }
1191 _markers.add(marker);
1192 marker.addTimeBarMarkerListener(this);
1193 if (isDisplayed(marker.getDate())) {
1194
1195 _tbvi.repaint();
1196 }
1197 if (_minDate != null && marker.getDate().compareTo(_minDate) < 0) {
1198 setMinDate(marker.getDate().copy());
1199 } else if (_maxDate != null && marker.getDate().compareTo(_maxDate) > 0) {
1200 setMaxDate(marker.getDate().copy());
1201 }
1202 }
1203
1204
1205
1206
1207
1208
1209 public void remMarker(TimeBarMarker marker) {
1210 if (_markers != null) {
1211 _markers.remove(marker);
1212 marker.remTimeBarMarkerListener(this);
1213 if (isDisplayed(marker.getDate())) {
1214
1215 _tbvi.repaint();
1216 }
1217 }
1218 }
1219
1220
1221
1222
1223
1224
1225
1226
1227 public TimeBarMarker getMarkerForXY(int x, int y) {
1228 if (_orientation == Orientation.HORIZONTAL) {
1229 return getMarkerForCoord(x);
1230 } else {
1231 return getMarkerForCoord(y);
1232 }
1233 }
1234
1235
1236
1237
1238
1239
1240
1241 protected TimeBarMarker getMarkerForCoord(int coord) {
1242 TimeBarMarker result = null;
1243 if (_markers != null) {
1244 for (int i = 0; i < _markers.size(); i++) {
1245 TimeBarMarker marker = (TimeBarMarker) _markers.get(i);
1246 int mx = xForDate(marker.getDate());
1247 if (coord - _selectionDelta < mx && coord + _selectionDelta > mx) {
1248 result = marker;
1249 break;
1250 }
1251 }
1252 }
1253 return result;
1254 }
1255
1256
1257
1258
1259
1260
1261 public List<TimeBarMarker> getMarkers() {
1262 return _markers;
1263 }
1264
1265
1266
1267
1268
1269
1270 public void addMarkers(List<TimeBarMarker> markers) {
1271 if (markers != null) {
1272 for (TimeBarMarker marker : markers) {
1273 addMarker(marker);
1274 }
1275 }
1276 }
1277
1278
1279
1280
1281
1282 public void updateScrollBars() {
1283 if (_model != null && _model.getRowCount() != 0) {
1284 updateTimeScrollBar();
1285 updateRowScrollBar();
1286 }
1287 }
1288
1289
1290
1291
1292 private void updateTimeScrollBar() {
1293 if (_tbvi != null && _model != null) {
1294 if (isMilliAccuracy()) {
1295 long milliSecondsDisplayed = getMilliSecondsDisplayed();
1296 long totalMilliSeconds = getTotalMilliSeconds();
1297 long pos = _startDate.diffMilliSeconds(_minDate);
1298
1299
1300 if (totalMilliSeconds - pos < milliSecondsDisplayed) {
1301 milliSecondsDisplayed = totalMilliSeconds - pos;
1302 }
1303
1304
1305
1306 int addWidth = _yAxisWidth + _hierarchyWidth;
1307 long addMillis;
1308 if (_orientation.equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
1309 addMillis = dateForCoord(_diagramRect.x + _diagramRect.width).diffMilliSeconds(
1310 dateForCoord(_diagramRect.x + _diagramRect.width - addWidth));
1311 } else {
1312 addMillis = dateForCoord(_diagramRect.y + _diagramRect.height).diffMilliSeconds(
1313 dateForCoord(_diagramRect.y + _diagramRect.height - addWidth));
1314 }
1315
1316 updateTimeScrollBar((int) totalMilliSeconds, (int) pos, (int) (milliSecondsDisplayed + addMillis));
1317 } else {
1318
1319
1320 long secondsDisplayed = getSecondsDisplayed();
1321 long totalSeconds = getTotalSeconds();
1322 long pos = _startDate.diffSecondsL(_minDate);
1323
1324
1325 if (totalSeconds - pos < secondsDisplayed) {
1326 secondsDisplayed = totalSeconds - pos;
1327 }
1328
1329
1330
1331 int addWidth = _yAxisWidth + _hierarchyWidth;
1332 int addSeconds = 0;
1333 if (_variableXScale) {
1334 if (_orientation.equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
1335 addSeconds = dateForCoord(_diagramRect.x + _diagramRect.width).diffSeconds(
1336 dateForCoord(_diagramRect.x + _diagramRect.width - addWidth));
1337 } else {
1338 addSeconds = dateForCoord(_diagramRect.y + _diagramRect.height).diffSeconds(
1339 dateForCoord(_diagramRect.y + _diagramRect.height - addWidth));
1340 }
1341 }
1342 int tot = 0;
1343 int p = 0;
1344 int displayed = 0;
1345
1346 if (totalSeconds < Integer.MAX_VALUE) {
1347 tot = (int) totalSeconds;
1348 p = (int) pos;
1349 displayed = (int) (secondsDisplayed + addSeconds);
1350 _timeFactor = 1.0;
1351 } else {
1352
1353 _timeFactor = (double) Integer.MAX_VALUE / (double) totalSeconds;
1354 tot = (int) ((double) totalSeconds * _timeFactor);
1355 p = (int) ((double) pos * _timeFactor);
1356 displayed = (int) ((double) (secondsDisplayed + addSeconds) * _timeFactor);
1357 }
1358
1359 updateTimeScrollBar(tot, p, displayed);
1360
1361 }
1362 }
1363 }
1364
1365
1366
1367
1368
1369
1370
1371
1372 private void updateTimeScrollBar(int max, int pos, int secondsDisplayed) {
1373 if (_orientation == Orientation.HORIZONTAL) {
1374 _tbvi.updateXScrollBar(max, pos, secondsDisplayed);
1375 } else if (_orientation == Orientation.VERTICAL) {
1376 _tbvi.updateYScrollBar(max, pos, secondsDisplayed);
1377 }
1378 }
1379
1380
1381
1382
1383
1384
1385
1386 public void handleHorizontalScroll(int value, boolean redirect) {
1387 if (!redirect || _orientation == Orientation.HORIZONTAL) {
1388 if (getMinDate() == null) {
1389 return;
1390 }
1391 JaretDate date = getMinDate().copy();
1392 if (isMilliAccuracy()) {
1393 date.advanceMillis((long) value);
1394 } else {
1395 date.advanceSeconds(value / _timeFactor);
1396 }
1397 scrollTo(date);
1398 } else if (_orientation == Orientation.VERTICAL) {
1399 handleVerticalScroll(value, false);
1400 } else {
1401 throw new RuntimeException("illegal");
1402 }
1403 }
1404
1405
1406
1407
1408
1409 private void updateRowScrollBar() {
1410 int first = getFirstRow();
1411 int firstRowAbs = (first >= _rowList.size()) ? 0: getAbsPosForRow(first);
1412 updateRowScrollBar(getTotalHeight(), firstRowAbs + _firstRowPixelOffset, _diagramRect.height);
1413
1414
1415
1416 }
1417
1418
1419
1420
1421
1422
1423
1424
1425 private void updateRowScrollBar(int max, int pos, int thumbSize) {
1426 if (_orientation == Orientation.HORIZONTAL) {
1427 _tbvi.updateYScrollBar(max, pos, thumbSize);
1428 } else if (_orientation == Orientation.VERTICAL) {
1429 _tbvi.updateXScrollBar(max, pos, thumbSize);
1430 }
1431 }
1432
1433
1434
1435
1436
1437
1438
1439 public int getRowIdxForAbsoluteOffset(int value) {
1440 if (!_timeBarViewState.getUseVariableRowHeights()) {
1441 int row = value / _timeBarViewState.getDefaultRowHeight();
1442 return row;
1443 } else {
1444 int y = 0;
1445 TimeBarRow row = getRow(0);
1446 int height = _timeBarViewState.getRowHeight(row);
1447 for (int i = 0; i < _rowList.size(); i++) {
1448 if (y <= value && value <= y + height) {
1449 return i;
1450 }
1451 y += height;
1452 if (i + 1 > _rowList.size() - 1) {
1453 break;
1454 }
1455 row = getRow(i + 1);
1456 height = _timeBarViewState.getRowHeight(row);
1457 }
1458
1459 throw new RuntimeException("could not find row idx for offset");
1460 }
1461 }
1462
1463
1464
1465
1466
1467
1468
1469
1470 public int getRowPixOffsetForAbsoluteOffset(int rowIdx, int value) {
1471 if (!_timeBarViewState.getUseVariableRowHeights()) {
1472 int off = value % _timeBarViewState.getDefaultRowHeight();
1473 return off;
1474 } else {
1475 int y = getAbsPosForRow(rowIdx);
1476 return value - y;
1477 }
1478 }
1479
1480
1481
1482
1483
1484
1485 public int getTotalHeight() {
1486 if (!_timeBarViewState.getUseVariableRowHeights()) {
1487 return getRowCount() * _timeBarViewState.getDefaultRowHeight();
1488 } else {
1489 int h = 0;
1490 for (int i = 0; i < _rowList.size(); i++) {
1491 TimeBarRow row = getRow(i);
1492 h += _timeBarViewState.getRowHeight(row);
1493 }
1494 return h;
1495 }
1496 }
1497
1498
1499
1500
1501
1502
1503
1504 public int getAbsPosForRow(int rowIdx) {
1505 if (!_timeBarViewState.getUseVariableRowHeights()) {
1506 return rowIdx * _timeBarViewState.getDefaultRowHeight();
1507 } else {
1508 int h = 0;
1509 for (int i = 0; i < rowIdx; i++) {
1510 TimeBarRow row = getRow(i);
1511 h += _timeBarViewState.getRowHeight(row);
1512 }
1513 return h;
1514 }
1515 }
1516
1517
1518
1519
1520
1521
1522
1523 public void handleVerticalScroll(int value, boolean redirect) {
1524 if (!redirect || _orientation == Orientation.HORIZONTAL) {
1525 int row = getRowIdxForAbsoluteOffset(value);
1526 int offset = getRowPixOffsetForAbsoluteOffset(row, value);
1527 setFirstRow(row, offset);
1528 } else if (_orientation == Orientation.VERTICAL) {
1529 handleHorizontalScroll(value, false);
1530 } else {
1531 throw new RuntimeException("illegal");
1532 }
1533 }
1534
1535
1536
1537
1538
1539
1540
1541
1542 public JaretDate dateForXY(int x, int y) {
1543 if (_startDate == null) {
1544 return null;
1545 }
1546 int coord;
1547 if (_orientation == Orientation.HORIZONTAL) {
1548 coord = x;
1549 } else {
1550 coord = y;
1551 }
1552 if (!_variableXScale) {
1553 return dateForCoordPlain(coord);
1554 } else {
1555 return dateForCoordVariable(coord);
1556 }
1557
1558 }
1559
1560
1561
1562
1563
1564
1565
1566
1567 public JaretDate dateForX(int x) {
1568 if (_startDate == null) {
1569 return null;
1570 }
1571 if (!_variableXScale) {
1572 return dateForCoordPlain(x);
1573 } else {
1574 return dateForCoordVariable(x);
1575 }
1576 }
1577
1578
1579
1580
1581
1582
1583
1584 public JaretDate dateForCoord(int coord) {
1585 if (_startDate == null) {
1586 return null;
1587 }
1588 if (!_variableXScale) {
1589 return dateForCoordPlain(coord);
1590 } else {
1591 return dateForCoordVariable(coord);
1592 }
1593 }
1594
1595
1596
1597
1598
1599
1600
1601
1602 public JaretDate dateForCoord(int x, int y) {
1603 if (_orientation == Orientation.HORIZONTAL) {
1604 return dateForCoord(x);
1605 } else {
1606 return dateForCoord(y);
1607 }
1608 }
1609
1610
1611
1612
1613
1614
1615
1616 private JaretDate dateForCoordPlain(int coord) {
1617 long pixDif = coord - (_yAxisWidth + _hierarchyWidth);
1618 long diffMilliSec = (long) ((double) pixDif / _pixelPerSeconds * MILLISCALING);
1619 JaretDate date = new JaretDate(_startDate);
1620 date.advanceMillis(diffMilliSec);
1621 return date;
1622 }
1623
1624
1625
1626
1627
1628
1629
1630 public JaretDate dateForCoordAbs(int coord) {
1631 if (!_variableXScale) {
1632 return dateForCoordAbsPlain(coord);
1633 } else {
1634 return dateForCoordAbsVariable(coord);
1635 }
1636 }
1637
1638
1639
1640
1641
1642
1643
1644 private JaretDate dateForCoordAbsPlain(int coord) {
1645 long pixDif = coord - (_yAxisWidth + _hierarchyWidth);
1646 JaretDate date = new JaretDate(_minDate);
1647 if (_milliAccuracy) {
1648 long diffMilliSec = (long) ((double) pixDif / _pixelPerSeconds * MILLISCALING);
1649 date.advanceMillis(diffMilliSec);
1650 } else {
1651 long diffSec = (long) ((double) pixDif / _pixelPerSeconds);
1652 date.advanceSeconds(diffSec);
1653 }
1654 return date;
1655 }
1656
1657
1658
1659
1660
1661
1662
1663 private JaretDate dateForCoordAbsVariable(int coord) {
1664 int pixDif = coord - (_yAxisWidth + _hierarchyWidth);
1665
1666
1667 int pixelToGo = pixDif;
1668 if (pixDif <= 0) {
1669
1670 return dateForCoordPlain(coord);
1671 }
1672 long milliSeconds = 0;
1673 JaretDate d = _minDate.copy();
1674
1675 while (pixelToGo > 0) {
1676 PPSInterval interval = getPPSInterval(d);
1677
1678 double pps = 0;
1679 JaretDate endPPS;
1680 boolean noFollowingPPSInterval = false;
1681 if (interval == null) {
1682
1683 pps = _pixelPerSeconds;
1684 Interval i = nextPPSInterval(d);
1685 if (i != null) {
1686 endPPS = i.getBegin().copy();
1687 } else {
1688 noFollowingPPSInterval = true;
1689 endPPS = getMaxDate().copy();
1690 }
1691 } else {
1692 pps = interval.getPps();
1693 endPPS = interval.getEnd().copy();
1694 }
1695 long milliSecondsToEndPPS = endPPS.diffMilliSeconds(d);
1696 int pixelToEndPPS = (int) Math.round(((double) milliSecondsToEndPPS * pps / MILLISCALING));
1697
1698 if (pixelToGo <= pixelToEndPPS || noFollowingPPSInterval) {
1699
1700 milliSeconds = milliSeconds + (long) ((double) pixelToGo / pps * MILLISCALING);
1701 JaretDate result = _minDate.copy().advanceMillis(milliSeconds);
1702 return result;
1703 } else {
1704
1705 long ms = endPPS.diffMilliSeconds(d);
1706 milliSeconds = milliSeconds + ms;
1707 pixelToGo = pixelToGo - pixelToEndPPS;
1708 d = endPPS.copy();
1709 }
1710 }
1711 return null;
1712 }
1713
1714
1715
1716
1717
1718
1719
1720 private JaretDate dateForCoordVariable(int coord) {
1721 int pixDif = coord - (_yAxisWidth + _hierarchyWidth);
1722
1723
1724 int pixelToGo = pixDif;
1725 if (pixDif <= 0) {
1726
1727 return dateForCoordPlain(coord);
1728 }
1729 long milliSeconds = 0;
1730 JaretDate d = _startDate.copy();
1731
1732 while (pixelToGo > 0) {
1733 PPSInterval interval = getPPSInterval(d);
1734
1735 double pps = 0;
1736 JaretDate endPPS;
1737 boolean noFollowingPPSInterval = false;
1738 if (interval == null) {
1739
1740 pps = _pixelPerSeconds;
1741 Interval i = nextPPSInterval(d);
1742 if (i != null) {
1743 endPPS = i.getBegin().copy();
1744 } else {
1745 noFollowingPPSInterval = true;
1746 endPPS = getMaxDate().copy();
1747 }
1748 } else {
1749 pps = interval.getPps();
1750 endPPS = interval.getEnd().copy();
1751 }
1752 long milliSecondsToEndPPS = endPPS.diffMilliSeconds(d);
1753 int pixelToEndPPS = (int) Math.round(((double) milliSecondsToEndPPS * pps / MILLISCALING));
1754
1755 if (pixelToGo <= pixelToEndPPS || noFollowingPPSInterval) {
1756
1757 milliSeconds = milliSeconds + (long) ((double) pixelToGo / pps * MILLISCALING);
1758 JaretDate result = _startDate.copy().advanceMillis(milliSeconds);
1759 return result;
1760 } else {
1761
1762 long ms = endPPS.diffMilliSeconds(d);
1763 milliSeconds = milliSeconds + ms;
1764 pixelToGo = pixelToGo - pixelToEndPPS;
1765 d = endPPS.copy();
1766 }
1767 }
1768 return null;
1769 }
1770
1771
1772
1773
1774
1775
1776
1777 public int xForDate(JaretDate date) {
1778 if (!_variableXScale) {
1779 return xForDatePlain(date, false);
1780 } else {
1781 return xForDateVariable(date, false);
1782 }
1783 }
1784
1785
1786
1787
1788
1789
1790
1791 public int xForDateAbs(JaretDate date) {
1792 if (!_variableXScale) {
1793 return xForDatePlain(date, true);
1794 } else {
1795 return xForDateVariable(date, true);
1796 }
1797 }
1798
1799
1800
1801
1802
1803
1804
1805
1806 protected int xForDatePlain(JaretDate date, boolean absolute) {
1807 int offset = _orientation.equals(TimeBarViewerInterface.Orientation.HORIZONTAL) ? _offsetLeft : _offsetTop;
1808 long milliSeconds;
1809 if (!absolute) {
1810 milliSeconds = date.diffMilliSeconds(_startDate);
1811 } else {
1812 milliSeconds = date.diffMilliSeconds(_minDate);
1813 }
1814
1815
1816 int x = _yAxisWidth + _hierarchyWidth + offset
1817 + (int) Math.round((((double) milliSeconds) * _pixelPerSeconds / MILLISCALING));
1818 return x;
1819 }
1820
1821
1822
1823
1824
1825
1826
1827
1828 protected int xForDateVariable(JaretDate date, boolean absolute) {
1829
1830 long milliSeconds;
1831 if (!absolute) {
1832 milliSeconds = date.diffMilliSeconds(_startDate);
1833 } else {
1834 milliSeconds = date.diffMilliSeconds(_minDate);
1835 }
1836 boolean neg = false;
1837 if (milliSeconds <= 0) {
1838 if (absolute) {
1839 return 0;
1840 }
1841
1842
1843 neg = true;
1844 milliSeconds = date.diffMilliSeconds(_minDate);
1845 }
1846
1847 long milliSecondsToGo = milliSeconds;
1848 JaretDate d = (absolute || neg) ? _minDate.copy() : _startDate.copy();
1849 int x = 0;
1850 while (milliSecondsToGo > 0) {
1851 PPSInterval interval = getPPSInterval(d);
1852
1853 double pps = 0;
1854 JaretDate endPPS;
1855 boolean noFollowingPPSInterval = false;
1856 if (interval == null) {
1857
1858 pps = _pixelPerSeconds;
1859 Interval i = nextPPSInterval(d);
1860 if (i != null) {
1861 endPPS = i.getBegin().copy();
1862 } else {
1863 noFollowingPPSInterval = true;
1864 endPPS = getMaxDate().copy();
1865 }
1866 } else {
1867 pps = interval.getPps();
1868 endPPS = interval.getEnd().copy();
1869 }
1870 if (date.compareTo(endPPS) <= 0 || noFollowingPPSInterval) {
1871
1872 x = x + (int) Math.round(((double) milliSecondsToGo * pps / MILLISCALING));
1873 if (absolute) {
1874 return x;
1875 }
1876
1877 if (neg) {
1878
1879 int firstOff = xForDateAbs(_startDate);
1880 x -= firstOff;
1881 }
1882 return _yAxisWidth + _hierarchyWidth + x;
1883 } else {
1884
1885 long ms = endPPS.diffMilliSeconds(d);
1886 x = x + (int) Math.round(((double) ms * pps / MILLISCALING));
1887 milliSecondsToGo = milliSecondsToGo - ms;
1888 d = endPPS.copy();
1889 }
1890 }
1891 if (absolute) {
1892 return x;
1893 }
1894
1895 if (neg) {
1896
1897 int firstOff = xForDateAbs(_startDate);
1898 x -= firstOff;
1899 }
1900 return _yAxisWidth + _hierarchyWidth + x;
1901 }
1902
1903
1904
1905
1906
1907
1908
1909 public PPSInterval getPPSInterval(JaretDate d) {
1910 List<Interval> l = _xScalePPSIntervalRow.getIntervals(d);
1911 if (l.size() == 0) {
1912 return null;
1913 }
1914 if (l.size() == 1) {
1915 PPSInterval interval = (PPSInterval) l.get(0);
1916 if (interval.getEnd().equals(d)) {
1917 return null;
1918 }
1919 return interval;
1920 }
1921 if (l.size() == 2) {
1922 PPSInterval interval1 = (PPSInterval) l.get(0);
1923 PPSInterval interval2 = (PPSInterval) l.get(1);
1924 if (interval1.getBegin().equals(d)) {
1925 return interval1;
1926 }
1927 if (interval2.getBegin().equals(d)) {
1928 return interval2;
1929 }
1930
1931 }
1932 throw new RuntimeException("no overlapping intervals in xscale row");
1933 }
1934
1935
1936
1937
1938
1939
1940
1941 public PPSInterval nextPPSInterval(JaretDate d) {
1942 PPSInterval result = null;
1943 result = getPPSInterval(d);
1944 if (result != null) {
1945 return result;
1946 }
1947
1948 List<Interval> list = _xScalePPSIntervalRow.getIntervals();
1949 for (int i = 0; i < list.size(); i++) {
1950 PPSInterval interval = (PPSInterval) list.get(i);
1951 long diffMilliSecs = d.diffMilliSeconds(interval.getBegin());
1952 if (diffMilliSecs <= 0) {
1953 result = interval;
1954 break;
1955 }
1956 }
1957 return result;
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967 public TimeBarRow rowForXY(int x, int y) {
1968 if (_diagramRect.contains(x, y) || _yAxisRect.contains(x, y) || _hierarchyRect.contains(x, y)) {
1969 if (_orientation == Orientation.HORIZONTAL) {
1970 return rowForY(y);
1971 } else {
1972 return rowForY(x);
1973 }
1974 } else {
1975 return null;
1976 }
1977 }
1978
1979
1980
1981
1982
1983
1984
1985 private int rowForCoordInternal(int coord) {
1986 if (!_timeBarViewState.getUseVariableRowHeights()) {
1987 if (_orientation == Orientation.HORIZONTAL) {
1988 return _firstRow + (coord + _firstRowPixelOffset - _diagramRect.y)
1989 / _timeBarViewState.getDefaultRowHeight();
1990 } else {
1991 return _firstRow + (coord + _firstRowPixelOffset - _diagramRect.x)
1992 / _timeBarViewState.getDefaultRowHeight();
1993 }
1994 }
1995 int maxY = 0;
1996 if (_orientation == Orientation.HORIZONTAL) {
1997 coord -= _diagramRect.y;
1998 maxY = _diagramRect.height;
1999 } else {
2000 coord -= _diagramRect.x;
2001 maxY = _diagramRect.width;
2002 }
2003
2004 int rowStart = -_firstRowPixelOffset;
2005 int idx = _firstRow;
2006
2007 while (rowStart < maxY && idx < _rowList.size()) {
2008 int rHeight = _timeBarViewState.getRowHeight(getRow(idx));
2009 if (coord >= rowStart && coord <= rowStart + rHeight) {
2010 return idx;
2011 }
2012 rowStart += rHeight;
2013 idx++;
2014 }
2015 return -1;
2016
2017 }
2018
2019
2020
2021
2022
2023
2024
2025
2026 public TimeBarRow rowForY(int y) {
2027
2028 if (_rowList == null || _model == null) {
2029 return null;
2030 }
2031 int idx = -1;
2032 idx = rowForCoordInternal(y);
2033 if (idx < _rowList.size() && idx >= 0) {
2034 return getRow(idx);
2035 } else {
2036 return null;
2037 }
2038 }
2039
2040
2041
2042
2043
2044
2045
2046 public int yForRow(TimeBarRow row) {
2047 if (!_timeBarViewState.getUseVariableRowHeights()) {
2048 int idx = _rowList.indexOf(row);
2049 if (idx == -1) {
2050 return -1;
2051 }
2052 idx = idx - _firstRow;
2053 if (_orientation == Orientation.HORIZONTAL) {
2054 return idx * _timeBarViewState.getDefaultRowHeight() + _diagramRect.y - _firstRowPixelOffset;
2055 } else {
2056 return idx * _timeBarViewState.getDefaultRowHeight() + _diagramRect.x - _firstRowPixelOffset;
2057 }
2058 }
2059
2060 int height;
2061 int offset;
2062 if (_orientation == Orientation.HORIZONTAL) {
2063 height = _diagramRect.height;
2064 offset = _diagramRect.y;
2065 } else {
2066 height = _diagramRect.width;
2067 offset = _diagramRect.x;
2068 }
2069
2070 int y = -_firstRowPixelOffset;
2071 int idx = _firstRow;
2072
2073 if (_rowList.size() == 0)
2074 return -1;
2075 TimeBarRow r = getRow(idx);
2076
2077 while (y <= height) {
2078 if (row.equals(r)) {
2079 return y + offset;
2080 }
2081 y += _timeBarViewState.getRowHeight(r);
2082 idx++;
2083 if (idx >= _rowList.size()) {
2084 break;
2085 }
2086 r = getRow(idx);
2087 }
2088 return -1;
2089
2090 }
2091
2092
2093
2094
2095
2096
2097
2098 public int dispIdxForRow(TimeBarRow row) {
2099 int rIdx = _rowList.indexOf(row);
2100 if (rIdx >= _firstRow && rIdx <= _firstRow + getRowsDisplayed()) {
2101 return rIdx - _firstRow;
2102 }
2103 return -1;
2104 }
2105
2106
2107
2108
2109
2110
2111
2112
2113 public Rectangle getRowBounds(TimeBarRow row) {
2114 if (!isRowDisplayed(row)) {
2115 return new Rectangle(0, 0, 0, 0);
2116 } else {
2117 if (_orientation == Orientation.HORIZONTAL) {
2118 int y = yForRow(row);
2119 return new Rectangle(0, y, _tbvi.getWidth(), _timeBarViewState.getRowHeight(row));
2120 } else {
2121 int x = yForRow(row);
2122 return new Rectangle(x, 0, _timeBarViewState.getRowHeight(row), _tbvi.getHeight());
2123 }
2124 }
2125 }
2126
2127
2128
2129
2130
2131
2132
2133
2134 public Rectangle getIntervalBounds(int rowIdx, Interval interval) {
2135 if (_orientation == Orientation.HORIZONTAL) {
2136 int x = xForDate(interval.getBegin());
2137 int x2 = xForDate(interval.getEnd());
2138 int width = x2 - x;
2139 int y = rowIdx == -1 ? 0 : yForRow(getRow(rowIdx));
2140 int height = rowIdx == -1 ? _tbvi.getHeight() : _timeBarViewState.getRowHeight(getRow(rowIdx));
2141 TimeBarRow row = rowIdx == -1 ? null : _rowList.get(rowIdx);
2142 if (row != null && !getTimeBarViewState().getDrawOverlapping(row)) {
2143 OverlapInfo oi = _overlapStrategy.getOverlapInfo(row, interval);
2144 if (oi != null) {
2145 if (!_useUniformHeight) {
2146 height = height / (oi.maxOverlapping + 1);
2147 } else {
2148 height = height / (_overlapStrategy.getMaxOverlapCount(row));
2149 }
2150 y = y + oi.pos * height;
2151 }
2152 }
2153 return new Rectangle(x, y, width, height);
2154 } else {
2155 int y = xForDate(interval.getBegin());
2156 int y2 = xForDate(interval.getEnd());
2157 int height = y2 - y;
2158 int x = rowIdx == -1 ? 0 : yForRow(getRow(rowIdx));
2159 int width = rowIdx == -1 ? _tbvi.getWidth() : _timeBarViewState.getRowHeight(getRow(rowIdx));
2160 TimeBarRow row = rowIdx == -1 ? null : _rowList.get(rowIdx);
2161 if (row != null && !getTimeBarViewState().getDrawOverlapping(row)) {
2162 OverlapInfo oi = _overlapStrategy.getOverlapInfo(_rowList.get(rowIdx), interval);
2163 if (oi != null) {
2164 if (!_useUniformHeight) {
2165 width = width / (oi.maxOverlapping + 1);
2166 } else {
2167 width = width / (_overlapStrategy.getMaxOverlapCount(row));
2168 }
2169 x = x + oi.pos * width;
2170 }
2171 }
2172 return new Rectangle(x, y, width, height);
2173 }
2174 }
2175
2176
2177
2178
2179
2180
2181
2182
2183 public Rectangle getIntervalBounds(Interval interval) {
2184 TimeBarRow row = _model.getRowForInterval(interval);
2185 if (row != null) {
2186 return getIntervalBounds(row, interval);
2187 }
2188 return null;
2189 }
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199 public Rectangle getIntervalBounds(TimeBarRow row, Interval interval) {
2200 return getIntervalBounds(row == null ? -1 : _rowList.indexOf(row), interval);
2201 }
2202
2203
2204
2205
2206 public int getRowsDisplayed() {
2207 if (!_timeBarViewState.getUseVariableRowHeights()) {
2208
2209 if (_orientation == Orientation.HORIZONTAL) {
2210 return _diagramRect.height / _timeBarViewState.getDefaultRowHeight() + 1;
2211
2212 } else {
2213 return _diagramRect.width / _timeBarViewState.getDefaultRowHeight() + 1;
2214
2215 }
2216 }
2217
2218 int end;
2219 if (_orientation == Orientation.HORIZONTAL) {
2220 end = _diagramRect.height;
2221 } else {
2222 end = _diagramRect.width;
2223 }
2224 int count = 0;
2225 int idx = _firstRow;
2226 int coord = -_firstRowPixelOffset;
2227 while (coord <= end && idx < _rowList.size()) {
2228 coord += _timeBarViewState.getRowHeight(getRow(idx++));
2229 count++;
2230 }
2231 return count;
2232
2233 }
2234
2235
2236
2237
2238
2239
2240
2241 public boolean isRowDisplayed(TimeBarRow row) {
2242 return _rowList.indexOf(row) - _firstRow < getRowsDisplayed();
2243 }
2244
2245
2246
2247
2248
2249
2250
2251
2252 public List<Interval> getIntervalsAt(int x, int y) {
2253 TimeBarRow row = rowForXY(x, y);
2254 return getIntervalsAt(row, x, y);
2255 }
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266 public List<Interval> getIntervalsAt(TimeBarRow row, int x, int y) {
2267 List<Interval> result = new ArrayList<Interval>();
2268 if (row != null) {
2269 JaretDate date;
2270 if (_orientation == Orientation.HORIZONTAL) {
2271 date = dateForCoord(x);
2272 } else {
2273 date = dateForCoord(y);
2274 }
2275
2276
2277 if (_milliAccuracy) {
2278 date.advanceMillis(1);
2279 }
2280 result = row.getIntervals(date);
2281
2282 if (_intervalFilter != null) {
2283 List<Interval> in = result;
2284 result = new ArrayList<Interval>();
2285 for (Interval interval : in) {
2286 if (_intervalFilter.isInResult(interval)) {
2287 result.add(interval);
2288 }
2289 }
2290 }
2291
2292
2293 if (result.size() <= 1 || x == -1 || y == -1) {
2294 return result;
2295 }
2296
2297 List<Interval> newResult = new ArrayList<Interval>(1);
2298 for (Interval interval : result) {
2299 Rectangle rect = getIntervalBounds(row, interval);
2300 if (rect.contains(x, y)) {
2301 newResult.add(interval);
2302 }
2303 }
2304 return newResult;
2305 } else {
2306 result = new ArrayList<Interval>();
2307 }
2308 return result;
2309
2310 }
2311
2312
2313
2314
2315
2316
2317
2318
2319 public List<Interval> getIntervalsAt(TimeBarRow row, int x) {
2320 if (_orientation == Orientation.HORIZONTAL) {
2321 return getIntervalsAt(row, x, -1);
2322 } else {
2323 return getIntervalsAt(row, -1, x);
2324 }
2325 }
2326
2327
2328
2329
2330
2331 public void markerMoved(TimeBarMarker marker, JaretDate oldDate, JaretDate currentDate) {
2332 int width = _tbvi.getMarkerWidth(marker);
2333 if (isDisplayed(currentDate)) {
2334
2335 if (_orientation.equals(Orientation.HORIZONTAL)) {
2336 _tbvi.repaint(xForDate(oldDate) - width / 2 + 1, 0, width + 1, _tbvi.getHeight());
2337 _tbvi.repaint(xForDate(currentDate) - width / 2 + 1, 0, width + 1, _tbvi.getHeight());
2338 } else {
2339
2340 _tbvi.repaint(0, xForDate(oldDate) - width / 2 + 1, _tbvi.getWidth(), width + 1);
2341 _tbvi.repaint(0, xForDate(currentDate) - width / 2 + 1, _tbvi.getWidth(), width + 1);
2342 }
2343 }
2344 if (marker.getDate().compareTo(_minDate) < 0) {
2345 setMinDate(marker.getDate().copy());
2346 } else if (marker.getDate().compareTo(_maxDate) > 0) {
2347 setMaxDate(marker.getDate().copy());
2348 }
2349 }
2350
2351
2352
2353
2354 public void markerDescriptionChanged(TimeBarMarker marker, String oldValue, String newValue) {
2355 int width = _tbvi.getMarkerWidth(marker);
2356 if (isDisplayed(marker.getDate())) {
2357 _tbvi.repaint(xForDate(marker.getDate()) - width / 2 + 1, 0, width / 2 + 1, _tbvi.getHeight());
2358 }
2359 }
2360
2361
2362
2363
2364
2365
2366
2367 public void selectionChanged(TimeBarSelectionModel selectionModel) {
2368
2369 _tbvi.repaint();
2370
2371
2372 _tbvi.fireSelectionChanged();
2373 }
2374
2375
2376
2377
2378 public void elementAddedToSelection(TimeBarSelectionModel selectionModel, Object element) {
2379 if (element instanceof TimeBarRow) {
2380 Rectangle rowRect = getRowBounds((TimeBarRow) element);
2381 _tbvi.repaint(rowRect);
2382 } else if (element instanceof Interval) {
2383
2384
2385 Rectangle intervalRect = getIntervalBounds(null, (Interval) element);
2386 _tbvi.repaint(intervalRect);
2387 } else if (element instanceof IIntervalRelation) {
2388
2389 _tbvi.repaint(_diagramRect);
2390 } else {
2391 throw new RuntimeException("Unknonw object in elementAddedToSelection " + element.getClass().getName());
2392 }
2393
2394
2395 _tbvi.fireSelectionChanged();
2396
2397 }
2398
2399
2400
2401
2402 public void elementRemovedFromSelection(TimeBarSelectionModel selectionModel, Object element) {
2403 if (element instanceof TimeBarRow) {
2404
2405
2406 if (_rowList.contains((TimeBarRow) element)) {
2407 Rectangle rowRect = getRowBounds((TimeBarRow) element);
2408 _tbvi.repaint(rowRect);
2409 }
2410 } else if (element instanceof Interval) {
2411 Interval interval = (Interval) element;
2412 TimeBarRow row = _model.getRowForInterval(interval);
2413
2414 if (row != null && row.getIntervals() != null && row.getIntervals().contains(interval)) {
2415 Rectangle intervalRect = getIntervalBounds(row, (Interval) element);
2416 _tbvi.repaint(intervalRect);
2417 }
2418 } else if (element instanceof IIntervalRelation) {
2419
2420 _tbvi.repaint(_diagramRect);
2421 } else {
2422 throw new RuntimeException("Unknown object in elementRemovedFromSelection " + element.getClass().getName());
2423 }
2424
2425
2426 _tbvi.fireSelectionChanged();
2427
2428 }
2429
2430
2431
2432
2433
2434
2435 public void modelDataChanged(TimeBarModel model) {
2436 checkAndAdjustMinMax();
2437 updateRowList();
2438 _overlapStrategy.clearCachedData();
2439 _tbvi.repaint();
2440 }
2441
2442
2443
2444
2445 public void rowDataChanged(TimeBarModel model, TimeBarRow row) {
2446 checkAndAdjustMinMax();
2447 if (!getTimeBarViewState().getDrawOverlapping(row)) {
2448 _overlapStrategy.updateOICache(row);
2449 }
2450 if (isRowDisplayed(row)) {
2451 _tbvi.repaint();
2452 }
2453
2454
2455
2456 }
2457
2458
2459
2460
2461 public void rowAdded(TimeBarModel model, TimeBarRow row) {
2462 checkAndAdjustMinMax();
2463 updateRowList();
2464 _tbvi.repaint();
2465 }
2466
2467
2468
2469
2470 public void rowRemoved(TimeBarModel model, TimeBarRow row) {
2471 checkAndAdjustMinMax();
2472 boolean isDisplayed = isRowDisplayed(row);
2473 updateRowList();
2474 if (isDisplayed) {
2475 _tbvi.repaint();
2476 }
2477
2478 if (_selectionModel != null) {
2479 _selectionModel.remSelectedRow(row);
2480 }
2481 }
2482
2483
2484
2485
2486 public void elementAdded(TimeBarModel model, TimeBarRow row, Interval element) {
2487 checkAndAdjustMinMax();
2488 if (!getTimeBarViewState().getDrawOverlapping(row)) {
2489 _overlapStrategy.updateOICache(row);
2490 }
2491 if (isRowDisplayed(row)) {
2492 _tbvi.repaint();
2493 }
2494 }
2495
2496
2497
2498
2499 public void elementRemoved(TimeBarModel model, TimeBarRow row, Interval element) {
2500 checkAndAdjustMinMax();
2501 if (!getTimeBarViewState().getDrawOverlapping(row)) {
2502 _overlapStrategy.updateOICache(row);
2503 }
2504 if (isRowDisplayed(row)) {
2505 _tbvi.repaint();
2506 }
2507
2508 if (_selectionModel != null) {
2509 _selectionModel.remSelectedInterval(element);
2510 }
2511 }
2512
2513
2514
2515
2516 public void elementChanged(TimeBarModel model, TimeBarRow row, Interval element) {
2517 checkAndAdjustMinMax();
2518 if (!getTimeBarViewState().getDrawOverlapping(row)) {
2519 _overlapStrategy.updateOICache(row);
2520 }
2521 if (isRowDisplayed(row)) {
2522 _tbvi.repaint();
2523 }
2524 }
2525
2526
2527
2528
2529 public void headerChanged(TimeBarModel model, TimeBarRow row, Object newHeader) {
2530 if (isRowDisplayed(row)) {
2531 _tbvi.repaint();
2532 }
2533 }
2534
2535
2536
2537
2538
2539
2540 public int getFirstRow() {
2541 return _firstRow;
2542 }
2543
2544
2545
2546
2547
2548
2549 public void setFirstRow(int firstRow) {
2550 setFirstRow(firstRow, 0);
2551 }
2552
2553
2554
2555
2556
2557
2558 public void setFirstRow(TimeBarRow row) {
2559 int index = _rowList.indexOf(row);
2560 if (index != -1) {
2561 setFirstRow(index, 0);
2562 }
2563 }
2564
2565
2566
2567
2568
2569
2570
2571 public void setFirstRow(int firstRow, int pixOffset) {
2572 if (firstRow != _firstRow || _firstRowPixelOffset != pixOffset) {
2573 int oldVal = _firstRow;
2574 int oldOffset = _firstRowPixelOffset;
2575
2576 if (_tbvi != null) {
2577
2578 int diff;
2579
2580
2581 if (oldVal > _rowList.size()) {
2582 diff = Integer.MAX_VALUE;
2583 } else {
2584 if (!_timeBarViewState.getUseVariableRowHeights()) {
2585 diff = (firstRow * _timeBarViewState.getDefaultRowHeight() + pixOffset)
2586 - (oldVal * _timeBarViewState.getDefaultRowHeight() + oldOffset);
2587 } else {
2588 diff = (getAbsPosForRow(firstRow) + pixOffset) - (getAbsPosForRow(oldVal) + oldOffset);
2589 }
2590 }
2591
2592
2593 int maxOptScroll = _orientation.equals(Orientation.HORIZONTAL) ? (_diagramRect.height - _diagramRect.height)
2594 : (_diagramRect.width - _diagramRect.width);
2595
2596 if (!_optimizeScrolling || Math.abs(diff) > maxOptScroll / 3) {
2597 _firstRow = firstRow;
2598 _firstRowPixelOffset = pixOffset;
2599 _tbvi.repaint();
2600 } else {
2601
2602 if (_orientation == Orientation.HORIZONTAL) {
2603 _tbvi.doScrollVertical(diff);
2604 } else {
2605 _tbvi.doScrollHorizontal(diff);
2606 }
2607
2608 _firstRow = firstRow;
2609 _firstRowPixelOffset = pixOffset;
2610 }
2611 if (_tbvi != null) {
2612 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_FIRSTROW, oldVal, firstRow);
2613 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_FIRSTROWOFFSET, oldOffset, pixOffset);
2614 }
2615 updateRowScrollBar();
2616 } else {
2617 _firstRow = firstRow;
2618 _firstRowPixelOffset = pixOffset;
2619 }
2620 }
2621 }
2622
2623
2624
2625
2626
2627
2628 public int getFirstRowOffset() {
2629 return _firstRowPixelOffset;
2630 }
2631
2632
2633
2634
2635
2636
2637 public void setFirstRowOffset(int offset) {
2638 setFirstRow(getFirstRow(), offset);
2639 }
2640
2641
2642
2643
2644
2645
2646
2647 public void setLastRow(int index) {
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670 if (index >= _rowList.size()) {
2671 setFirstRow(0, 0);
2672 return;
2673 }
2674 TimeBarRow row = getRow(index);
2675 int absY = getAbsPosForRow(index);
2676 int endY = absY + _timeBarViewState.getRowHeight(row);
2677
2678 int height = _diagramRect.height;
2679
2680 int upperBound = endY - height;
2681 int y = endY;
2682 int idx = index;
2683
2684 if (endY < height) {
2685 setFirstRow(0, 0);
2686 } else {
2687 y -= _timeBarViewState.getRowHeight(row);
2688 idx--;
2689 while (idx > 0 && y > upperBound) {
2690 row = getRow(idx);
2691 y -= _timeBarViewState.getRowHeight(row);
2692 idx--;
2693 }
2694 int offset = Math.abs(y - upperBound);
2695 if (idx >= 0) {
2696 setFirstRow(idx + 1, offset);
2697 } else {
2698 setFirstRow(0, offset);
2699 }
2700
2701 }
2702
2703 }
2704
2705
2706
2707
2708
2709
2710
2711 public void setLastRow(TimeBarRow row) {
2712 int index = _rowList.indexOf(row);
2713 if (index != -1) {
2714 setLastRow(index);
2715 }
2716 }
2717
2718
2719
2720
2721 public int getTimeScalePosition() {
2722 return _timeScalePosition;
2723 }
2724
2725
2726
2727
2728 public void setTimeScalePosition(int timeScalePosition) {
2729 _timeScalePosition = timeScalePosition;
2730 if (_tbvi != null) {
2731 _tbvi.repaint();
2732 }
2733 }
2734
2735
2736
2737
2738 public int getYAxisWidth() {
2739 return _yAxisWidth;
2740 }
2741
2742
2743
2744
2745 public void setYAxisWidth(int axisWidth) {
2746 int oldval = _yAxisWidth;
2747 _yAxisWidth = axisWidth;
2748 if (oldval != _yAxisWidth) {
2749 if (_tbvi != null) {
2750 _tbvi.repaint();
2751 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_YAXISWIDTH, oldval, _yAxisWidth);
2752 }
2753 }
2754 }
2755
2756
2757
2758
2759 public int getXAxisHeight() {
2760 return _xAxisHeight;
2761 }
2762
2763
2764
2765
2766
2767
2768 public void setXAxisHeight(int axisHeight) {
2769 if (axisHeight != _xAxisHeight) {
2770 int oldVal = _xAxisHeight;
2771 _xAxisHeight = axisHeight;
2772 if (_tbvi != null) {
2773 _tbvi.repaint();
2774 _tbvi.firePropertyChange(TimeBarViewerInterface.PROPERTYNAME_XAXISHEIGHT, oldVal, axisHeight);
2775 }
2776 }
2777 }
2778
2779
2780
2781
2782
2783
2784 public void setHierarchyWidth(int width) {
2785 _hierarchyWidth = width;
2786 if (_tbvi != null) {
2787 _tbvi.repaint();
2788 }
2789 }
2790
2791
2792
2793
2794
2795
2796 public int getHierarchyWidth() {
2797 return _hierarchyWidth;
2798 }
2799
2800
2801
2802
2803
2804
2805
2806 public void preparePaint(int cwidth, int cheight) {
2807 if (_orientation == Orientation.HORIZONTAL) {
2808 preparePaintHorizontal(cwidth, cheight);
2809 } else {
2810 preparePaintVertical(cwidth, cheight);
2811 }
2812
2813
2814 if (_initialStartDate != null) {
2815 JaretDate startDate = _initialStartDate;
2816 _initialStartDate = null;
2817 setSecondsDisplayed(_initialSecondsDisplayed, false);
2818 setStartDate(startDate);
2819 }
2820
2821 }
2822
2823
2824
2825
2826
2827
2828
2829 public void preparePaintHorizontal(int cwidth, int cheight) {
2830
2831 int topy = (_timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_BOTTOM || _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_NONE) ? 0
2832 : _xAxisHeight;
2833 int height = _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_NONE ? cheight : cheight
2834 - _xAxisHeight;
2835
2836 _diagramRect = new Rectangle(_hierarchyWidth + _yAxisWidth, topy, cwidth - _yAxisWidth - _hierarchyWidth,
2837 height);
2838
2839 _yAxisRect = new Rectangle(_hierarchyWidth, topy, _yAxisWidth, height);
2840
2841 _hierarchyRect = new Rectangle(0, topy, _hierarchyWidth, height);
2842
2843 if (_timeScalePosition != TimeBarViewerInterface.TIMESCALE_POSITION_NONE) {
2844 _xAxisRect = new Rectangle(_diagramRect.x,
2845 _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_TOP ? 0 : cheight - _xAxisHeight,
2846 _diagramRect.width, _xAxisHeight);
2847 } else {
2848 _xAxisRect = new Rectangle(0, 0, 0, 0);
2849 }
2850
2851 _endDate = dateForX(cwidth);
2852
2853
2854 _titleRect = new Rectangle(0, _xAxisRect.y, _hierarchyRect.width + _yAxisRect.width, _xAxisRect.height);
2855
2856
2857 if (_offsetLeft != 0 || _offsetTop != 0) {
2858 _diagramRect.x += _offsetLeft;
2859 _diagramRect.y += _offsetTop;
2860 _yAxisRect.x += _offsetLeft;
2861 _yAxisRect.y += _offsetTop;
2862 _xAxisRect.x += _offsetLeft;
2863 _xAxisRect.y += _offsetTop;
2864 _hierarchyRect.x += _offsetLeft;
2865 _hierarchyRect.y += _offsetTop;
2866 _titleRect.x += _offsetLeft;
2867 _titleRect.y += _offsetTop;
2868 }
2869
2870 if (_autoScaleRows > 0) {
2871 int rowHeight = _diagramRect.height / _autoScaleRows;
2872 setRowHeight(rowHeight);
2873 }
2874
2875 }
2876
2877
2878
2879
2880
2881
2882
2883 public void preparePaintVertical(int cwidth, int cheight) {
2884
2885 int leftX = (_timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_BOTTOM || _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_NONE) ? 0
2886 : _xAxisHeight;
2887 int width = _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_NONE ? cwidth : cwidth
2888 - _xAxisHeight;
2889
2890
2891 _diagramRect = new Rectangle(leftX, _hierarchyWidth + _yAxisWidth, width, cheight - _yAxisWidth
2892 - _hierarchyWidth);
2893
2894
2895 _yAxisRect = new Rectangle(leftX, _hierarchyWidth, width, _yAxisWidth);
2896
2897 _hierarchyRect = new Rectangle(leftX, 0, width, _hierarchyWidth);
2898
2899
2900 if (_timeScalePosition != TimeBarViewerInterface.TIMESCALE_POSITION_NONE) {
2901 int tsX = _timeScalePosition == TimeBarViewerInterface.TIMESCALE_POSITION_TOP ? 0 : cwidth - _xAxisHeight;
2902 _xAxisRect = new Rectangle(tsX, _diagramRect.y, _xAxisHeight, _diagramRect.height);
2903 } else {
2904 _xAxisRect = new Rectangle(0, 0, 0, 0);
2905 }
2906
2907 _endDate = dateForX(cheight);
2908
2909
2910 _titleRect = new Rectangle(_xAxisRect.x, 0, _xAxisRect.width, _hierarchyRect.height + _yAxisRect.height);
2911
2912
2913 if (_offsetLeft != 0 || _offsetTop != 0) {
2914 _diagramRect.x += _offsetLeft;
2915 _diagramRect.y += _offsetTop;
2916 _yAxisRect.x += _offsetLeft;
2917 _yAxisRect.y += _offsetTop;
2918 _xAxisRect.x += _offsetLeft;
2919 _xAxisRect.y += _offsetTop;
2920 _hierarchyRect.x += _offsetLeft;
2921 _hierarchyRect.y += _offsetTop;
2922 _titleRect.x += _offsetLeft;
2923 _titleRect.y += _offsetTop;
2924 }
2925 if (_autoScaleRows > 0) {
2926 int rowWidth = _diagramRect.width / _autoScaleRows;
2927 setRowHeight(rowWidth);
2928 }
2929
2930 }
2931
2932
2933
2934
2935 public Rectangle getDiagramRect() {
2936 return _diagramRect;
2937 }
2938
2939
2940
2941
2942 public Rectangle getXAxisRect() {
2943 return _xAxisRect;
2944 }
2945
2946
2947
2948
2949 public Rectangle getYAxisRect() {
2950 return _yAxisRect;
2951 }
2952
2953
2954
2955
2956 public Rectangle getHierarchyRect() {
2957 return _hierarchyRect;
2958 }
2959
2960
2961
2962
2963
2964
2965 public Rectangle getTitleRect() {
2966 return _titleRect;
2967 }
2968
2969
2970
2971
2972 public JaretDate getLastStartDate() {
2973 return _lastStartDate;
2974 }
2975
2976
2977
2978
2979 public void setLastStartDate(JaretDate lastStartDate) {
2980 _lastStartDate = lastStartDate;
2981 }
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991 private List<Interval> getIntervalsSortedAt(TimeBarRow row, int x) {
2992 List<Interval> intervals = getIntervalsAt(row, x);
2993 if (intervals.size() == 0) {
2994 return intervals;
2995 }
2996
2997
2998 Collections.sort(intervals, new Comparator<Interval>() {
2999 public int compare(Interval i1, Interval i2) {
3000 return i1.getSeconds() - i2.getSeconds();
3001 }
3002
3003 });
3004 return intervals;
3005 }
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015 private Interval intervalAt(TimeBarRow row, int x, int y) {
3016 Interval result = null;
3017
3018 List<Interval> intervals;
3019 if (_orientation == Orientation.HORIZONTAL) {
3020 intervals = getIntervalsSortedAt(row, x);
3021 } else {
3022 intervals = getIntervalsSortedAt(row, y);
3023 }
3024 if (intervals.size() == 0) {
3025 return null;
3026 }
3027 for (Interval interval : intervals) {
3028 Rectangle intervalRect = getIntervalBounds(row, interval);
3029 boolean overlapping = getTimeBarViewState().getDrawOverlapping(row) ? false : _overlapStrategy
3030 .getOverlapInfo(row, interval).overlappingCount > 0
3031 || _useUniformHeight;
3032 if (_tbvi.timeBarContains(interval, intervalRect, x - intervalRect.x, y - intervalRect.y, overlapping)) {
3033 result = interval;
3034
3035 break;
3036 }
3037 }
3038 return result;
3039 }
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051 public void mousePressed(int x, int y, boolean isPopupTrigger, int modifierMask) {
3052 _lastPressedX = x;
3053 _lastPressedY = y;
3054 boolean nothingHitInDiagramArea = true;
3055 if (_diagramRect.contains(x, y)) {
3056
3057 if ((modifierMask & InputEvent.SHIFT_DOWN_MASK) == 0) {
3058
3059 TimeBarRow row = rowForXY(x, y);
3060
3061 Interval interval = intervalAt(row, x, y);
3062
3063
3064 if (interval != null && (_intervalFilter == null || _intervalFilter.isInResult(interval))) {
3065
3066 setFocussedInterval(interval);
3067
3068
3069 if ((modifierMask & InputEvent.CTRL_DOWN_MASK) != 0) {
3070 if (!_selectionModel.isSelected(interval)) {
3071 _selectionModel.addSelectedInterval(interval);
3072 } else {
3073 _selectionModel.remSelectedInterval(interval);
3074 }
3075 } else if (_selectionModel.isEmpty()) {
3076 _selectionModel.setSelectedInterval(interval);
3077 }
3078 } else {
3079
3080 List<IIntervalRelation> relations = _tbvi.getRelationsForCoord(x, y);
3081 if (relations != null && relations.size() > 0) {
3082
3083 handleRelationSelection(relations, modifierMask);
3084 } else {
3085
3086
3087 if (!isPopupTrigger && (modifierMask & InputEvent.CTRL_DOWN_MASK) == 0) {
3088
3089 if (!_selectionModel.getRowSelectionToggleMode()) {
3090 _selectionModel.clearSelection();
3091 } else {
3092 _selectionModel.clearIntervalSelection();
3093 _selectionModel.clearRelationSelection();
3094 }
3095 }
3096
3097
3098
3099
3100
3101 if (!isPopupTrigger && _selectionModel.getMultipleSelectionAllowed() && _rectSelectionEnabled
3102 && (row == null || getTouchedInterval(row, x, y) == null)) {
3103 _selectionRect = new Rectangle(x, y, 0, 0);
3104 fireSelectionRectChanged();
3105 }
3106 nothingHitInDiagramArea = true;
3107 }
3108 }
3109 } else {
3110 if (_regionRectEnabled) {
3111 _regionSelection = new TBRect();
3112 JaretDate startDate = dateForCoord(x, y);
3113 _regionSelection.startDate = startDate;
3114 _regionSelection.endDate = startDate.copy();
3115 TimeBarRow row = rowForXY(x, y);
3116 _regionSelection.startRow = row;
3117 _regionSelection.endRow = row;
3118
3119 _regionStartDate = startDate.copy();
3120 _regionStartRow = row;
3121
3122 fireRegionRectChanged();
3123 }
3124 }
3125 } else if (_lineDraggingAllowed && hierarchyLineHit(x, y)) {
3126
3127 _hierarchyLineDragging = true;
3128 } else if (_lineDraggingAllowed && headerLineHit(x, y)) {
3129
3130 _headerLineDragging = true;
3131 } else if (_rowHeightDraggingAllowed && rowLineHit(x, y)) {
3132
3133 _heightDraggedRow = getRowByBottomLine(x, y);
3134 } else if (_yAxisRect.contains(x, y)) {
3135
3136 TimeBarRow row = rowForXY(x, y);
3137 handleRowSelection(row, modifierMask);
3138 } else if (_hierarchyRect.contains(x, y) && !isPopupTrigger) {
3139
3140 TimeBarRow row = rowForXY(x, y);
3141 if (row instanceof TimeBarNode) {
3142 TimeBarNode node = (TimeBarNode) row;
3143 if (_tbvi.isInToggleArea(node, x, y)) {
3144 _hierarchicalViewState.setExpanded(node, !_hierarchicalViewState.isExpanded(node));
3145 } else if (_tbvi.isInHierarchySelectionArea(node, x, y)) {
3146 handleRowSelection(row, modifierMask);
3147 }
3148 }
3149 } else if (_xAxisRect.contains(x, y)) {
3150
3151 TimeBarMarker marker = getMarkerForXY(x, y);
3152 if (marker != null && marker.isDraggable()) {
3153 _tbvi.setCursor(Cursor.MOVE_CURSOR);
3154 _draggedMarker = marker;
3155 _markerDragStart = marker.getDate().copy();
3156 fireMarkerDragStarted(marker);
3157 }
3158 }
3159 if (_markerDraggingInDiagramArea && _draggedMarker == null && nothingHitInDiagramArea) {
3160 TimeBarMarker marker = getMarkerForXY(x, y);
3161 if (marker != null && marker.isDraggable()) {
3162 _tbvi.setCursor(Cursor.MOVE_CURSOR);
3163 _draggedMarker = marker;
3164 _markerDragStart = marker.getDate().copy();
3165 fireMarkerDragStarted(marker);
3166 }
3167 }
3168 }
3169
3170
3171 protected int _lastRowSelectionIndex = -1;
3172
3173
3174
3175
3176
3177
3178
3179 private void handleRowSelection(TimeBarRow row, int modifierMask) {
3180 int rowIdx = _rowList.indexOf(row);
3181 if ((modifierMask & InputEvent.SHIFT_DOWN_MASK) != 0) {
3182 if (_lastRowSelectionIndex == -1) {
3183 _selectionModel.addSelectedRow(row);
3184 _lastRowSelectionIndex = rowIdx;
3185 } else {
3186 _selectionModel.setSelectedRow(row);
3187 setRowSelection(_lastRowSelectionIndex, rowIdx);
3188 }
3189 } else {
3190 if ((modifierMask & InputEvent.CTRL_DOWN_MASK) != 0 || _selectionModel.getRowSelectionToggleMode()) {
3191 if (!_selectionModel.isSelected(row)) {
3192 _selectionModel.addSelectedRow(row);
3193 _lastRowSelectionIndex = rowIdx;
3194 } else {
3195 _selectionModel.remSelectedRow(row);
3196 }
3197 } else if (!_selectionModel.getRowSelectionToggleMode()) {
3198 _selectionModel.setSelectedRow(row);
3199 _lastRowSelectionIndex = rowIdx;
3200 }
3201 }
3202 }
3203
3204
3205
3206
3207
3208
3209
3210 private void handleRelationSelection(List<IIntervalRelation> relations, int modifierMask) {
3211 IIntervalRelation relation = relations.get(0);
3212 if ((modifierMask & InputEvent.CTRL_DOWN_MASK) != 0) {
3213 if (!_selectionModel.isSelected(relation)) {
3214 _selectionModel.addSelectedRelation(relation);
3215 } else {
3216 _selectionModel.remSelectedRelation(relation);
3217 }
3218 } else {
3219 _selectionModel.setSelectedRelation(relation);
3220 }
3221 }
3222
3223
3224
3225
3226
3227
3228
3229 private void setRowSelection(int startIndex, int endIndex) {
3230 int start = Math.min(startIndex, endIndex);
3231 int end = Math.max(startIndex, endIndex);
3232 for (int i = start; i <= end; i++) {
3233 _selectionModel.addSelectedRow(_rowList.get(i));
3234 }
3235 }
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245 public void mouseReleased(int x, int y, boolean isPopupTrigger, int modifierMask) {
3246 if (_headerLineDragging || _hierarchyLineDragging || _heightDraggedRow != null) {
3247 _headerLineDragging = false;
3248 _hierarchyLineDragging = false;
3249 _heightDraggedRow = null;
3250 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3251 _tbvi.repaint();
3252 }
3253 if (_draggedMarker != null) {
3254 TimeBarMarker marker = _draggedMarker;
3255 _draggedMarker = null;
3256 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3257
3258 _tbvi.repaint();
3259 fireMarkerDragStopped(marker);
3260 }
3261 if (_selectionRect != null) {
3262
3263
3264 _selectionRect = null;
3265 if (_lastSelRect != null) {
3266 _tbvi.repaint(_lastSelRect.x, _lastSelRect.y, _lastSelRect.width + 1, _lastSelRect.height + 1);
3267 }
3268 fireSelectionRectClosed();
3269 } else {
3270 if (!isPopupTrigger && (modifierMask & InputEvent.CTRL_DOWN_MASK) == 0 && _diagramRect.contains(x, y)) {
3271 TimeBarRow row = rowForXY(x, y);
3272 if (row != null) {
3273 Interval interval = intervalAt(row, x, y);
3274 if (interval != null) {
3275 _selectionModel.setSelectedInterval(interval);
3276 }
3277 }
3278 }
3279 }
3280 if (_changingInterval != null) {
3281
3282 fireIntervalChanged(_intervalDraggedRow, _changingInterval, _originalInterval.getBegin(), _originalInterval
3283 .getEnd());
3284 _changingInterval = null;
3285 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3286
3287 if (_dragAllSelectedIntervals && _draggedIntervals != null) {
3288 for (int i = 0; i < _draggedIntervals.size(); i++) {
3289 fireIntervalChanged(_draggedIntervalsRows.get(i), _draggedIntervals.get(i), _originalIntervals.get(
3290 i).getBegin(), _originalIntervals.get(i).getEnd());
3291 }
3292 _originalIntervals = null;
3293 _draggedIntervals = null;
3294 _draggedIntervalsRows = null;
3295 }
3296
3297 }
3298
3299
3300 if (isPopupTrigger) {
3301 TimeBarRow row = rowForXY(x, y);
3302 _ctxCoordinate = new Point(x, y);
3303 _ctxRow = row;
3304 _ctxDate = dateForCoord(x, y);
3305 if (_hierarchyRect.contains(x, y)) {
3306 _tbvi.displayHierarchyContextMenu(row, x, y);
3307 } else if (_yAxisRect.contains(x, y)) {
3308 _tbvi.displayHeaderContextMenu(row, x, y);
3309 } else if (_titleRect.contains(x, y)) {
3310 _tbvi.displayTitleContextMenu(x, y);
3311 } else if (_xAxisRect.contains(x, y)) {
3312 _tbvi.displayTimeScaleContextMenu(x, y);
3313 } else if (_diagramRect.contains(x, y)) {
3314 Interval interval = intervalAt(row, x, y);
3315
3316 if (interval != null && (_intervalFilter == null || _intervalFilter.isInResult(interval))) {
3317
3318 if (!_selectionModel.isSelected(interval)) {
3319 _selectionModel.setSelectedInterval(interval);
3320 }_tbvi.displayIntervalContextMenu(interval, x, y);
3321 } else {
3322 _tbvi.displayBodyContextMenu(x, y);
3323 }
3324 }
3325 }
3326
3327 }
3328
3329
3330
3331
3332 private void cancelDrag() {
3333 if (_draggedMarker != null) {
3334
3335 _draggedMarker.setDate(_markerDragStart);
3336 _draggedMarker = null;
3337 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3338 _tbvi.repaint();
3339 } else if (_changingInterval != null && _draggedInterval) {
3340
3341 _changingInterval.setBegin(_originalInterval.getBegin());
3342 _changingInterval.setEnd(_originalInterval.getEnd());
3343
3344
3345 fireIntervalChangeCancelled(_intervalDraggedRow, _changingInterval);
3346
3347 _changingInterval = null;
3348 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3349
3350 if (_dragAllSelectedIntervals && _draggedIntervals != null) {
3351 for (int i = 0; i < _draggedIntervals.size(); i++) {
3352 Interval orig = _originalIntervals.get(i);
3353 Interval changing = _draggedIntervals.get(i);
3354 TimeBarRow row = _draggedIntervalsRows.get(i);
3355 changing.setBegin(orig.getBegin());
3356 changing.setEnd(orig.getEnd());
3357 fireIntervalChangeCancelled(row, changing);
3358 }
3359 }
3360
3361 } else if (_changingInterval != null && !_draggedInterval) {
3362
3363 _changingInterval.setBegin(_originalInterval.getBegin());
3364 _changingInterval.setEnd(_originalInterval.getEnd());
3365
3366
3367 fireIntervalChangeCancelled(_intervalDraggedRow, _changingInterval);
3368
3369 _changingInterval = null;
3370 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
3371 }
3372
3373 }
3374
3375
3376 protected Point _ctxCoordinate;
3377
3378 protected TimeBarRow _ctxRow;
3379
3380 protected JaretDate _ctxDate;
3381
3382
3383
3384
3385
3386
3387 public Point getCtxCoordinate() {
3388 return _ctxCoordinate;
3389 }
3390
3391
3392
3393
3394
3395
3396 public TimeBarRow getCtxRow() {
3397 return _ctxRow;
3398 }
3399
3400
3401
3402
3403
3404
3405
3406 public Pair<TimeBarRow, JaretDate> getPopUpInformation() {
3407 Pair<TimeBarRow, JaretDate> result = new Pair<TimeBarRow, JaretDate>(_ctxRow, _ctxDate);
3408 return result;
3409 }
3410
3411
3412
3413
3414
3415
3416
3417
3418 protected Interval _originalInterval;
3419
3420
3421 protected List<Interval> _originalIntervals;
3422
3423
3424 protected List<Interval> _draggedIntervals;
3425
3426 protected List<TimeBarRow> _draggedIntervalsRows;
3427
3428
3429 protected int _startIntervalDragX;
3430
3431
3432 protected JaretDate _startIntervalDragDate = null;
3433
3434
3435 protected JaretDate _lastDragDate;
3436
3437
3438 protected JaretDate _markerDragStart;
3439
3440
3441 protected TimeBarRow _intervalDraggedRow;
3442
3443
3444 protected int _scrolledlastDrag;
3445
3446
3447 protected double _lastGridSnapDifference = 0;
3448
3449 protected List<Double> _lastGridSnapDifferences;
3450
3451 protected int _lastPressedX;
3452 protected int _lastPressedY;
3453
3454
3455
3456
3457
3458
3459
3460 public void mouseDragged(int x, int y, int modifierMask) {
3461
3462 Point coord = limitCoord(x, y);
3463 JaretDate xdate = dateForXY(coord.x, coord.y);
3464
3465 boolean horizontal = _orientation == Orientation.HORIZONTAL;
3466 if (_draggedMarker != null) {
3467
3468 _draggedMarker.setDate(xdate);
3469 if (_autoscroll) {
3470 scrollDateToVisible(xdate);
3471 }
3472 } else if (_changingInterval != null && _draggedInterval) {
3473 dragInterval(_originalInterval, _draggedInterval, _lastDragDate, xdate, x, y, _dragAllSelectedIntervals);
3474 } else if (_changingInterval != null && !_draggedInterval) {
3475
3476 double diffSeconds = -1.0 * _startIntervalDragDate.diffMilliSeconds(xdate) / 1000.0;
3477
3478 diffSeconds = calcGridSnap(diffSeconds, 0, _intervalDraggedRow, _changingInterval, -1);
3479 if (_draggedIntervalEdgeLeft) {
3480 JaretDate newBegin = _originalInterval.getBegin().copy();
3481 newBegin.advanceSeconds(diffSeconds);
3482
3483 boolean allowed = isNewBeginAllowed(_intervalDraggedRow, _changingInterval, newBegin);
3484 if (allowed) {
3485 _changingInterval.setBegin(newBegin);
3486 if (_autoscroll) {
3487 scrollDateToVisible(newBegin);
3488 }
3489 }
3490 } else {
3491 JaretDate newEnd = _originalInterval.getEnd().copy();
3492 newEnd.advanceSeconds(diffSeconds);
3493
3494 boolean allowed = isNewEndAllowed(_intervalDraggedRow, _changingInterval, newEnd);
3495 if (allowed) {
3496 _changingInterval.setEnd(newEnd);
3497 if (_autoscroll) {
3498 scrollDateToVisible(newEnd);
3499 }
3500 }
3501 }
3502
3503 fireIntervalIntermediateChange(_intervalDraggedRow, _changingInterval, _originalInterval.getBegin(),
3504 _originalInterval.getEnd());
3505 } else if (_selectionRect != null) {
3506
3507 _selectionRect.width = x - _selectionRect.x;
3508 _selectionRect.height = y - _selectionRect.y;
3509 if (_lastSelRect != null) {
3510 rectRepaint(_lastSelRect);
3511 }
3512 Rectangle curSelRect = normalizeRectangle(_selectionRect);
3513 selectIntervals(curSelRect);
3514 rectRepaint(curSelRect);
3515 fireSelectionRectChanged();
3516 } else if (_regionSelection != null && (modifierMask & InputEvent.SHIFT_DOWN_MASK) != 0) {
3517
3518 if (_lastRegionSelection != null) {
3519 _tbvi.repaint(calcRect(_lastRegionSelection));
3520 }
3521 JaretDate curDate = dateForCoord(x, y);
3522 TimeBarRow row = rowForXY(x, y);
3523
3524
3525 if (curDate.compareTo(_regionStartDate) > 0) {
3526 _regionSelection.startDate = _regionStartDate;
3527 _regionSelection.endDate = curDate;
3528 } else {
3529 _regionSelection.endDate = _regionStartDate;
3530 _regionSelection.startDate = curDate;
3531 }
3532
3533
3534 if (row != null) {
3535 int startRowIdx = _rowList.indexOf(_regionStartRow);
3536 int curIdx = _rowList.indexOf(row);
3537 if (startRowIdx <= curIdx) {
3538 _regionSelection.startRow = _regionStartRow;
3539 _regionSelection.endRow = row;
3540 } else {
3541 _regionSelection.endRow = _regionStartRow;
3542 _regionSelection.startRow = row;
3543 }
3544 }
3545 _tbvi.repaint(calcRect(_regionSelection));
3546
3547 _lastRegionSelection = _regionSelection;
3548
3549 fireRegionRectChanged();
3550 } else if (_hierarchyLineDragging) {
3551 int value = horizontal ? x : y;
3552 if (value > MIN_DRAG_HIERARCHY_WIDTH) {
3553 setHierarchyWidth(value);
3554 }
3555 } else if (_headerLineDragging) {
3556 int value = (horizontal ? x : y) - _hierarchyWidth;
3557 if (value > MIN_DRAG_HEADER_WIDTH) {
3558 setYAxisWidth(value);
3559 }
3560 } else if (_heightDraggedRow != null) {
3561 int beginCoord = yForRow(_heightDraggedRow);
3562 int value = (horizontal ? y : x) - beginCoord;
3563 if (value > MIN_ROW_HEIGHT) {
3564 _timeBarViewState.setRowHeight(_heightDraggedRow, value);
3565 }
3566 } else {
3567
3568
3569
3570 TimeBarRow row = rowForXY(x, y);
3571 if (row != null) {
3572 Interval interval = getTouchedInterval(row, _lastPressedX, _lastPressedY);
3573 if (interval != null && isResizingAllowed(row, interval)) {
3574 Rectangle rect = getIntervalBounds(row, interval);
3575 int diff = horizontal ? Math.abs(_lastPressedX - rect.x) : Math.abs(_lastPressedY - rect.y);
3576 if (diff <= _selectionDelta) {
3577
3578 _draggedIntervalEdgeLeft = true;
3579 _tbvi.setCursor(horizontal ? Cursor.E_RESIZE_CURSOR : Cursor.N_RESIZE_CURSOR);
3580 } else {
3581
3582 _draggedIntervalEdgeLeft = false;
3583 _tbvi.setCursor(horizontal ? Cursor.W_RESIZE_CURSOR : Cursor.S_RESIZE_CURSOR);
3584 }
3585 _changingInterval = interval;
3586 _draggedInterval = false;
3587 _originalInterval = new IntervalImpl();
3588 _originalInterval.setBegin(interval.getBegin());
3589 _originalInterval.setEnd(interval.getEnd());
3590 _startIntervalDragDate = xdate;
3591 _intervalDraggedRow = row;
3592
3593 fireIntervalChangeStarted(_intervalDraggedRow, _changingInterval);
3594 }
3595 }
3596
3597 if (_changingInterval == null) {
3598 List<Interval> intervals = getIntervalsAt(x, y);
3599 if (intervals.size() == 1) {
3600 Interval interval = intervals.get(0);
3601 boolean shiftAllowed = isShiftingAllowed(row, interval);
3602
3603
3604
3605
3606 if (_dragAllSelectedIntervals && shiftAllowed) {
3607 int size = getSelectionModel().getSelectedIntervals().size();
3608 _originalIntervals = new ArrayList<Interval>(size);
3609 _draggedIntervals = new ArrayList<Interval>(size);
3610 _draggedIntervalsRows = new ArrayList<TimeBarRow>(size);
3611 _lastGridSnapDifferences = new ArrayList<Double>(size);
3612 for (int i = 0; i < size; i++) {
3613 _lastGridSnapDifferences.add(0.0);
3614 }
3615
3616 for (Interval selInterval : getSelectionModel().getSelectedIntervals()) {
3617 TimeBarRow selIntervalRow = getModel().getRowForInterval(selInterval);
3618 if (!isShiftingAllowed(selIntervalRow, interval)) {
3619 shiftAllowed = false;
3620 break;
3621 }
3622 if (!selInterval.equals(interval)) {
3623 Interval copy = new IntervalImpl();
3624 copy.setBegin(selInterval.getBegin().copy());
3625 copy.setEnd(selInterval.getEnd().copy());
3626 _originalIntervals.add(copy);
3627 _draggedIntervals.add(selInterval);
3628 _draggedIntervalsRows.add(selIntervalRow);
3629 }
3630
3631 }
3632 }
3633
3634 if (shiftAllowed) {
3635 _changingInterval = interval;
3636 _draggedInterval = true;
3637 _originalInterval = new IntervalImpl();
3638 _originalInterval.setBegin(interval.getBegin());
3639 _originalInterval.setEnd(interval.getEnd());
3640 _startIntervalDragDate = xdate;
3641 _intervalDraggedRow = row;
3642 _tbvi.setCursor(Cursor.MOVE_CURSOR);
3643
3644
3645 fireIntervalChangeStarted(_intervalDraggedRow, _changingInterval);
3646 if (_draggedIntervals != null && _draggedIntervals.size() > 0) {
3647 for (int i = 0; i < _draggedIntervals.size(); i++) {
3648 fireIntervalChangeStarted(_draggedIntervalsRows.get(i), _draggedIntervals.get(i));
3649 }
3650 }
3651 }
3652 }
3653 }
3654 }
3655 _lastDragDate = xdate;
3656 }
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670 private void dragInterval(Interval originalInterval, boolean draggedInterval, JaretDate lastDragDate,
3671 JaretDate currentDragDate, int x, int y, boolean dragSelected) {
3672 boolean horizontal = _orientation == Orientation.HORIZONTAL;
3673
3674
3675 double deltaSeconds = currentDragDate.diffMilliSeconds(lastDragDate) / 1000.0;
3676
3677 deltaSeconds += _scrolledlastDrag;
3678
3679
3680
3681
3682 if (horizontal) {
3683 if (x > _diagramRect.x + _diagramRect.width) {
3684 deltaSeconds = secsForPixelDiff(_autoscrollDelta);
3685 } else if (x < _diagramRect.x) {
3686 deltaSeconds = -secsForPixelDiff(_autoscrollDelta);
3687 }
3688 } else {
3689 if (y > _diagramRect.y + _diagramRect.height) {
3690 deltaSeconds = secsForPixelDiff(_autoscrollDelta);
3691 } else if (y < _diagramRect.y) {
3692 deltaSeconds = -secsForPixelDiff(_autoscrollDelta);
3693 }
3694 }
3695
3696 double deltaSecondsSnap = calcGridSnap(deltaSeconds, _lastGridSnapDifference, _intervalDraggedRow,
3697 _changingInterval, -1);
3698
3699 JaretDate newBegin = _changingInterval.getBegin().copy();
3700 newBegin.advanceSeconds(deltaSecondsSnap);
3701 JaretDate newEnd = _changingInterval.getEnd().copy();
3702 newEnd.advanceSeconds(deltaSecondsSnap);
3703
3704 List<Double> deltas = new ArrayList<Double>();
3705
3706 boolean allowed = isShiftingAllowed(_intervalDraggedRow, _changingInterval, newBegin);
3707 if (_dragAllSelectedIntervals && allowed && _draggedIntervals != null) {
3708 for (int i = 0; i < _draggedIntervals.size(); i++) {
3709 deltaSecondsSnap = calcGridSnap(deltaSeconds, _lastGridSnapDifferences.get(i), _draggedIntervalsRows
3710 .get(i), _draggedIntervals.get(i), i);
3711 deltas.add(deltaSecondsSnap);
3712 JaretDate nb = _draggedIntervals.get(i).getBegin().copy().advanceSeconds(deltaSecondsSnap);
3713 allowed = allowed & isShiftingAllowed(_draggedIntervalsRows.get(i), _draggedIntervals.get(i), nb);
3714 }
3715 }
3716
3717 if (allowed) {
3718
3719
3720 if (deltaSecondsSnap > 0) {
3721 _changingInterval.setEnd(newEnd);
3722 _changingInterval.setBegin(newBegin);
3723 } else {
3724 _changingInterval.setBegin(newBegin);
3725 _changingInterval.setEnd(newEnd);
3726 }
3727 if (_autoscroll && _lastDragDate != null) {
3728 if (deltaSeconds < 0) {
3729 int scrolledSeconds = scrollDateToVisible(newBegin);
3730 _scrolledlastDrag = scrolledSeconds;
3731 } else {
3732 int scrolledSeconds = scrollDateToVisible(newEnd);
3733 _scrolledlastDrag = scrolledSeconds;
3734 }
3735 }
3736
3737 if (_dragAllSelectedIntervals) {
3738 for (int i = 0; i < _draggedIntervals.size(); i++) {
3739 Interval di = _draggedIntervals.get(i);
3740 double deltaSnap = deltas.get(i);
3741 JaretDate nb = di.getBegin().copy().advanceSeconds(deltaSnap);
3742 JaretDate ne = di.getEnd().copy().advanceSeconds(deltaSnap);
3743 di.setBegin(nb);
3744 di.setEnd(ne);
3745 }
3746 }
3747
3748
3749 fireIntervalIntermediateChange(_intervalDraggedRow, _changingInterval, _originalInterval.getBegin(),
3750 _originalInterval.getEnd());
3751 if (_dragAllSelectedIntervals) {
3752 for (int i = 0; i < _draggedIntervals.size(); i++) {
3753 fireIntervalIntermediateChange(_draggedIntervalsRows.get(i), _draggedIntervals.get(i),
3754 _originalIntervals.get(i).getBegin(), _originalIntervals.get(i).getEnd());
3755 }
3756 }
3757 }
3758
3759 }
3760
3761
3762
3763
3764
3765
3766
3767 private int secsForPixelDiff(int pixDif) {
3768 if (_milliAccuracy) {
3769 int diffSec = (int) ((double) pixDif / _pixelPerSeconds);
3770 return diffSec;
3771 } else {
3772 int diffSec = (int) ((double) pixDif / _pixelPerSeconds);
3773 return diffSec;
3774 }
3775
3776 }
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786 private Point limitCoord(int x, int y) {
3787 int limit = _autoscrollDelta;
3788 if (x < _diagramRect.x - limit) {
3789 x = _diagramRect.x - limit;
3790 } else if (x > _diagramRect.x + _diagramRect.width + limit) {
3791 x = _diagramRect.x + _diagramRect.width + limit;
3792 }
3793 if (y < _diagramRect.y - limit) {
3794 y = _diagramRect.y - limit;
3795 } else if (y > _diagramRect.y + _diagramRect.height + limit) {
3796 x = _diagramRect.y + _diagramRect.height + limit;
3797 }
3798
3799 return new Point(x, y);
3800 }
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815 private double calcGridSnap(double diffSeconds, double additionalDelta, TimeBarRow row, Interval interval, int index) {
3816 if (_intervalModificators != null && _intervalModificators.size() > 0) {
3817 IntervalModificator modificator = null;
3818 for (IntervalModificator m : _intervalModificators) {
3819 if (m.isApplicable(row, interval)) {
3820 modificator = m;
3821 break;
3822 }
3823 }
3824 if (modificator != null) {
3825 double newVal;
3826 double gridsnap = -1;
3827
3828 if (modificator instanceof IIntervalModificator) {
3829 gridsnap = ((IIntervalModificator) modificator).getSecondGridSnap(row, interval);
3830 }
3831
3832 if (gridsnap < 0) {
3833 gridsnap = modificator.getSecondGridSnap();
3834 }
3835 if (gridsnap < 0) {
3836 return diffSeconds;
3837 }
3838 diffSeconds += additionalDelta;
3839 if (Math.abs(diffSeconds % gridsnap) > gridsnap / 2) {
3840 double off;
3841 if (diffSeconds < 0) {
3842 off = -gridsnap;
3843 } else {
3844 off = gridsnap;
3845 }
3846 newVal = diffSeconds - diffSeconds % gridsnap + off;
3847 } else {
3848 newVal = diffSeconds - diffSeconds % gridsnap;
3849 }
3850 if (index == -1) {
3851 _lastGridSnapDifference = diffSeconds - newVal;
3852 } else {
3853 _lastGridSnapDifferences.set(index, diffSeconds - newVal);
3854 }
3855 return newVal;
3856 }
3857 }
3858 return diffSeconds;
3859
3860 }
3861
3862
3863
3864
3865
3866
3867
3868
3869 private boolean isShiftingAllowed(TimeBarRow row, Interval interval) {
3870 if (_intervalModificators == null || _intervalModificators.size() == 0) {
3871 return false;
3872 }
3873 boolean allowed = true;
3874
3875 for (IntervalModificator modificator : _intervalModificators) {
3876 allowed = allowed
3877 && (!modificator.isApplicable(row, interval) || modificator.isShiftingAllowed(row, interval));
3878 }
3879 return allowed;
3880 }
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890 private boolean isShiftingAllowed(TimeBarRow row, Interval interval, JaretDate newBegin) {
3891 if (_intervalModificators == null || _intervalModificators.size() == 0) {
3892 return false;
3893 }
3894 boolean allowed = true;
3895
3896 for (IntervalModificator modificator : _intervalModificators) {
3897 allowed = allowed
3898 && (!modificator.isApplicable(row, interval) || modificator.shiftAllowed(row, interval, newBegin));
3899 }
3900 return allowed;
3901 }
3902
3903
3904
3905
3906
3907
3908
3909
3910 private boolean isResizingAllowed(TimeBarRow row, Interval interval) {
3911 if (_intervalModificators == null || _intervalModificators.size() == 0) {
3912 return false;
3913 }
3914 boolean result = true;
3915 if (_intervalModificators != null) {
3916 for (IntervalModificator modificator : _intervalModificators) {
3917 result = result
3918 && (!modificator.isApplicable(row, interval) || modificator.isSizingAllowed(row, interval));
3919 }
3920 }
3921 return result;
3922 }
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932 private boolean isNewBeginAllowed(TimeBarRow row, Interval interval, JaretDate newBegin) {
3933 boolean allowed = true;
3934 for (IntervalModificator modificator : _intervalModificators) {
3935 allowed = allowed
3936 && (!modificator.isApplicable(row, interval) || modificator
3937 .newBeginAllowed(row, interval, newBegin));
3938 }
3939 return allowed;
3940 }
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950 private boolean isNewEndAllowed(TimeBarRow row, Interval interval, JaretDate newEnd) {
3951 boolean allowed = true;
3952 for (IntervalModificator modificator : _intervalModificators) {
3953 allowed = allowed
3954 && (!modificator.isApplicable(row, interval) || modificator.newEndAllowed(row, interval, newEnd));
3955 }
3956 return allowed;
3957 }
3958
3959
3960
3961
3962
3963
3964 private void rectRepaint(Rectangle rect) {
3965 _tbvi.repaint(rect.x, rect.y, rect.width, 1);
3966 _tbvi.repaint(rect.x, rect.y + rect.height, rect.width, 1);
3967 _tbvi.repaint(rect.x, rect.y, 1, rect.height);
3968 _tbvi.repaint(rect.x + rect.width, rect.y, 1, rect.height);
3969 }
3970
3971
3972
3973
3974
3975
3976
3977 public void mouseMoved(int x, int y) {
3978 boolean horizontal = _orientation == Orientation.HORIZONTAL;
3979 boolean nothingHitInDiagramArea = true;
3980 if (_lineDraggingAllowed && (hierarchyLineHit(x, y) || headerLineHit(x, y))) {
3981 _tbvi.setCursor(Cursor.HAND_CURSOR);
3982 nothingHitInDiagramArea = false;
3983 } else if (_rowHeightDraggingAllowed && rowLineHit(x, y)) {
3984 _tbvi.setCursor(Cursor.HAND_CURSOR);
3985 nothingHitInDiagramArea = false;
3986 } else if (_diagramRect != null && _diagramRect.contains(x, y)) {
3987
3988
3989
3990 TimeBarRow row = rowForXY(x, y);
3991 if (row != null) {
3992 Interval interval = getTouchedInterval(row, x, y);
3993 if (interval != null && isResizingAllowed(row, interval)) {
3994 JaretDate d = dateForXY(x, y);
3995 long eastDiff = Math.abs(d.diffMilliSeconds(interval.getBegin()));
3996 long westDiff = Math.abs(d.diffMilliSeconds(interval.getEnd()));
3997 if (eastDiff < westDiff) {
3998 _tbvi.setCursor(horizontal ? Cursor.E_RESIZE_CURSOR : Cursor.N_RESIZE_CURSOR);
3999 } else {
4000 _tbvi.setCursor(horizontal ? Cursor.W_RESIZE_CURSOR : Cursor.S_RESIZE_CURSOR);
4001 }
4002 nothingHitInDiagramArea = false;
4003 } else {
4004 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
4005 }
4006 }
4007 } else {
4008 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
4009 }
4010
4011
4012 if (nothingHitInDiagramArea
4013 && ((_xAxisRect != null && _xAxisRect.contains(x, y)) || _markerDraggingInDiagramArea)) {
4014 TimeBarMarker marker = getMarkerForXY(x, y);
4015 if (marker != null) {
4016 _tbvi.setCursor(Cursor.HAND_CURSOR);
4017 } else {
4018 _tbvi.setCursor(Cursor.DEFAULT_CURSOR);
4019 }
4020 }
4021
4022 }
4023
4024
4025
4026
4027
4028
4029
4030
4031 private boolean hierarchyLineHit(int x, int y) {
4032 if (_orientation == Orientation.HORIZONTAL) {
4033 return (_hierarchyWidth > 0 && Math.abs(_hierarchyWidth - x) < _selectionDelta);
4034 } else {
4035 return (_hierarchyWidth > 0 && Math.abs(_hierarchyWidth - y) < _selectionDelta);
4036 }
4037 }
4038
4039
4040
4041
4042
4043
4044
4045
4046 public boolean rowLineHit(int x, int y) {
4047 if (_rowList.size() > 0 && (_yAxisRect.contains(x, y) || _hierarchyRect.contains(x, y))) {
4048 int coord;
4049 int max;
4050 if (_orientation == Orientation.HORIZONTAL) {
4051 coord = y;
4052 coord -= _yAxisRect.y;
4053 max = _yAxisRect.height;
4054 } else {
4055 coord = x;
4056 coord -= _yAxisRect.x;
4057 max = _yAxisRect.width;
4058 }
4059 TimeBarRow row = getRow(_firstRow);
4060 int idx = _firstRow;
4061 int endCoord = _timeBarViewState.getRowHeight(row) - _firstRowPixelOffset;
4062
4063 while (endCoord < max && idx < _rowList.size()) {
4064 if (Math.abs(endCoord - coord) < _selectionDelta) {
4065 return true;
4066 }
4067 idx++;
4068 if (idx > _rowList.size() - 1) {
4069 break;
4070 }
4071 row = getRow(idx);
4072 endCoord += _timeBarViewState.getRowHeight(row);
4073 }
4074 }
4075 return false;
4076 }
4077
4078
4079
4080
4081
4082
4083
4084
4085 private TimeBarRow getRowByBottomLine(int x, int y) {
4086 if (_diagramRect.contains(x, y) || _yAxisRect.contains(x, y) || _hierarchyRect.contains(x, y)) {
4087 int coord;
4088 int max;
4089 if (_orientation == Orientation.HORIZONTAL) {
4090 coord = y;
4091 coord -= _diagramRect.y;
4092 max = _diagramRect.height;
4093 } else {
4094 coord = x;
4095 coord -= _diagramRect.x;
4096 max = _diagramRect.width;
4097 }
4098 TimeBarRow row = getRow(_firstRow);
4099 int idx = _firstRow;
4100 int endCoord = _timeBarViewState.getRowHeight(row) - _firstRowPixelOffset;
4101
4102 while (endCoord < max) {
4103 if (Math.abs(endCoord - coord) < _selectionDelta) {
4104 return row;
4105 }
4106 idx++;
4107 row = getRow(idx);
4108 endCoord += _timeBarViewState.getRowHeight(row);
4109 }
4110 }
4111 return null;
4112 }
4113
4114
4115
4116
4117
4118
4119
4120
4121 private boolean headerLineHit(int x, int y) {
4122 if (_orientation == Orientation.HORIZONTAL) {
4123 return (_yAxisWidth > 0 && Math.abs(_hierarchyWidth + _yAxisWidth - x) < _selectionDelta);
4124 } else {
4125 return (_yAxisWidth > 0 && Math.abs(_hierarchyWidth + _yAxisWidth - y) < _selectionDelta);
4126 }
4127 }
4128
4129
4130
4131
4132
4133
4134
4135 private Rectangle normalizeRectangle(Rectangle rect) {
4136 int x = Math.min(rect.x, rect.x + rect.width);
4137 int y = Math.min(rect.y, rect.y + rect.height);
4138 int width = Math.abs(rect.width);
4139 int height = Math.abs(rect.height);
4140 return new Rectangle(x, y, width, height);
4141 }
4142
4143
4144
4145
4146
4147
4148
4149
4150 public void selectIntervals(Rectangle curSelRect) {
4151
4152 List<Interval> intervals = getIntervals(curSelRect);
4153
4154
4155 for (Interval interval : intervals) {
4156 if (!_selectionModel.getSelectedIntervals().contains(interval)) {
4157 _selectionModel.addSelectedInterval(interval);
4158 }
4159 }
4160 List<Interval> selection = new ArrayList<Interval>();
4161 selection.addAll(_selectionModel.getSelectedIntervals());
4162
4163 for (Interval interval : selection) {
4164 if (!intervals.contains(interval)) {
4165 _selectionModel.remSelectedInterval(interval);
4166 }
4167 }
4168 }
4169
4170
4171
4172
4173
4174
4175
4176 public List<Interval> getIntervals(Rectangle curSelRect) {
4177 List<Interval> result = new ArrayList<Interval>();
4178 boolean horizontal = _orientation == Orientation.HORIZONTAL;
4179
4180 List<TimeBarRow> rows = horizontal ? getRows(curSelRect.y, curSelRect.y + curSelRect.height) : getRows(
4181 curSelRect.x, curSelRect.x + curSelRect.width);
4182
4183 JaretDate begin = horizontal ? dateForCoord(curSelRect.x) : dateForCoord(curSelRect.y);
4184 JaretDate end = horizontal ? dateForCoord(curSelRect.x + curSelRect.width) : dateForCoord(curSelRect.y
4185 + curSelRect.height);
4186
4187
4188 for (TimeBarRow row : rows) {
4189 List<Interval> intervals = row.getIntervals(begin, end);
4190 for (Interval interval : intervals) {
4191 boolean overlapping = getTimeBarViewState().getDrawOverlapping(row) ? false : _overlapStrategy
4192 .getOverlapInfo(row, interval).overlappingCount > 0;
4193 Rectangle intervalRect = getIntervalBounds(row, interval);
4194
4195
4196 Rectangle containingRect = _tbvi.timeBarContainingRect(interval, intervalRect, overlapping);
4197 if (containingRect == null) {
4198 containingRect = intervalRect;
4199 }
4200
4201 if (curSelRect.contains(containingRect)) {
4202 result.add(interval);
4203 }
4204 }
4205 }
4206
4207 return result;
4208 }
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220 private Interval getTouchedInterval(TimeBarRow row, int x, int y) {
4221
4222 List<Interval> intervals = row.getIntervals(getStartDate(), getEndDate());
4223 List<Interval> candidates = new ArrayList<Interval>(5);
4224 List<Rectangle> candidateRects = new ArrayList<Rectangle>(5);
4225 for (Interval interval : intervals) {
4226 Rectangle intervalRect = getIntervalBounds(row, interval);
4227 if (_orientation == Orientation.HORIZONTAL) {
4228 if (y >= intervalRect.y && y <= intervalRect.y + intervalRect.height) {
4229 if (Math.abs(x - intervalRect.x) <= _selectionDelta) {
4230 candidates.add(interval);
4231 candidateRects.add(intervalRect);
4232 } else if (Math.abs(intervalRect.x + intervalRect.width - x) <= _selectionDelta) {
4233 candidates.add(interval);
4234 candidateRects.add(intervalRect);
4235 }
4236 }
4237 } else {
4238 if (x >= intervalRect.x && x <= intervalRect.x + intervalRect.width) {
4239 if (Math.abs(y - intervalRect.y) <= _selectionDelta) {
4240 candidates.add(interval);
4241 candidateRects.add(intervalRect);
4242 } else if (Math.abs(intervalRect.y + intervalRect.height - y) <= _selectionDelta) {
4243 candidates.add(interval);
4244 candidateRects.add(intervalRect);
4245 }
4246 }
4247 }
4248 }
4249
4250 if (candidates.size() == 0) {
4251 return null;
4252 }
4253 if (candidates.size() == 1) {
4254 return candidates.get(0);
4255 }
4256
4257 for (int i = 0; i < candidates.size(); i++) {
4258 Interval interval = candidates.get(i);
4259 Rectangle rect = candidateRects.get(i);
4260 if (rect.contains(x, y)) {
4261 return interval;
4262 }
4263 }
4264
4265
4266 return candidates.get(0);
4267
4268 }
4269
4270
4271
4272
4273
4274
4275
4276
4277 private List<TimeBarRow> getRows(int c1, int c2) {
4278 List<TimeBarRow> result = new ArrayList<TimeBarRow>();
4279
4280 for (int r = _firstRow; r <= _firstRow + getRowsDisplayed() && r < getRowCount(); r++) {
4281
4282
4283
4284 int startC = yForRow(getRow(r));
4285 int endC = startC + _timeBarViewState.getRowHeight(getRow(r));
4286 if ((startC >= c1 && startC <= c2) || (endC >= c1 && endC <= c2) || (c1 >= startC && c1 <= endC)) {
4287 result.add(getRow(r));
4288 }
4289 }
4290 return result;
4291 }
4292
4293
4294
4295
4296 public boolean getDrawRowGrid() {
4297 return _drawRowGrid;
4298 }
4299
4300
4301
4302
4303 public void setDrawRowGrid(boolean drawRowGrid) {
4304 _drawRowGrid = drawRowGrid;
4305 if (_tbvi != null) {
4306 _tbvi.repaint();
4307 }
4308 }
4309
4310
4311
4312
4313
4314
4315 public void highlightRow(int y) {
4316 TimeBarRow row = rowForY(y);
4317 highlightRow(row);
4318 }
4319
4320
4321
4322
4323
4324
4325 public void highlightRow(TimeBarRow row) {
4326 if (row != _highlightedRow) {
4327 TimeBarRow oldRow = _highlightedRow;
4328 _highlightedRow = row;
4329 _tbvi.repaint(getRowBounds(_highlightedRow));
4330 if (oldRow != null) {
4331
4332 _tbvi.repaint(getRowBounds(oldRow));
4333 }
4334 }
4335 }
4336
4337
4338
4339
4340
4341 public void deHighlightRow() {
4342 if (_highlightedRow != null) {
4343 TimeBarRow row = _highlightedRow;
4344 _highlightedRow = null;
4345 _tbvi.repaint(getRowBounds(row));
4346 }
4347 }
4348
4349
4350
4351
4352
4353
4354 public TimeBarRow getHighlightedRow() {
4355 return _highlightedRow;
4356 }
4357
4358
4359
4360
4361
4362
4363 public TimeBarMarker getDraggedMarker() {
4364 return _draggedMarker;
4365 }
4366
4367
4368
4369
4370
4371
4372 public Rectangle getSelectionRect() {
4373 return _selectionRect;
4374 }
4375
4376
4377
4378
4379
4380
4381 public void setLastSelRect(Rectangle rect) {
4382 _lastSelRect = rect;
4383 }
4384
4385
4386
4387
4388
4389
4390 public Rectangle getLastSelRect() {
4391 return _lastSelRect;
4392 }
4393
4394
4395
4396
4397
4398
4399
4400
4401 public String getToolTipText(int x, int y) {
4402
4403 TimeBarMarker marker = getMarkerForXY(x, y);
4404 if (marker != null) {
4405 return marker.getDescription();
4406 }
4407
4408
4409 if (_diagramRect.contains(x, y)) {
4410 TimeBarRow row = rowForXY(x, y);
4411 if (row != null) {
4412
4413 String tooltip = null;
4414 List<Interval> intervals = getIntervalsAt(row, x, y);
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435 if (intervals.size() == 0) {
4436
4437 return _tbvi.getRelationTooltip(x, y);
4438 }
4439
4440 Interval interval;
4441 if (intervals.size() == 1) {
4442 interval = intervals.get(0);
4443 } else {
4444 interval = _intervalSelectionStrategy.selectInterval(intervals);
4445 }
4446 Rectangle intervalRect = getIntervalBounds(row, interval);
4447 boolean overlapping = getTimeBarViewState().getDrawOverlapping(row) ? false : _overlapStrategy
4448 .getOverlapInfo(row, interval).overlappingCount > 0;
4449 if (_tbvi.timeBarContains(interval, intervalRect, x - intervalRect.x, y - intervalRect.y, overlapping)) {
4450 tooltip = _tbvi.getIntervalToolTipText(interval, intervalRect, x - intervalRect.x, y
4451 - intervalRect.y);
4452 }
4453 return tooltip;
4454 }
4455 } else if (_hierarchyRect.contains(x, y)) {
4456
4457 TimeBarRow row = rowForXY(x, y);
4458 if (row instanceof TimeBarNode) {
4459 return _tbvi.getHierarchyToolTipText((TimeBarNode) row, x, y);
4460 } else {
4461
4462 return null;
4463 }
4464 } else if (_yAxisRect.contains(x, y)) {
4465
4466 return _tbvi.getHeaderToolTipText(rowForXY(x, y), x, y);
4467 } else if (_xAxisRect.contains(x, y)) {
4468
4469 return _tbvi.getTimeScaleToolTipText(x, y);
4470 }
4471 return null;
4472 }
4473
4474
4475
4476
4477
4478
4479
4480 public Rectangle getHeaderRect(TimeBarRow row) {
4481 if (!isRowDisplayed(row)) {
4482 return null;
4483 } else {
4484 if (_orientation.equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
4485 int y = yForRow(row);
4486 Rectangle rect = new Rectangle(_yAxisRect.x, y, _yAxisWidth, _timeBarViewState.getRowHeight(row));
4487 return rect;
4488 } else {
4489 int x = yForRow(row);
4490 Rectangle rect = new Rectangle(x, _yAxisRect.y, _timeBarViewState.getRowHeight(row), _yAxisWidth);
4491 return rect;
4492 }
4493 }
4494 }
4495
4496
4497
4498
4499
4500
4501
4502 public Rectangle getHierarchyRect(TimeBarRow row) {
4503 if (!isRowDisplayed(row)) {
4504 return null;
4505 } else {
4506 int y = yForRow(row);
4507 Rectangle rect = new Rectangle(_hierarchyRect.x, y, _hierarchyWidth, _timeBarViewState.getRowHeight(row));
4508 return rect;
4509 }
4510 }
4511
4512
4513
4514
4515
4516
4517 public String toString() {
4518 StringBuffer buf = new StringBuffer();
4519 buf.append("TimeBarViewerDelegate[");
4520 buf.append("Name:" + _name + ",");
4521 buf.append("StartDate:" + _startDate.toDisplayString() + ",");
4522 buf.append("MinDate:" + _minDate.toDisplayString() + ",");
4523 buf.append("MaxDate:" + _maxDate.toDisplayString() + ",");
4524
4525 buf.append("]");
4526 return buf.toString();
4527 }
4528
4529
4530
4531
4532
4533
4534 public void setName(String name) {
4535 _name = name;
4536 }
4537
4538
4539
4540
4541
4542
4543 public String getName() {
4544 return _name;
4545 }
4546
4547
4548
4549
4550
4551
4552
4553 public void setAutoscrollEnabled(boolean enableAutoscroll) {
4554 _autoscroll = enableAutoscroll;
4555 }
4556
4557
4558
4559
4560
4561
4562 public boolean isAutoscrollEnabled() {
4563 return _autoscroll;
4564 }
4565
4566
4567
4568
4569
4570
4571
4572 public int scrollDateToVisible(JaretDate date) {
4573 JaretDate enddate = getStartDate().copy();
4574 date = date.copy();
4575 JaretDate oldStartDate = getStartDate().copy();
4576 if (_milliAccuracy) {
4577 enddate.advanceMillis(getMilliSecondsDisplayed());
4578 if (date.compareTo(getStartDate()) < 0) {
4579 setStartDate(date);
4580 } else if (date.compareTo(enddate) > 0) {
4581 date.advanceMillis(-getMilliSecondsDisplayed());
4582 setStartDate(date);
4583 }
4584 } else {
4585 enddate.advanceSeconds(getSecondsDisplayed());
4586 if (date.compareTo(getStartDate()) < 0) {
4587 setStartDate(date);
4588 } else if (date.compareTo(enddate) > 0) {
4589 date.advanceSeconds(-getSecondsDisplayed());
4590 setStartDate(date);
4591 }
4592 }
4593 return oldStartDate.diffSeconds(getStartDate());
4594 }
4595
4596
4597
4598
4599
4600
4601 public void scrollRowToVisible(TimeBarRow row) {
4602 if (!isFiltered(row)) {
4603 int ridx = _rowList.indexOf(row);
4604 if (ridx == -1) {
4605 return;
4606 }
4607 if (ridx < _firstRow) {
4608 setFirstRow(ridx);
4609 } else if (ridx >= _firstRow + getRowsDisplayed()) {
4610 setLastRow(ridx);
4611 } else if (getTimeBarViewState().getUseVariableRowHeights() && ridx >= _firstRow + getRowsDisplayed() - 1) {
4612 setLastRow(ridx);
4613 }
4614 }
4615 }
4616
4617
4618
4619
4620
4621
4622
4623
4624 public void scrollIntervalToVisible(TimeBarRow row, Interval interval) {
4625
4626 scrollRowToVisible(row);
4627 if (_milliAccuracy) {
4628 if (interval.getBegin().compareTo(_startDate) < 0) {
4629 scrollDateToVisible(interval.getBegin());
4630 } else if (interval.getEnd().diffMilliSeconds(interval.getBegin()) > getMilliSecondsDisplayed()) {
4631 setStartDate(interval.getBegin());
4632 } else {
4633 scrollDateToVisible(interval.getEnd());
4634 }
4635 } else {
4636 if (interval.getBegin().compareTo(_startDate) < 0) {
4637 scrollDateToVisible(interval.getBegin());
4638 } else if (interval.getEnd().diffSeconds(interval.getBegin()) > getSecondsDisplayed()) {
4639 setStartDate(interval.getBegin());
4640 } else {
4641 scrollDateToVisible(interval.getEnd());
4642 }
4643 }
4644 }
4645
4646
4647
4648
4649
4650
4651
4652
4653 public boolean isIntervalVisible(TimeBarRow row, Interval interval) {
4654 if (!isRowDisplayed(row)) {
4655 return false;
4656 }
4657
4658 if (interval.getBegin().compareTo(_startDate) < 0 && interval.getEnd().compareTo(getEndDate()) >= 0) {
4659
4660 return true;
4661 } else if (interval.getBegin().compareTo(getEndDate()) > 0) {
4662
4663 return false;
4664 } else if (interval.getEnd().compareTo(_startDate) < 0) {
4665
4666 return false;
4667 }
4668 return true;
4669 }
4670
4671
4672
4673
4674
4675
4676
4677 public void scrollIntervalToVisible(Interval interval) {
4678 TimeBarRow row = _model.getRowForInterval(interval);
4679 if (row != null) {
4680 scrollIntervalToVisible(row, interval);
4681 }
4682 }
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692 public void scrollIntervalToVisible(Interval interval, double horizontalRatio, double verticalRatio) {
4693 if (horizontalRatio < 0.0 || horizontalRatio > 1.0 || verticalRatio < 0.0 || verticalRatio > 1.0) {
4694 throw new IllegalArgumentException("ratios have to be in the range from 0.0 to 1.0");
4695 }
4696 TimeBarRow row = _model.getRowForInterval(interval);
4697 if (row != null) {
4698 scrollIntervalToVisible(row, interval, horizontalRatio, verticalRatio);
4699 }
4700 }
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711 public void scrollIntervalToVisible(TimeBarRow row, Interval interval, double horizontalRatio, double verticalRatio) {
4712 if (horizontalRatio < 0.0 || horizontalRatio > 1.0 || verticalRatio < 0.0 || verticalRatio > 1.0) {
4713 throw new IllegalArgumentException("ratios have to be in the range from 0.0 to 1.0");
4714 }
4715
4716 int secondsDisplayed = getSecondsDisplayed();
4717 double secondsFromStart = (double) secondsDisplayed * horizontalRatio;
4718 JaretDate startDate = interval.getBegin().copy().backSeconds(secondsFromStart);
4719
4720
4721 int pos = (int) (getDiagramRect().height * verticalRatio);
4722 int destRowIdx = _rowList.indexOf(row);
4723
4724
4725
4726 int togo = pos;
4727 int idx;
4728 if (togo > 0) {
4729 idx = destRowIdx - 1;
4730 } else {
4731 idx = destRowIdx;
4732 }
4733 int rowHeight = 0;
4734 while (togo > 0 && idx >= 0) {
4735 rowHeight = getTimeBarViewState().getRowHeight(_rowList.get(idx));
4736 togo -= rowHeight;
4737 idx--;
4738 }
4739
4740 if (idx < 0) {
4741 setFirstRow(0);
4742 } else {
4743 setFirstRow(idx, rowHeight - togo);
4744 }
4745 setStartDate(startDate);
4746
4747 }
4748
4749
4750
4751
4752
4753
4754 public synchronized void addIntervalModificator(IntervalModificator intervalModificator) {
4755 if (_intervalModificators == null) {
4756 _intervalModificators = new Vector<IntervalModificator>();
4757 }
4758 _intervalModificators.add(intervalModificator);
4759 }
4760
4761
4762
4763
4764
4765
4766 public void remIntervalModificator(IntervalModificator intervalModificator) {
4767 if (_intervalModificators != null) {
4768 _intervalModificators.remove(intervalModificator);
4769 }
4770 }
4771
4772
4773
4774
4775
4776
4777 public ITimeBarViewState getTimeBarViewState() {
4778 return _timeBarViewState;
4779 }
4780
4781
4782
4783
4784
4785
4786 public HierarchicalViewState getHierarchicalViewState() {
4787 return _hierarchicalViewState;
4788 }
4789
4790
4791
4792
4793
4794
4795 public void setHierarchicalViewState(HierarchicalViewState hvs) {
4796 _hierarchicalViewState = hvs;
4797 }
4798
4799
4800
4801
4802
4803
4804 public void setTitle(String title) {
4805 _title = title;
4806 if (_tbvi != null) {
4807 _tbvi.repaint();
4808 }
4809 }
4810
4811
4812
4813
4814
4815
4816 public String getTitle() {
4817 return _title;
4818 }
4819
4820
4821
4822
4823 public boolean isDrawOverlapping() {
4824 return _drawOverlapping;
4825 }
4826
4827
4828
4829
4830
4831
4832
4833 public void setDrawOverlapping(boolean drawOverlapping) {
4834 _drawOverlapping = drawOverlapping;
4835 if (_tbvi != null) {
4836 _tbvi.repaint();
4837 }
4838 }
4839
4840
4841
4842
4843
4844
4845
4846 public int getMaxOverlapCount(TimeBarRow row) {
4847 if (getTimeBarViewState().getDrawOverlapping(row)) {
4848 return 1;
4849 } else {
4850 return _overlapStrategy.getMaxOverlapCount(row);
4851 }
4852 }
4853
4854
4855
4856
4857
4858
4859
4860 public List<Interval> filterIntervals(List<Interval> intervals) {
4861 if (_intervalFilter == null) {
4862 return intervals;
4863 }
4864 ArrayList<Interval> result = new ArrayList<Interval>();
4865 for (Interval interval : intervals) {
4866 if (_intervalFilter.isInResult(interval)) {
4867 result.add(interval);
4868 }
4869 }
4870
4871 return result;
4872 }
4873
4874
4875
4876
4877
4878 public void propertyChange(PropertyChangeEvent evt) {
4879 if (evt.getSource().equals(_rowFilter) || evt.getSource().equals(_rowSorter)) {
4880
4881
4882 updateRowList();
4883 if (_tbvi != null) {
4884 _tbvi.repaint();
4885 }
4886 } else if (evt.getSource() instanceof TimeBarIntervalFilter) {
4887 if (_tbvi != null) {
4888 _overlapStrategy.clearCachedData();
4889 _tbvi.repaint();
4890 }
4891 }
4892 }
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902 public Interval getFocussedInterval() {
4903 return _focussedInterval;
4904 }
4905
4906
4907
4908
4909 public TimeBarRow getFocussedRow() {
4910 return _focussedRow;
4911 }
4912
4913
4914
4915
4916
4917
4918
4919 public boolean isFocussed(Interval interval) {
4920 if (_focussedInterval == null) {
4921 return false;
4922 }
4923 return _focussedInterval.equals(interval);
4924 }
4925
4926
4927
4928
4929
4930
4931 public void setFocussedInterval(Interval interval) {
4932 setFocussedInterval(null, interval);
4933 }
4934
4935
4936
4937
4938
4939
4940
4941 public void setFocussedInterval(TimeBarRow row, Interval interval) {
4942 if (_focussedInterval == null && interval == null) {
4943 return;
4944 }
4945 if (_focussedInterval != null && _focussedInterval.equals(interval)) {
4946 return;
4947 }
4948 if (interval != null && isFiltered(interval)) {
4949
4950 return;
4951 }
4952 if (interval != null && row == null) {
4953 _focussedRow = _model.getRowForInterval(interval);
4954 if (_focussedRow == null || isFiltered(_focussedRow)) {
4955 return;
4956 }
4957 } else {
4958 _focussedRow = row;
4959 }
4960
4961 _focussedInterval = interval;
4962
4963 if (_focussedInterval != null && _scrollOnFocus) {
4964 if (!isIntervalVisible(_focussedRow, _focussedInterval)) {
4965 scrollIntervalToVisible(_focussedRow, _focussedInterval);
4966 }
4967 }
4968 _tbvi.repaint();
4969 fireFocussedIntervalChange(_focussedRow, _focussedInterval);
4970 }
4971
4972
4973
4974
4975 public void moveFocusRight() {
4976 if (_focussedRow != null && _focussedInterval != null) {
4977 int idx = _focussedRow.getIntervals().indexOf(_focussedInterval);
4978 if (idx + 1 < _focussedRow.getIntervals().size()) {
4979 setFocussedInterval(_focussedRow.getIntervals().get(idx + 1));
4980 }
4981 }
4982 }
4983
4984
4985
4986
4987 public void moveFocusLeft() {
4988 if (_focussedRow != null && _focussedInterval != null) {
4989 int idx = _focussedRow.getIntervals().indexOf(_focussedInterval);
4990 if (idx - 1 >= 0) {
4991 setFocussedInterval(_focussedRow.getIntervals().get(idx - 1));
4992 }
4993 }
4994 }
4995
4996
4997
4998
4999 public void moveFocusUp() {
5000 if (_focussedRow != null && _focussedInterval != null) {
5001 int ridx = _rowList.indexOf(_focussedRow);
5002 if (ridx > 0) {
5003 TimeBarRow focussedRow = _rowList.get(ridx - 1);
5004 List<Interval> intervals = focussedRow.getIntervals(_focussedInterval.getBegin(), _focussedInterval
5005 .getEnd());
5006 if (intervals != null && intervals.size() > 0) {
5007 setFocussedInterval(focussedRow, intervals.get(0));
5008 } else {
5009 Interval interval = getNearestInterval(focussedRow, _focussedInterval);
5010 if (interval != null) {
5011 setFocussedInterval(focussedRow, interval);
5012 }
5013 }
5014 }
5015 }
5016 }
5017
5018
5019
5020
5021 public void moveFocusDown() {
5022 if (_focussedRow != null && _focussedInterval != null) {
5023 int ridx = _rowList.indexOf(_focussedRow);
5024 if (ridx + 1 < _rowList.size()) {
5025 TimeBarRow focussedRow = _rowList.get(ridx + 1);
5026 List<Interval> intervals = focussedRow.getIntervals(_focussedInterval.getBegin(), _focussedInterval
5027 .getEnd());
5028 if (intervals != null && intervals.size() > 0) {
5029 setFocussedInterval(focussedRow, intervals.get(0));
5030 } else {
5031 Interval interval = getNearestInterval(focussedRow, _focussedInterval);
5032 if (interval != null) {
5033 setFocussedInterval(focussedRow, interval);
5034 }
5035 }
5036 }
5037 }
5038 }
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048 private Interval getNearestInterval(TimeBarRow row, Interval interval) {
5049 Interval result = null;
5050 long deltaSec = -1;
5051 JaretDate d = new JaretDate(interval.getBegin());
5052 d.advanceSeconds(interval.getSeconds() / 2.0);
5053 for (Interval i : row.getIntervals()) {
5054 int delta = Math.abs(i.getBegin().diffSeconds(d));
5055 if (delta < deltaSec || deltaSec == -1) {
5056 result = i;
5057 deltaSec = delta;
5058 }
5059 delta = Math.abs(i.getEnd().diffSeconds(d));
5060 if (delta < deltaSec || deltaSec == -1) {
5061 result = i;
5062 deltaSec = delta;
5063 }
5064 }
5065 return result;
5066 }
5067
5068
5069
5070
5071
5072
5073 public synchronized void addFocussedIntervalListener(FocussedIntervalListener listener) {
5074 if (_focussedIntervalListeners == null) {
5075 _focussedIntervalListeners = new Vector<FocussedIntervalListener>(2);
5076 }
5077 _focussedIntervalListeners.add(listener);
5078 }
5079
5080
5081
5082
5083
5084
5085 public synchronized void remFocussedIntervalListener(FocussedIntervalListener listener) {
5086 if (_focussedIntervalListeners != null) {
5087 _focussedIntervalListeners.remove(listener);
5088 }
5089 }
5090
5091
5092
5093
5094
5095
5096
5097 protected synchronized void fireFocussedIntervalChange(TimeBarRow newFocussedRow, Interval newFocussedInterval) {
5098 if (_focussedIntervalListeners != null) {
5099 for (FocussedIntervalListener listener : _focussedIntervalListeners) {
5100 listener.focussedIntervalChanged(_tbvi, newFocussedRow, newFocussedInterval);
5101 }
5102 }
5103 }
5104
5105
5106
5107
5108
5109
5110 public synchronized void addSelectionRectListener(ISelectionRectListener listener) {
5111 if (_selectionRectListeners == null) {
5112 _selectionRectListeners = new Vector<ISelectionRectListener>(2);
5113 }
5114 _selectionRectListeners.add(listener);
5115 }
5116
5117
5118
5119
5120
5121
5122 public synchronized void remSelectionRectListener(ISelectionRectListener listener) {
5123 if (_selectionRectListeners != null) {
5124 _selectionRectListeners.remove(listener);
5125 }
5126 }
5127
5128
5129
5130
5131 protected void fireSelectionRectChanged() {
5132 if (_selectionRectListeners != null) {
5133 for (ISelectionRectListener listener : _selectionRectListeners) {
5134 boolean horizontal = _orientation == Orientation.HORIZONTAL;
5135 Rectangle curSelRect = _selectionRect;
5136
5137 List<TimeBarRow> rows = horizontal ? getRows(curSelRect.y, curSelRect.y + curSelRect.height) : getRows(
5138 curSelRect.x, curSelRect.x + curSelRect.width);
5139
5140 JaretDate begin = horizontal ? dateForCoord(curSelRect.x) : dateForCoord(curSelRect.y);
5141 JaretDate end = horizontal ? dateForCoord(curSelRect.x + curSelRect.width) : dateForCoord(curSelRect.y
5142 + curSelRect.height);
5143
5144 listener.selectionRectChanged(this, begin, end, rows);
5145 }
5146 }
5147 }
5148
5149
5150
5151
5152 protected void fireSelectionRectClosed() {
5153 if (_selectionRectListeners != null) {
5154 for (ISelectionRectListener listener : _selectionRectListeners) {
5155 listener.selectionRectClosed(this);
5156 }
5157 }
5158 }
5159
5160
5161
5162
5163 protected void fireRegionRectChanged() {
5164 if (_selectionRectListeners != null) {
5165 for (ISelectionRectListener listener : _selectionRectListeners) {
5166
5167 listener.regionRectChanged(this, _regionSelection);
5168 }
5169 }
5170 }
5171
5172
5173
5174
5175 protected void fireRegionRectClosed() {
5176 if (_selectionRectListeners != null) {
5177 for (ISelectionRectListener listener : _selectionRectListeners) {
5178 listener.regionRectClosed(this);
5179 }
5180 }
5181 }
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191 public void handleKeyPressed(int keyCode, int modifierMask) {
5192 boolean horizontal = _orientation.equals(Orientation.HORIZONTAL);
5193 if (modifierMask == 0) {
5194 switch (keyCode) {
5195 case KeyEvent.VK_RIGHT:
5196 if (horizontal) {
5197 moveFocusRight();
5198 } else {
5199 moveFocusDown();
5200 }
5201 break;
5202 case KeyEvent.VK_LEFT:
5203 if (horizontal) {
5204 moveFocusLeft();
5205 } else {
5206 moveFocusUp();
5207 }
5208 break;
5209 case KeyEvent.VK_UP:
5210 if (horizontal) {
5211 moveFocusUp();
5212 } else {
5213 moveFocusLeft();
5214 }
5215 break;
5216 case KeyEvent.VK_DOWN:
5217 if (horizontal) {
5218 moveFocusDown();
5219 } else {
5220 moveFocusRight();
5221 }
5222 break;
5223 case KeyEvent.VK_SPACE:
5224 selectFocussedInterval(false);
5225 break;
5226 case KeyEvent.VK_ESCAPE:
5227 cancelDrag();
5228 break;
5229
5230 default:
5231
5232 break;
5233 }
5234 } else if ((modifierMask & InputEvent.SHIFT_DOWN_MASK) != 0) {
5235 switch (keyCode) {
5236 case KeyEvent.VK_RIGHT:
5237 growRight(_focussedRow, _focussedInterval, _keyboardChangeDelta);
5238 break;
5239 case KeyEvent.VK_LEFT:
5240 growLeft(_focussedRow, _focussedInterval, _keyboardChangeDelta);
5241 break;
5242 default:
5243
5244 break;
5245 }
5246 } else if ((modifierMask & InputEvent.ALT_DOWN_MASK) != 0) {
5247 switch (keyCode) {
5248 case KeyEvent.VK_RIGHT:
5249 growLeft(_focussedRow, _focussedInterval, -_keyboardChangeDelta);
5250 break;
5251 case KeyEvent.VK_LEFT:
5252 growRight(_focussedRow, _focussedInterval, -_keyboardChangeDelta);
5253 break;
5254 default:
5255
5256 break;
5257 }
5258 } else if ((modifierMask & InputEvent.CTRL_DOWN_MASK) != 0) {
5259 switch (keyCode) {
5260 case KeyEvent.VK_RIGHT:
5261 moveInterval(_focussedRow, _focussedInterval, _keyboardChangeDelta);
5262 break;
5263 case KeyEvent.VK_LEFT:
5264 moveInterval(_focussedRow, _focussedInterval, -_keyboardChangeDelta);
5265 break;
5266 case KeyEvent.VK_SPACE:
5267 selectFocussedInterval(true);
5268 break;
5269 case KeyEvent.VK_ESCAPE:
5270 cancelDrag();
5271 break;
5272 default:
5273
5274 break;
5275 }
5276 }
5277 }
5278
5279
5280
5281
5282
5283
5284 private void selectFocussedInterval(boolean add) {
5285 if (_focussedInterval != null) {
5286 if (!add) {
5287 _selectionModel.setSelectedInterval(_focussedInterval);
5288 } else {
5289 if (!_selectionModel.isSelected(_focussedInterval)) {
5290 _selectionModel.addSelectedInterval(_focussedInterval);
5291 } else {
5292 _selectionModel.remSelectedInterval(_focussedInterval);
5293 }
5294 }
5295 }
5296 }
5297
5298
5299
5300
5301
5302
5303
5304
5305 private void moveInterval(TimeBarRow row, Interval interval, int deltaSeconds) {
5306 if (interval == null) {
5307 return;
5308 }
5309 JaretDate newBegin = interval.getBegin().copy().advanceSeconds(deltaSeconds);
5310 boolean allowed = isShiftingAllowed(row, interval, newBegin);
5311 if (allowed) {
5312 JaretDate oldBegin = interval.getBegin();
5313 JaretDate oldEnd = interval.getEnd();
5314
5315 interval.setBegin(newBegin);
5316 interval.setEnd(interval.getEnd().advanceSeconds(deltaSeconds));
5317
5318
5319 fireIntervalChangeStarted(row, interval);
5320 fireIntervalChanged(row, interval, oldBegin, oldEnd);
5321 }
5322
5323 }
5324
5325
5326
5327
5328
5329
5330
5331
5332 private void growLeft(TimeBarRow row, Interval interval, int deltaSeconds) {
5333 if (interval == null) {
5334 return;
5335 }
5336 JaretDate newBegin = interval.getBegin().copy().backSeconds(deltaSeconds);
5337 boolean allowed = isNewBeginAllowed(row, interval, newBegin);
5338 if (allowed) {
5339 JaretDate oldBegin = interval.getBegin();
5340 interval.setBegin(newBegin);
5341
5342
5343 fireIntervalChangeStarted(row, interval);
5344 fireIntervalChanged(row, interval, oldBegin, interval.getEnd());
5345 }
5346 }
5347
5348
5349
5350
5351
5352
5353
5354
5355 private void growRight(TimeBarRow row, Interval interval, int deltaSeconds) {
5356 if (interval == null) {
5357 return;
5358 }
5359 JaretDate newEnd = interval.getEnd().copy().advanceSeconds(deltaSeconds);
5360 boolean allowed = isNewEndAllowed(row, interval, newEnd);
5361 if (allowed) {
5362 JaretDate oldEnd = interval.getEnd();
5363 interval.setEnd(newEnd);
5364
5365
5366 fireIntervalChangeStarted(row, interval);
5367 fireIntervalChanged(row, interval, interval.getBegin(), oldEnd);
5368 }
5369 }
5370
5371
5372
5373
5374
5375
5376 public int getKeyboardChangeDelta() {
5377 return _keyboardChangeDelta;
5378 }
5379
5380
5381
5382
5383
5384
5385 public void setKeyboardChangeDelta(int keyboardChangeDelta) {
5386 _keyboardChangeDelta = keyboardChangeDelta;
5387 }
5388
5389
5390
5391
5392
5393
5394
5395 public boolean hasVariableXScale() {
5396 return _variableXScale;
5397 }
5398
5399
5400
5401
5402
5403
5404 public void setVariableXScale(boolean state) {
5405 if (state != _variableXScale) {
5406 _variableXScale = state;
5407 if (state) {
5408 setOptimizeScrolling(false);
5409
5410
5411 _xScalePPSIntervalRow = new DefaultTimeBarNode(new DefaultRowHeader("PPSROW"));
5412 if (_repaintingRowListener == null) {
5413 _repaintingRowListener = new TimeBarRowListener() {
5414
5415
5416 public void elementAdded(TimeBarRow row, Interval element) {
5417 updateTimeScaleBreaks();
5418 _tbvi.repaint();
5419 }
5420
5421 public void elementChanged(TimeBarRow row, Interval element) {
5422 updateTimeScaleBreaks();
5423 _tbvi.repaint();
5424 }
5425
5426 public void elementRemoved(TimeBarRow row, Interval element) {
5427 _tbvi.repaint();
5428 }
5429
5430 public void headerChanged(TimeBarRow row, TimeBarRowHeader newHeader) {
5431 _tbvi.repaint();
5432 }
5433
5434 public void rowDataChanged(TimeBarRow row) {
5435 updateTimeScaleBreaks();
5436 _tbvi.repaint();
5437 }
5438 };
5439 }
5440 _xScalePPSIntervalRow.addTimeBarRowListener(_repaintingRowListener);
5441 } else {
5442 if (_xScalePPSIntervalRow != null && _repaintingRowListener != null) {
5443 _xScalePPSIntervalRow.remTimeBarRowListener(_repaintingRowListener);
5444 }
5445 _xScalePPSIntervalRow = null;
5446 }
5447 if (_tbvi != null) {
5448 _tbvi.repaint();
5449 }
5450 updateScrollBars();
5451 }
5452 }
5453
5454
5455
5456
5457
5458
5459 public TimeBarNode getPpsRow() {
5460 return _xScalePPSIntervalRow;
5461 }
5462
5463
5464
5465
5466
5467
5468 public int getSelectionDelta() {
5469 return _selectionDelta;
5470 }
5471
5472
5473
5474
5475
5476
5477 public void setSelectionDelta(int selectionDelta) {
5478 _selectionDelta = selectionDelta;
5479 }
5480
5481
5482
5483
5484
5485
5486 public boolean isLineDraggingAllowed() {
5487 return _lineDraggingAllowed;
5488 }
5489
5490
5491
5492
5493
5494
5495 public void setLineDraggingAllowed(boolean lineDraggingAllowed) {
5496 _lineDraggingAllowed = lineDraggingAllowed;
5497 }
5498
5499
5500
5501
5502
5503
5504 public boolean isMilliAccuracy() {
5505 return _milliAccuracy;
5506 }
5507
5508
5509
5510
5511
5512
5513
5514 public void setMilliAccuracy(boolean milliAccuracy) {
5515 _milliAccuracy = milliAccuracy;
5516 }
5517
5518
5519
5520
5521
5522
5523
5524
5525 public void setDrawingOffset(int marginLeft, int marginTop) {
5526 _offsetLeft = marginLeft;
5527 _offsetTop = marginTop;
5528 }
5529
5530
5531
5532
5533
5534
5535 public boolean getOptimizeScrolling() {
5536 return _optimizeScrolling;
5537 }
5538
5539
5540
5541
5542
5543
5544 public void setOptimizeScrolling(boolean optimizeScrolling) {
5545 if (_variableXScale && optimizeScrolling) {
5546 throw new RuntimeException("Optimized scrolling can not be used together with a variable xscale");
5547 }
5548 _optimizeScrolling = optimizeScrolling;
5549 }
5550
5551
5552
5553
5554
5555
5556 public Orientation getOrientation() {
5557 return _orientation;
5558 }
5559
5560
5561
5562
5563
5564
5565 public void setOrientation(Orientation orientation) {
5566 if (_orientation != orientation) {
5567 _orientation = orientation;
5568 updateScrollBars();
5569 if (_tbvi != null) {
5570 _tbvi.repaint();
5571 }
5572 }
5573 }
5574
5575
5576
5577
5578
5579
5580 public int getAutoScaleRows() {
5581 return _autoScaleRows;
5582 }
5583
5584
5585
5586
5587
5588
5589
5590 public void setAutoScaleRows(int rows) {
5591 if (_autoScaleRows != rows) {
5592 _autoScaleRows = rows;
5593 if (_tbvi != null) {
5594 _tbvi.repaint();
5595 }
5596 }
5597 }
5598
5599
5600
5601
5602
5603
5604 public void addTimeBarChangeListener(ITimeBarChangeListener listener) {
5605 if (!_timeBarChangeListeners.contains(listener)) {
5606 _timeBarChangeListeners.add(listener);
5607 }
5608 }
5609
5610
5611
5612
5613
5614
5615 public void removeTimeBarChangeListener(ITimeBarChangeListener listener) {
5616 _timeBarChangeListeners.remove(listener);
5617 }
5618
5619
5620
5621
5622
5623
5624
5625 protected void fireIntervalChangeStarted(TimeBarRow row, Interval interval) {
5626 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5627 listener.intervalChangeStarted(row, interval);
5628 }
5629 }
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639 protected void fireIntervalIntermediateChange(TimeBarRow row, Interval interval, JaretDate oldBegin,
5640 JaretDate oldEnd) {
5641 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5642 listener.intervalIntermediateChange(row, interval, oldBegin, oldEnd);
5643 }
5644
5645 }
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655 protected void fireIntervalChanged(TimeBarRow row, Interval interval, JaretDate oldBegin, JaretDate oldEnd) {
5656 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5657 listener.intervalChanged(row, interval, oldBegin, oldEnd);
5658 }
5659
5660 }
5661
5662
5663
5664
5665
5666
5667
5668 protected void fireIntervalChangeCancelled(TimeBarRow row, Interval interval) {
5669 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5670 listener.intervalChangeCancelled(row, interval);
5671 }
5672 }
5673
5674
5675
5676
5677
5678
5679 protected void fireMarkerDragStarted(TimeBarMarker marker) {
5680 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5681 listener.markerDragStarted(marker);
5682 }
5683 }
5684
5685
5686
5687
5688
5689
5690 protected void fireMarkerDragStopped(TimeBarMarker marker) {
5691 for (ITimeBarChangeListener listener : _timeBarChangeListeners) {
5692 listener.markerDragStopped(marker);
5693 }
5694 }
5695
5696
5697
5698
5699
5700
5701 public boolean isRowHeightDraggingAllowed() {
5702 return _rowHeightDraggingAllowed;
5703 }
5704
5705
5706
5707
5708
5709
5710 public void setRowHeightDraggingAllowed(boolean rowHeightDraggingAllowed) {
5711 if (_rowHeightDraggingAllowed != rowHeightDraggingAllowed) {
5712 _rowHeightDraggingAllowed = rowHeightDraggingAllowed;
5713 if (_tbvi != null) {
5714 _tbvi.firePropertyChangeX(TimeBarViewerInterface.PROPERTYNAME_ROWHEIGHTDRAGGINGALLOWED,
5715 !rowHeightDraggingAllowed, rowHeightDraggingAllowed);
5716 }
5717 }
5718 }
5719
5720
5721
5722
5723
5724
5725
5726
5727 public boolean isInRowAxis(int x, int y) {
5728 return _hierarchyRect.contains(x, y) || _yAxisRect.contains(x, y);
5729 }
5730
5731
5732
5733
5734
5735
5736
5737
5738 public boolean isInDiagram(int x, int y) {
5739 return _diagramRect.contains(x, y);
5740 }
5741
5742
5743
5744
5745
5746
5747 public boolean getStrictClipTimeCheck() {
5748 return _strictClipTimeCheck;
5749 }
5750
5751
5752
5753
5754
5755
5756
5757
5758 public void setStrictClipTimeCheck(boolean strictClipTimeCheck) {
5759 _strictClipTimeCheck = strictClipTimeCheck;
5760 }
5761
5762
5763
5764
5765
5766
5767 public int getScrollLookBackMinutes() {
5768 return _scrollLookBackMinutes;
5769 }
5770
5771
5772
5773
5774
5775
5776 public void setScrollLookBackMinutes(int scrollLookBackMinutes) {
5777 _scrollLookBackMinutes = scrollLookBackMinutes;
5778 }
5779
5780
5781
5782
5783
5784
5785
5786 public int getScrollLookForwardMinutes() {
5787 return _scrollLookForwardMinutes;
5788 }
5789
5790
5791
5792
5793
5794
5795 public void setScrollLookForwardMinutes(int scrollLookForwardMinutes) {
5796 _scrollLookForwardMinutes = scrollLookForwardMinutes;
5797 }
5798
5799
5800
5801
5802
5803
5804 public IOverlapStrategy getOverlapStrategy() {
5805 return _overlapStrategy;
5806 }
5807
5808
5809
5810
5811
5812
5813 public void setOverlapStrategy(IOverlapStrategy overlapStrategy) {
5814 if (overlapStrategy == null) {
5815 throw new IllegalArgumentException("Strategy may not be null");
5816 }
5817 IOverlapStrategy oldStrategy = _overlapStrategy;
5818 _overlapStrategy = overlapStrategy;
5819 oldStrategy.dispose();
5820 }
5821
5822
5823
5824
5825
5826
5827 public int getAutoscrollDelta() {
5828 return _autoscrollDelta;
5829 }
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839 public void setAutoscrollDelta(int autoscrollDelta) {
5840 _autoscrollDelta = autoscrollDelta;
5841 }
5842
5843
5844
5845
5846
5847
5848 public boolean getDragAllSelectedIntervals() {
5849 return _dragAllSelectedIntervals;
5850 }
5851
5852
5853
5854
5855
5856
5857 public void setDragAllSelectedIntervals(boolean dragAllSelectedIntervals) {
5858 _dragAllSelectedIntervals = dragAllSelectedIntervals;
5859 }
5860
5861
5862
5863
5864
5865
5866 public boolean getScrollOnFocus() {
5867 return _scrollOnFocus;
5868 }
5869
5870
5871
5872
5873
5874
5875 public void setScrollOnFocus(boolean scrollOnFocus) {
5876 _scrollOnFocus = scrollOnFocus;
5877 }
5878
5879
5880
5881
5882
5883
5884 public boolean getHideRoot() {
5885 return _hideRoot;
5886 }
5887
5888
5889
5890
5891
5892
5893 public void setHideRoot(boolean hideRoot) {
5894 _hideRoot = hideRoot;
5895 if (_model instanceof StdHierarchicalTimeBarModel) {
5896 ((StdHierarchicalTimeBarModel) _model).setHideRoot(hideRoot);
5897 }
5898 }
5899
5900
5901 protected boolean _markerDraggingInDiagramArea = false;
5902
5903
5904
5905
5906
5907
5908 public boolean getMarkerDraggingInDiagramArea() {
5909 return _markerDraggingInDiagramArea;
5910 }
5911
5912
5913
5914
5915
5916
5917
5918 public void setMarkerDraggingInDiagramArea(boolean allowed) {
5919 _markerDraggingInDiagramArea = allowed;
5920 }
5921
5922
5923
5924
5925
5926
5927 public boolean isMarkerDraggingInProgress() {
5928 return _draggedMarker != null;
5929 }
5930
5931
5932
5933
5934
5935
5936 public IIntervalSelectionStrategy getIntervalSelectionStrategy() {
5937 return _intervalSelectionStrategy;
5938 }
5939
5940
5941
5942
5943
5944
5945 public void setIntervalSelectionStrategy(IIntervalSelectionStrategy intervalSelectionStrategy) {
5946 _intervalSelectionStrategy = intervalSelectionStrategy;
5947 }
5948
5949
5950
5951
5952
5953
5954
5955 public Rectangle calcRect(TBRect tbrect) {
5956 Rectangle result = new Rectangle();
5957 if (_orientation == Orientation.HORIZONTAL) {
5958 result.x = xForDate(tbrect.startDate);
5959 result.width = xForDate(tbrect.endDate) - result.x;
5960 result.y = getRowBounds(tbrect.startRow).y;
5961 result.height = getRowBounds(tbrect.endRow).y + getTimeBarViewState().getRowHeight(tbrect.endRow)
5962 - result.y;
5963 } else {
5964 result.y = xForDate(tbrect.startDate);
5965 result.height = xForDate(tbrect.endDate) - result.x;
5966 result.x = getRowBounds(tbrect.startRow).y;
5967 result.width = getRowBounds(tbrect.endRow).y + getTimeBarViewState().getRowHeight(tbrect.endRow) - result.y;
5968 }
5969 return result;
5970 }
5971
5972
5973
5974
5975
5976
5977 public TBRect getRegionRect() {
5978 return _regionSelection;
5979 }
5980
5981
5982
5983
5984 public void clearRegionRect() {
5985 if (_regionSelection != null) {
5986 _regionSelection = null;
5987 _lastRegionSelection = null;
5988 _tbvi.repaint();
5989 fireRegionRectClosed();
5990 }
5991 }
5992
5993
5994
5995
5996
5997
5998 public void setRegionRectEnable(boolean enabled) {
5999 _regionRectEnabled = enabled;
6000 clearRegionRect();
6001 }
6002
6003
6004
6005
6006
6007
6008 public boolean getRegionRectEnable() {
6009 return _regionRectEnabled;
6010 }
6011
6012
6013
6014
6015
6016
6017 public void setUseUniformHeight(boolean useUniformHeight) {
6018 if (useUniformHeight != _useUniformHeight) {
6019 _useUniformHeight = useUniformHeight;
6020 _tbvi.repaint();
6021 }
6022 }
6023
6024
6025
6026
6027
6028
6029 public boolean getUseUniformHeight() {
6030 return _useUniformHeight;
6031 }
6032
6033
6034
6035
6036 public void componentResized() {
6037 if (_diagramRect.width != 0) {
6038 preparePaint(_tbvi.getWidth(), _tbvi.getHeight());
6039
6040 int numRows = _rowList.size();
6041 if (numRows > 0) {
6042 TimeBarRow row = _rowList.get(_rowList.size() - 1);
6043 int absStartY = getAbsPosForRow(_firstRow) + _firstRowPixelOffset;
6044 int absLastY = getAbsPosForRow(_rowList.size() - 1);
6045
6046 if ((absLastY + _timeBarViewState.getRowHeight(row)) - absStartY < _diagramRect.height) {
6047 setLastRow(row);
6048 }
6049 }
6050 }
6051 updateScrollBars();
6052 }
6053
6054
6055 }