1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package de.jaret.examples.timebars.hierarchy.swt;
21
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Locale;
25
26 import org.eclipse.jface.action.Action;
27 import org.eclipse.jface.action.MenuManager;
28 import org.eclipse.jface.resource.ImageDescriptor;
29 import org.eclipse.jface.resource.ImageRegistry;
30 import org.eclipse.jface.viewers.ILabelProvider;
31 import org.eclipse.jface.viewers.ILabelProviderListener;
32 import org.eclipse.jface.window.ApplicationWindow;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.dnd.DND;
35 import org.eclipse.swt.dnd.DragSource;
36 import org.eclipse.swt.dnd.DragSourceEvent;
37 import org.eclipse.swt.dnd.DragSourceListener;
38 import org.eclipse.swt.dnd.DropTarget;
39 import org.eclipse.swt.dnd.DropTargetEvent;
40 import org.eclipse.swt.dnd.DropTargetListener;
41 import org.eclipse.swt.dnd.TextTransfer;
42 import org.eclipse.swt.dnd.Transfer;
43 import org.eclipse.swt.events.DisposeEvent;
44 import org.eclipse.swt.events.DisposeListener;
45 import org.eclipse.swt.graphics.Image;
46 import org.eclipse.swt.graphics.Point;
47 import org.eclipse.swt.layout.GridData;
48 import org.eclipse.swt.layout.GridLayout;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Display;
52 import org.eclipse.swt.widgets.Menu;
53 import org.eclipse.swt.widgets.Shell;
54
55 import de.jaret.examples.timebars.hierarchy.model.DemoTimeBarNode;
56 import de.jaret.examples.timebars.hierarchy.model.ModelCreator;
57 import de.jaret.examples.timebars.pdi.swt.SwtControlPanel;
58 import de.jaret.util.date.Interval;
59 import de.jaret.util.date.IntervalImpl;
60 import de.jaret.util.date.JaretDate;
61 import de.jaret.util.date.holidayenumerator.HolidayEnumeratorFactory;
62 import de.jaret.util.ui.ResourceImageDescriptor;
63 import de.jaret.util.ui.timebars.TimeBarMarkerImpl;
64 import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
65 import de.jaret.util.ui.timebars.TimeBarViewerInterface;
66 import de.jaret.util.ui.timebars.mod.DefaultIntervalModificator;
67 import de.jaret.util.ui.timebars.model.AddingTimeBarRowModel;
68 import de.jaret.util.ui.timebars.model.DefaultRowHeader;
69 import de.jaret.util.ui.timebars.model.DefaultTimeBarNode;
70 import de.jaret.util.ui.timebars.model.DefaultTimeBarRowModel;
71 import de.jaret.util.ui.timebars.model.HierarchicalTimeBarModel;
72 import de.jaret.util.ui.timebars.model.ISelectionRectListener;
73 import de.jaret.util.ui.timebars.model.PPSInterval;
74 import de.jaret.util.ui.timebars.model.TBRect;
75 import de.jaret.util.ui.timebars.model.TimeBarNode;
76 import de.jaret.util.ui.timebars.model.TimeBarRow;
77 import de.jaret.util.ui.timebars.swt.RowContextMenuHandler;
78 import de.jaret.util.ui.timebars.swt.TimeBarViewer;
79 import de.jaret.util.ui.timebars.swt.renderer.BoxTimeScaleRenderer;
80 import de.jaret.util.ui.timebars.swt.renderer.DefaultGridRenderer;
81 import de.jaret.util.ui.timebars.swt.renderer.DefaultHierarchyRenderer;
82 import de.jaret.util.ui.timebars.swt.renderer.DefaultTitleRenderer;
83 import de.jaret.util.ui.timebars.swt.renderer.RelationRenderer;
84 import de.jaret.util.ui.timebars.swt.util.actions.JaretTimeBarsActionFactory;
85
86 /***
87 * Simple hierarchical view, SWT version. Scaling, manipulating the intervals, tree structure. The sum interval is
88 * rendered by a specialized sum renderer. The arrows beetwenn the intervals are a demonstration of the relation
89 * renderer that in fact is a global assistance renderer. Context menus on scale and hierarchy. Hierarchy using label
90 * provider including icons.
91 * <p>
92 * The example also demonstrates the usage of a variable xaxis definition. To see that version set _variableXAxis to
93 * true.
94 * </p>
95 *
96 * @author Peter Kliem
97 * @version $Id: SwtHierachy.java 1083 2011-07-01 20:29:16Z kliem $
98 */
99 public class SwtHierachy extends ApplicationWindow {
100
101 private static final boolean VARIABLE_XAXIS = false;
102
103 static TimeBarViewer _tbv;
104
105 /***
106 * If set to true, DND of nodes will be supported (for testing). This disables drawing of references.
107 */
108 private static final boolean SUPPORT_DND = false;
109
110 public SwtHierachy() {
111 super(null);
112 }
113
114 protected Control createContents(Composite parent) {
115 GridLayout gridLayout = new GridLayout();
116 gridLayout.numColumns = 1;
117 parent.setLayout(gridLayout);
118
119
120 HierarchicalTimeBarModel model = ModelCreator.createModel(2, 5);
121
122 _tbv = new TimeBarViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
123 GridData gd = new GridData(GridData.FILL_BOTH);
124 _tbv.setLayoutData(gd);
125
126 _tbv.setTimeScalePosition(TimeBarViewer.TIMESCALE_POSITION_TOP);
127
128 _tbv.setModel(model);
129
130
131
132
133 _tbv.setPixelPerSecond(0.00144);
134
135
136 DefaultTitleRenderer titleRenderer = new DefaultTitleRenderer();
137 titleRenderer.setBackgroundRscName("/de/jaret/examples/timebars/hierarchy/swt/titlebg.png");
138 _tbv.setTitleRenderer(titleRenderer);
139 _tbv.setTitle("SwtHierarchy");
140
141
142 if (VARIABLE_XAXIS) {
143 _tbv.setVariableXScale(true);
144 DefaultTimeBarNode scaleRow = (DefaultTimeBarNode) _tbv.getPpsRow();
145 scaleRow.setLevel(1);
146 model.getRootNode().addNode(scaleRow);
147 PPSInterval pps1 = new PPSInterval(_tbv.getPixelPerSecond() / 2);
148 pps1.setBegin(new JaretDate());
149 pps1.setEnd(new JaretDate().advanceDays(1));
150 scaleRow.addInterval(pps1);
151
152 PPSInterval pps2 = new PPSInterval(_tbv.getPixelPerSecond() / 4);
153 pps2.setBegin(new JaretDate().advanceDays(3));
154 pps2.setEnd(new JaretDate().advanceDays(5));
155 scaleRow.addInterval(pps2);
156 }
157
158
159 DefaultHierarchyRenderer hrenderer = new DefaultHierarchyRenderer();
160 hrenderer.setLabelProvider(new LabelProvider());
161 hrenderer.setDrawLabels(true);
162 hrenderer.setDrawIcons(true);
163 hrenderer.setLevelWidth(25);
164 hrenderer.setFixedLevelWidth(true);
165 hrenderer.setRscNames("/de/jaret/examples/timebars/hierarchy/swt/collapsed.png",
166 "/de/jaret/examples/timebars/hierarchy/swt/expanded.png",
167 "/de/jaret/examples/timebars/hierarchy/swt/leaf.png");
168 hrenderer.setSize(16);
169 _tbv.setHierarchyRenderer(hrenderer);
170 _tbv.setHierarchyWidth(200);
171
172
173 _tbv.addIntervalModificator(new DefaultIntervalModificator());
174
175
176 _tbv.registerTimeBarRenderer(AddingTimeBarRowModel.MergedInterval.class, new SumRenderer());
177
178
179 DefaultGridRenderer gridRenderer = new DefaultGridRenderer();
180 gridRenderer.setHolidayEnumerator(HolidayEnumeratorFactory.getHolidayEnumeratorInstance(Locale.getDefault(),
181 "NRW"));
182 _tbv.setGridRenderer(gridRenderer);
183
184
185
186
187
188
189
190 _tbv.setTimeScaleRenderer(new BoxTimeScaleRenderer());
191
192 final RelationRenderer relationRenderer = new RelationRenderer();
193 if (!SUPPORT_DND) {
194 _tbv.setRelationRenderer(relationRenderer);
195 }
196
197 TimeBarMarkerImpl tm = new TimeBarMarkerImpl(true, new JaretDate().advanceDays(1));
198 tm.setDescription("TimeBarMarker");
199 _tbv.addMarker(tm);
200
201
202 SwtControlPanel ctrl = new SwtControlPanel(parent, SWT.NULL, _tbv, null);
203 gd = new GridData(GridData.FILL_HORIZONTAL);
204 ctrl.setLayoutData(gd);
205
206
207 SwtHierarchyControlPanel ctrl2 = new SwtHierarchyControlPanel(parent, SWT.NULL, _tbv);
208 gd = new GridData(GridData.FILL_HORIZONTAL);
209 ctrl2.setLayoutData(gd);
210
211
212 SwtRelationRendererControlPanel ctrl3 = new SwtRelationRendererControlPanel(parent, SWT.NULL, _tbv);
213 gd = new GridData(GridData.FILL_HORIZONTAL);
214 ctrl3.setLayoutData(gd);
215
216
217
218 MenuManager mm = new MenuManager();
219 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_SCALETOWEEK));
220 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_SCALETOMONTH));
221 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_SCALETOYEAR));
222 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_CENTERSCALE));
223 _tbv.setScaleContextMenu(mm.createContextMenu(_tbv));
224
225
226 RowContextMenuHandler hierarchyCtxHandler = new HCtxHandler();
227 _tbv.setHierarchyCtxHandler(hierarchyCtxHandler);
228
229
230 TimeBarNode root = model.getRootNode();
231 _tbv.getHierarchicalViewState().setExpandedRecursive(root, true);
232
233
234 _tbv.setRegionRectEnable(true);
235
236
237 MenuManager bodyMM = new MenuManager();
238 bodyMM.add(new ZoomAction(_tbv));
239 bodyMM.add(new ClearRegionAction(_tbv));
240 Menu bodyContextMenu = bodyMM.createContextMenu(_tbv);
241 _tbv.setBodyContextMenu(bodyContextMenu);
242
243
244 MenuManager intervalMM = new MenuManager();
245 intervalMM.add(new DummyAction(_tbv));
246 Menu intervalContextMenu = intervalMM.createContextMenu(_tbv);
247 _tbv.setIntervalContextMenu(intervalContextMenu);
248
249 if (SUPPORT_DND) {
250 initDND(_tbv, parent);
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332 return _tbv;
333 }
334
335 /***
336 * Action that zooms the timeline to the selection if present. It listens to changes on the region selection to
337 * determine its enablement.
338 *
339 * @author kliem
340 * @version $Id: SwtHierachy.java 1083 2011-07-01 20:29:16Z kliem $
341 */
342 public class ZoomAction extends Action implements ISelectionRectListener {
343 private TimeBarViewer _tbv;
344
345 public ZoomAction(TimeBarViewer tbv) {
346 _tbv = tbv;
347 setEnabled(false);
348 _tbv.addSelectionRectListener(this);
349 }
350
351 /***
352 * {@inheritDoc}
353 */
354 public void run() {
355 if (_tbv.getRegionRect() != null) {
356 TBRect tbrect = _tbv.getRegionRect();
357 JaretDate startDate = tbrect.startDate;
358 int seconds = tbrect.endDate.diffSeconds(tbrect.startDate);
359 int pixel = _tbv.getDelegate().getDiagramRect().width;
360 double pps = ((double) pixel) / ((double) seconds);
361 _tbv.clearRegionRect();
362 _tbv.setPixelPerSecond(pps);
363 _tbv.setStartDate(startDate);
364
365 }
366 }
367
368 /***
369 * {@inheritDoc}
370 */
371 public String getText() {
372 return "Zoom to region";
373 }
374
375 public void regionRectChanged(TimeBarViewerDelegate delegate, TBRect tbrect) {
376 setEnabled(true);
377 }
378
379 public void regionRectClosed(TimeBarViewerDelegate delegate) {
380 setEnabled(false);
381 }
382
383 public void selectionRectChanged(TimeBarViewerDelegate delegate, JaretDate beginDate, JaretDate endDate,
384 List<TimeBarRow> rows) {
385
386
387 }
388
389 public void selectionRectClosed(TimeBarViewerDelegate delegate) {
390
391 }
392 }
393
394 /***
395 * Action that clears the region rect.
396 *
397 * @author kliem
398 * @version $Id: SwtHierachy.java 1083 2011-07-01 20:29:16Z kliem $
399 */
400 public class ClearRegionAction extends Action {
401 private TimeBarViewer _tbv;
402
403 public ClearRegionAction(TimeBarViewer tbv) {
404 _tbv = tbv;
405 }
406
407 /***
408 * {@inheritDoc}
409 */
410 public void run() {
411 _tbv.clearRegionRect();
412 }
413
414 /***
415 * {@inheritDoc}
416 */
417 public String getText() {
418 return "Clear region";
419 }
420
421 }
422
423 /***
424 * Simpled dummy action.
425 *
426 * @author kliem
427 * @version $Id: SwtHierachy.java 1083 2011-07-01 20:29:16Z kliem $
428 */
429 public class DummyAction extends Action {
430 private TimeBarViewer _tbv;
431
432 public DummyAction(TimeBarViewer tbv) {
433 _tbv = tbv;
434 }
435
436 /***
437 * {@inheritDoc}
438 */
439 public void run() {
440 System.out.println("dummy action triggered");
441 }
442
443 /***
444 * {@inheritDoc}
445 */
446 public String getText() {
447 return "Dummy action";
448 }
449
450 }
451
452
453 public class HCtxHandler implements RowContextMenuHandler {
454 Menu ctx;
455
456 public HCtxHandler() {
457 MenuManager mm = new MenuManager();
458 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_EXPANDNODE));
459 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_COLLAPSENODE));
460 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_EXPANDALL));
461 mm.add(_tbv.getActionFactory().createStdAction(JaretTimeBarsActionFactory.ACTION_COLLAPSEALL));
462 ctx = mm.createContextMenu(_tbv);
463 }
464
465 public Menu getContextMenu(TimeBarViewer tbv, TimeBarRow row) {
466 return ctx;
467 }
468 }
469
470 protected void configureShell(Shell shell) {
471 super.configureShell(shell);
472 shell.setText(getClass().getName());
473 shell.setSize(800, 800);
474 }
475
476 public static void main(String[] args) {
477 SwtHierachy test = new SwtHierachy();
478 test.setBlockOnOpen(true);
479 test.open();
480 }
481
482 public class LabelProvider implements ILabelProvider {
483 ImageRegistry _imageRegistry;
484
485 public Image getImage(Object element) {
486 if (element instanceof DemoTimeBarNode) {
487 DemoTimeBarNode node = (DemoTimeBarNode) element;
488 return node.isType() ? getImageRegistry().get("true") : getImageRegistry().get("false");
489 } else {
490 return getImageRegistry().get("adding");
491 }
492
493 }
494
495 public String getText(Object element) {
496 if (element instanceof DemoTimeBarNode) {
497 DemoTimeBarNode node = (DemoTimeBarNode) element;
498 return node.getText();
499 } else if (element instanceof DefaultTimeBarNode && VARIABLE_XAXIS) {
500 return "PPS";
501 } else {
502 return "adding node";
503 }
504 }
505
506 public void addListener(ILabelProviderListener listener) {
507 }
508
509 public void dispose() {
510 if (_imageRegistry != null) {
511 _imageRegistry.dispose();
512 }
513 }
514
515 public boolean isLabelProperty(Object element, String property) {
516 return false;
517 }
518
519 public void removeListener(ILabelProviderListener listener) {
520 }
521
522 public ImageRegistry getImageRegistry() {
523 if (_imageRegistry == null) {
524 _imageRegistry = new ImageRegistry();
525 ImageDescriptor imgDesc = new ResourceImageDescriptor("/de/jaret/examples/timebars/hierarchy/true.gif");
526 _imageRegistry.put("true", imgDesc);
527 imgDesc = new ResourceImageDescriptor("/de/jaret/examples/timebars/hierarchy/false.gif");
528 _imageRegistry.put("false", imgDesc);
529 imgDesc = new ResourceImageDescriptor("/de/jaret/examples/timebars/hierarchy/adding.gif");
530 _imageRegistry.put("adding", imgDesc);
531 }
532 return _imageRegistry;
533 }
534 }
535
536
537 private Point _dragStart;
538 private int _startOffsetX;
539 private int _startOffsetY;
540 private JaretDate _dragStartDate;
541 private List<Interval> _draggedIntervals;
542 private List<Integer> _yOffsets;
543 private List<Interval> _origIntervals;
544 private TimeBarRow _draggedRow;
545 private TimeBarNode _parentNode;
546 private boolean _isRowDrag;
547
548 /***
549 * Init the drag source and the drop target for the timebar viewer. Information will be provided as text for
550 * dropping outside the table viewer. Drag&Drop inside the viewer uses instance data to transport the information
551 * about the dragged interval. This example supports dragging all selected intervals and dragging a single row
552 * determined when the drag starts.
553 *
554 * @param tbv timebarviewer
555 * @param parent parent of the timebarviewer (for disposal listening)
556 */
557 private void initDND(final TimeBarViewer tbv, Composite parent) {
558
559 int operations = DND.DROP_MOVE;
560 final DragSource source = new DragSource(tbv, operations);
561
562
563 Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
564 source.setTransfer(types);
565
566 source.addDragListener(new DragSourceListener() {
567 public void dragStart(DragSourceEvent event) {
568
569
570 if (_tbv.isInRowAxis(event.x, event.y)) {
571
572 TimeBarRow row = _tbv.getRowForXY(event.x, event.y);
573 if (row != null && !_tbv.rowLineHit(event.x, event.y)) {
574
575 _isRowDrag = true;
576 _dragStart = new Point(event.x, event.y);
577
578
579
580 _draggedRow = row;
581 _parentNode = getParent(_tbv.getHierarchicalModel().getRootNode(), (TimeBarNode) row);
582
583 } else {
584 event.doit = false;
585 }
586
587 } else {
588
589
590
591
592
593 List<Interval> l = tbv.getIntervalsAt(event.x, event.y);
594 if (l.size() > 0) {
595 Interval interval = l.get(0);
596 JaretDate date = tbv.dateForXY(event.x, event.y);
597 if (Math.abs(date.diffSeconds(interval.getBegin())) < 1000
598 || Math.abs(date.diffSeconds(interval.getEnd())) < 1000) {
599 System.out.println("Near the border of an interval -> no drag");
600 event.doit = false;
601 } else {
602
603 _dragStart = new Point(event.x, event.y);
604 _dragStartDate = _tbv.dateForXY(event.x, event.y);
605 _isRowDrag = false;
606
607 _tbv.getSelectionModel().addSelectedInterval(interval);
608
609
610
611
612
613 _draggedIntervals = new ArrayList<Interval>();
614 _origIntervals = new ArrayList<Interval>();
615 _yOffsets = new ArrayList<Integer>();
616
617 for (Interval i : _tbv.getSelectionModel().getSelectedIntervals()) {
618 _draggedIntervals.add(new IntervalImpl(i.getBegin().copy(), i.getEnd().copy()));
619 _origIntervals.add(i);
620 TimeBarRow row = _tbv.getModel().getRowForInterval(i);
621 int yOffset;
622 if (_tbv.getTBOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
623 yOffset = _tbv.getYForRow(row) - _dragStart.y;
624 } else {
625 yOffset = _tbv.getYForRow(row) - _dragStart.x;
626 }
627 _yOffsets.add(yOffset);
628 }
629
630 TimeBarRow row = _tbv.getRowForXY(event.x, event.y);
631
632 _startOffsetY = event.y - tbv.getYForRow(row);
633 _startOffsetX = event.x - tbv.getYForRow(row);
634 }
635 } else {
636 event.doit = false;
637 }
638 }
639 }
640
641 public void dragSetData(DragSourceEvent event) {
642
643 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
644
645
646
647 if (_isRowDrag) {
648 event.data = "row: " + _draggedRow.getRowHeader().getLabel();
649 } else {
650 StringBuffer buf = new StringBuffer();
651 buf.append("intervals:");
652 for (Interval interval : _origIntervals) {
653 buf.append(interval);
654 buf.append(";");
655 }
656 event.data = buf.toString();
657 }
658 }
659 }
660
661 public void dragFinished(DragSourceEvent event) {
662
663
664 if (event.detail == DND.DROP_MOVE) {
665 System.out.println("Perform move");
666 if (_isRowDrag) {
667 _parentNode.remNode((TimeBarNode) _draggedRow);
668 } else {
669 for (Interval interval : _origIntervals) {
670 DefaultTimeBarRowModel row = (DefaultTimeBarRowModel) _tbv.getModel().getRowForInterval(
671 interval);
672 row.remInterval(interval);
673 }
674 }
675 }
676
677
678 _tbv.deHighlightRow();
679 _tbv.setGhostIntervals(null, null);
680 _tbv.setGhostRows(null, null);
681 _draggedIntervals = null;
682 _draggedRow = null;
683 _isRowDrag = false;
684 _origIntervals = null;
685 }
686
687 });
688
689
690
691
692
693 operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
694 final DropTarget target = new DropTarget(tbv, operations);
695
696
697 final TextTransfer textTransfer = TextTransfer.getInstance();
698 types = new Transfer[] {textTransfer};
699 target.setTransfer(types);
700
701 target.addDropListener(new DropTargetListener() {
702 public void dragEnter(DropTargetEvent event) {
703 }
704
705 public void dragOver(DropTargetEvent event) {
706
707
708 if (_isRowDrag && _draggedRow != null) {
709
710 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
711 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
712 tbv.setGhostRow(_draggedRow, 0);
713 tbv.setGhostOrigin(destX, destY);
714 TimeBarRow overRow = tbv.getRowForXY(destX, destY);
715 if (overRow != null) {
716 tbv.highlightRow(overRow);
717 } else {
718 tbv.deHighlightRow();
719 }
720
721 } else if (!_isRowDrag && _draggedIntervals != null && _draggedIntervals.size() > 0) {
722
723 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
724 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
725
726 JaretDate curDate = _tbv.dateForXY(destX, destY);
727 long diffSeconds = _dragStartDate.diffSeconds(curDate);
728
729 for (int i = 0; i < _draggedIntervals.size(); i++) {
730 Interval orig = _origIntervals.get(i);
731 Interval interval = _draggedIntervals.get(i);
732 interval.setBegin(orig.getBegin().copy().advanceSeconds(-diffSeconds));
733 interval.setEnd(orig.getEnd().copy().advanceSeconds(-diffSeconds));
734 }
735
736
737
738
739 TimeBarRow overRow = tbv.getRowForXY(destX, destY);
740 if (overRow != null) {
741 tbv.highlightRow(overRow);
742 } else {
743 System.out.println("Row is null x,y:" + event.x + "," + event.y);
744 tbv.deHighlightRow();
745 }
746
747 tbv.setGhostIntervals(_draggedIntervals, _yOffsets);
748 tbv.setGhostOrigin(destX, destY);
749 }
750 }
751
752 public void dragOperationChanged(DropTargetEvent event) {
753 }
754
755 public void dragLeave(DropTargetEvent event) {
756
757 tbv.deHighlightRow();
758 tbv.setGhostIntervals(null, null);
759 }
760
761 public void dropAccept(DropTargetEvent event) {
762 }
763
764 public void drop(DropTargetEvent event) {
765
766
767
768
769
770 if (textTransfer.isSupportedType(event.currentDataType)) {
771 String text = (String) event.data;
772 System.out.println("DROP: " + text);
773
774 if (_isRowDrag && _draggedRow != null) {
775 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
776 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
777
778 TimeBarRow overRow = tbv.getRowForXY(destX, destY);
779 System.out.println("over row " + overRow.getRowHeader());
780 if (overRow != null) {
781
782
783
784 _parentNode.remNode((TimeBarNode) _draggedRow);
785 TimeBarNode node = (TimeBarNode) overRow;
786 node.addNode((TimeBarNode) _draggedRow);
787 }
788 } else if (_draggedIntervals != null) {
789
790 for (int i = 0; i < _draggedIntervals.size(); i++) {
791 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
792 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
793 int offY = _yOffsets.get(i);
794 TimeBarRow overRow = null;
795 if (_tbv.getTBOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
796 overRow = tbv.rowForY(destY + offY + _startOffsetY);
797 } else {
798 overRow = tbv.rowForY(destX + offY + _startOffsetX);
799 }
800 if (overRow instanceof DefaultTimeBarRowModel) {
801 DefaultTimeBarRowModel row = (DefaultTimeBarRowModel) overRow;
802 if (overRow != null) {
803 row.addInterval(_draggedIntervals.get(i));
804 }
805 }
806 }
807 }
808 }
809 }
810
811 private DefaultTimeBarRowModel copyDraggedRow() {
812 DefaultRowHeader header = (DefaultRowHeader) _draggedRow.getRowHeader();
813 DefaultTimeBarRowModel row = new DefaultTimeBarRowModel(new DefaultRowHeader(header.getLabel()
814 + "(copy)"));
815 for (Interval interval : _draggedRow.getIntervals()) {
816 row.addInterval(new IntervalImpl(interval.getBegin().copy(), interval.getEnd().copy()));
817 }
818 return row;
819 }
820 });
821
822
823
824
825 parent.addDisposeListener(new DisposeListener() {
826 public void widgetDisposed(DisposeEvent e) {
827 source.dispose();
828 target.dispose();
829 }
830 });
831
832 }
833
834 /***
835 * Removes a node from it's parent node.
836 *
837 * @param model
838 * @param draggedRow
839 */
840 private boolean removeNode(TimeBarNode root, TimeBarNode draggedRow) {
841 if (root.getChildren().contains(draggedRow)) {
842 root.remNode(draggedRow);
843 return true;
844 } else {
845 for (TimeBarNode node : root.getChildren()) {
846 boolean result = removeNode(node, draggedRow);
847 if (result) {
848 return true;
849 }
850 }
851 }
852 return false;
853 }
854
855 private TimeBarNode getParent(TimeBarNode root, TimeBarNode draggedRow) {
856 if (root.getChildren().contains(draggedRow)) {
857 return root;
858 } else {
859 for (TimeBarNode node : root.getChildren()) {
860 TimeBarNode result = getParent(node, draggedRow);
861 if (result != null) {
862 return result;
863 }
864 }
865 }
866 return null;
867 }
868
869 }