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.calendar.swt;
21
22 import java.beans.PropertyChangeListener;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.eclipse.jface.window.ApplicationWindow;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.dnd.DND;
29 import org.eclipse.swt.dnd.DragSource;
30 import org.eclipse.swt.dnd.DragSourceEvent;
31 import org.eclipse.swt.dnd.DragSourceListener;
32 import org.eclipse.swt.dnd.DropTarget;
33 import org.eclipse.swt.dnd.DropTargetEvent;
34 import org.eclipse.swt.dnd.DropTargetListener;
35 import org.eclipse.swt.dnd.TextTransfer;
36 import org.eclipse.swt.dnd.Transfer;
37 import org.eclipse.swt.events.DisposeEvent;
38 import org.eclipse.swt.events.DisposeListener;
39 import org.eclipse.swt.events.MouseAdapter;
40 import org.eclipse.swt.events.MouseEvent;
41 import org.eclipse.swt.graphics.Point;
42 import org.eclipse.swt.graphics.Rectangle;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Control;
47 import org.eclipse.swt.widgets.Display;
48 import org.eclipse.swt.widgets.Shell;
49
50 import de.jaret.examples.timebars.calendar.model.Appointment;
51 import de.jaret.examples.timebars.calendar.model.AppointmentModificator;
52 import de.jaret.examples.timebars.calendar.model.CalendarIntervalFilter;
53 import de.jaret.examples.timebars.calendar.model.CalendarModel;
54 import de.jaret.examples.timebars.calendar.model.Day;
55 import de.jaret.examples.timebars.calendar.model.ModelCreator;
56 import de.jaret.examples.timebars.calendar.swt.renderer.AppointmentRenderer;
57 import de.jaret.examples.timebars.calendar.swt.renderer.CalendarGridRenderer;
58 import de.jaret.examples.timebars.calendar.swt.renderer.CalendarTimeScaleRenderer;
59 import de.jaret.examples.timebars.calendar.swt.renderer.DayHeaderRenderer;
60 import de.jaret.util.date.Interval;
61 import de.jaret.util.date.JaretDate;
62 import de.jaret.util.ui.timebars.TimeBarRowFilter;
63 import de.jaret.util.ui.timebars.TimeBarViewerDelegate;
64 import de.jaret.util.ui.timebars.TimeBarViewerInterface;
65 import de.jaret.util.ui.timebars.model.DefaultTimeBarRowModel;
66 import de.jaret.util.ui.timebars.model.TimeBarModel;
67 import de.jaret.util.ui.timebars.model.TimeBarRow;
68 import de.jaret.util.ui.timebars.strategy.OverlapInfo;
69 import de.jaret.util.ui.timebars.swt.TimeBarViewer;
70
71 /***
72 * SWT: example demonstrating the vertical orientation showing a calendar view.
73 *
74 * @author Peter Kliem
75 * @version $Id: SwtCalendarExample.java 1104 2012-02-07 22:03:30Z kliem $
76 */
77 public class SwtCalendarExample extends ApplicationWindow {
78 private static TimeBarViewer _tbv;
79
80 public SwtCalendarExample() {
81 super(null);
82 }
83
84 protected Control createContents(Composite parent) {
85 GridLayout gridLayout = new GridLayout();
86 gridLayout.numColumns = 1;
87 parent.setLayout(gridLayout);
88
89 TimeBarModel model = ModelCreator.createCalendarModel();
90
91 GridData gd = new GridData(GridData.FILL_BOTH);
92
93 _tbv = new TimeBarViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);
94 _tbv.setLayoutData(gd);
95
96 _tbv.setTimeScalePosition(TimeBarViewer.TIMESCALE_POSITION_TOP);
97 _tbv.setModel(model);
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 _tbv.setPixelPerSecond(0.018);
121 _tbv.setDrawRowGrid(true);
122
123 _tbv.setSelectionDelta(6);
124
125 _tbv.setRowHeight(150);
126
127 _tbv.setTBOrientation(TimeBarViewerInterface.Orientation.VERTICAL);
128
129 _tbv.setYAxisWidth(20);
130
131
132
133 _tbv.setAdjustMinMaxDatesByModel(false);
134 _tbv.setMinDate(CalendarModel.BASEDATE.copy());
135 _tbv.setMaxDate(CalendarModel.BASEDATE.copy().advanceDays(1));
136
137
138 _tbv.setHeaderRenderer(new DayHeaderRenderer());
139
140
141 _tbv.setTimeScaleRenderer(new CalendarTimeScaleRenderer());
142
143
144 AppointmentRenderer ar = new AppointmentRenderer();
145 _tbv.registerTimeBarRenderer(Appointment.class, ar);
146
147
148 _tbv.addIntervalModificator(new AppointmentModificator());
149
150 _tbv.setGridRenderer(new CalendarGridRenderer());
151
152 CalendarControlPanel ctrl = new CalendarControlPanel(parent, SWT.NULL, _tbv, null);
153 gd = new GridData(GridData.FILL_HORIZONTAL);
154 ctrl.setLayoutData(gd);
155
156
157
158 _tbv.addMouseListener(new MouseAdapter() {
159 public void mouseDoubleClick(MouseEvent e) {
160 List<Interval> intervals = _tbv.getIntervalsAt(e.x, e.y);
161 if (intervals != null && intervals.size() > 0) {
162 for (Interval interval : intervals) {
163 System.out.println("Doubleclicked: " + interval.toString());
164 }
165 }
166 }
167 });
168
169 initDND(_tbv, parent);
170
171 _tbv.setIntervalFilter(new CalendarIntervalFilter());
172 _tbv.setYAxisWidth(50);
173
174 return _tbv;
175 }
176
177
178 private Point _dragStart;
179 private int _startOffsetX;
180 private int _startOffsetY;
181 private JaretDate _dragStartDate;
182 private List<Interval> _draggedIntervals;
183 private List<Integer> _yOffsets;
184 private List<Interval> _origIntervals;
185 private List<TimeBarRow> _origRows;
186 private TimeBarRow _draggedRow;
187 private boolean _isRowDrag;
188 int _lastDragOverX;
189 int _lastDragOverY;
190
191 /***
192 * Init the drag source and the drop target for the timebar viewer. Information will be provided as text for
193 * dropping outside the table viewer. Drag&Drop inside the viewer uses instance data to transport the information
194 * about the dragged intervals.
195 *
196 * @param tbv timebarviewer
197 * @param parent parent of the timebarviewer (for disposal listening)
198 */
199 private void initDND(final TimeBarViewer tbv, Composite parent) {
200
201 int operations = DND.DROP_COPY | DND.DROP_MOVE;
202 final DragSource source = new DragSource(tbv, operations);
203
204
205 Transfer[] types = new Transfer[] {TextTransfer.getInstance()};
206 source.setTransfer(types);
207
208 source.addDragListener(new DragSourceListener() {
209 public void dragStart(DragSourceEvent event) {
210 boolean horizontal = _tbv.getTBOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL);
211 TimeBarViewerDelegate delegate = (TimeBarViewerDelegate) _tbv.getData("delegate");
212
213
214 if (_tbv.isInDiagram(event.x, event.y)) {
215 List<Interval> l = tbv.getIntervalsAt(event.x, event.y);
216 if (l.size() > 0) {
217 Interval interval = l.get(0);
218
219 TimeBarRow clickedRow = _tbv.getModel().getRowForInterval(interval);
220 OverlapInfo oi = delegate.getOverlapStrategy().getOverlapInfo(clickedRow, interval);
221 boolean overlap = oi != null ? oi.overlappingCount > 0 : false;
222
223 Rectangle bounds = _tbv.getIntervalBounds(interval);
224 if (AppointmentRenderer.isInDragMark(bounds, event.x, event.y, horizontal, overlap)) {
225
226 _dragStart = new Point(event.x, event.y);
227 _dragStartDate = _tbv.dateForXY(event.x, event.y);
228 _isRowDrag = false;
229
230 _tbv.getSelectionModel().addSelectedInterval(interval);
231
232
233
234
235
236 _draggedIntervals = new ArrayList<Interval>();
237 _origIntervals = new ArrayList<Interval>();
238 _origRows = new ArrayList<TimeBarRow>();
239 _yOffsets = new ArrayList<Integer>();
240
241 for (Interval i : _tbv.getSelectionModel().getSelectedIntervals()) {
242 _draggedIntervals.add(((Appointment) i).copy());
243 TimeBarRow row = _tbv.getModel().getRowForInterval(i);
244 _origIntervals.add(i);
245 _origRows.add(row);
246
247 int yOffset;
248 if (_tbv.getTBOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
249 yOffset = _tbv.getYForRow(row) - _dragStart.y;
250 } else {
251 yOffset = _tbv.getYForRow(row) - _dragStart.x;
252 }
253 _yOffsets.add(yOffset);
254 }
255
256 TimeBarRow row = _tbv.getRowForXY(event.x, event.y);
257
258 _startOffsetY = event.y - tbv.getYForRow(row);
259 _startOffsetX = event.x - tbv.getYForRow(row);
260 return;
261 }
262 }
263 }
264 event.doit = false;
265 }
266
267 public void dragSetData(DragSourceEvent event) {
268
269 if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
270
271
272
273 if (_isRowDrag) {
274 event.data = "row: " + _draggedRow.getRowHeader().getLabel();
275 } else {
276 StringBuffer buf = new StringBuffer();
277 buf.append("intervals:");
278 for (Interval interval : _origIntervals) {
279 buf.append(interval);
280 buf.append(";");
281 }
282 event.data = buf.toString();
283 }
284 }
285 }
286
287 public void dragFinished(DragSourceEvent event) {
288
289
290 if (event.detail == DND.DROP_MOVE) {
291 System.out.println("Perform move");
292 for (Interval interval : _origIntervals) {
293 DefaultTimeBarRowModel row = (DefaultTimeBarRowModel) _tbv.getModel().getRowForInterval(
294 interval);
295 row.remInterval(interval);
296 }
297 }
298
299
300 _tbv.deHighlightRow();
301 _tbv.setGhostIntervals(null, null);
302 _tbv.setGhostRows(null, null);
303 _draggedIntervals = null;
304 _draggedRow = null;
305 _isRowDrag = false;
306 _origIntervals = null;
307 _origRows = null;
308 }
309 });
310
311
312
313
314
315 operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
316 final DropTarget target = new DropTarget(tbv, operations);
317
318
319 final TextTransfer textTransfer = TextTransfer.getInstance();
320 types = new Transfer[] {textTransfer};
321 target.setTransfer(types);
322
323 target.addDropListener(new DropTargetListener() {
324 public void dragEnter(DropTargetEvent event) {
325 }
326
327 public void dragOver(DropTargetEvent event) {
328
329
330
331 if (event.x != _lastDragOverX || event.y != _lastDragOverY) {
332 _lastDragOverX = event.x;
333 _lastDragOverY = event.y;
334
335
336
337 if (!_isRowDrag && _draggedIntervals != null && _draggedIntervals.size() > 0) {
338
339 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
340 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
341
342 JaretDate curDate = _tbv.dateForXY(destX, destY);
343 long diffSeconds = _dragStartDate.diffSeconds(curDate);
344
345 for (int i = 0; i < _draggedIntervals.size(); i++) {
346 Interval orig = _origIntervals.get(i);
347 Interval interval = _draggedIntervals.get(i);
348 interval.setBegin(orig.getBegin().copy().advanceSeconds(-diffSeconds));
349 interval.setEnd(orig.getEnd().copy().advanceSeconds(-diffSeconds));
350 }
351
352
353
354
355 TimeBarRow overRow = tbv.getRowForXY(destX, destY);
356 if (overRow != null) {
357 tbv.highlightRow(overRow);
358 } else {
359 System.out.println("Row is null x,y:" + event.x + "," + event.y);
360 tbv.deHighlightRow();
361 }
362
363 tbv.setGhostIntervals(_draggedIntervals, _yOffsets);
364 tbv.setGhostOrigin(destX, destY);
365 }
366 }
367 }
368
369 public void dragOperationChanged(DropTargetEvent event) {
370 }
371
372 public void dragLeave(DropTargetEvent event) {
373
374 tbv.deHighlightRow();
375 tbv.setGhostIntervals(null, null);
376 }
377
378 public void dropAccept(DropTargetEvent event) {
379 }
380
381 public void drop(DropTargetEvent event) {
382
383
384 if (textTransfer.isSupportedType(event.currentDataType)) {
385 String text = (String) event.data;
386 System.out.println("DROP: " + text);
387
388 if (_draggedIntervals != null) {
389 for (int i = 0; i < _draggedIntervals.size(); i++) {
390 int destY = Display.getCurrent().map(null, tbv, event.x, event.y).y;
391 int destX = Display.getCurrent().map(null, tbv, event.x, event.y).x;
392 int offY = _yOffsets.get(i);
393 TimeBarRow overRow = null;
394 if (_tbv.getTBOrientation().equals(TimeBarViewerInterface.Orientation.HORIZONTAL)) {
395 overRow = tbv.rowForY(destY + offY + _startOffsetY);
396 } else {
397 overRow = tbv.rowForY(destX + offY + _startOffsetX);
398 }
399 DefaultTimeBarRowModel row = (DefaultTimeBarRowModel) overRow;
400
401
402 if (overRow != null) {
403 row.addInterval(_draggedIntervals.get(i));
404 Appointment app = (Appointment) _draggedIntervals.get(i);
405 Day destDay = (Day) overRow;
406 JaretDate realBegin = app.getRealBegin().copy();
407 realBegin.setDate(destDay.getDayDate().getDay(), destDay.getDayDate().getMonth(),
408 destDay.getDayDate().getYear());
409 app.setRealBegin(realBegin);
410 JaretDate realEnd = app.getRealEnd().copy();
411 realEnd.setDate(destDay.getDayDate().getDay(), destDay.getDayDate().getMonth(), destDay
412 .getDayDate().getYear());
413 app.setRealEnd(realEnd);
414
415 }
416 }
417 }
418 }
419 }
420
421 });
422
423
424
425
426 parent.addDisposeListener(new DisposeListener() {
427 public void widgetDisposed(DisposeEvent e) {
428 source.dispose();
429 target.dispose();
430 }
431 });
432
433 }
434
435 protected void configureShell(Shell shell) {
436 super.configureShell(shell);
437 shell.setText(getClass().getName());
438 }
439
440 public static void main(String[] args) {
441 SwtCalendarExample test = new SwtCalendarExample();
442 test.setBlockOnOpen(true);
443 test.open();
444 }
445
446 }