tmf: Fix remaining Java warnings in tmf.ui
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / virtualtable / TmfVirtualTable.java
CommitLineData
9ccc6d01
FC
1/*******************************************************************************
2 * Copyright (c) 2010 Ericsson
3934297e 3 *
9ccc6d01
FC
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
3934297e 8 *
9ccc6d01
FC
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
3934297e 11 * Francois Chouinard - Refactoring, slider support, bug fixing
b21305c2 12 * Patrick Tasse - Improvements and bug fixing
7cc11afa 13 * Xavier Raynaud - Improvements
9ccc6d01
FC
14 ******************************************************************************/
15
fb5cad3d 16package org.eclipse.linuxtools.tmf.ui.widgets.virtualtable;
9ccc6d01 17
8fd82db5 18import org.eclipse.linuxtools.internal.tmf.ui.Activator;
9ccc6d01 19import org.eclipse.swt.SWT;
b21305c2 20import org.eclipse.swt.custom.TableEditor;
9ccc6d01
FC
21import org.eclipse.swt.events.ControlAdapter;
22import org.eclipse.swt.events.ControlEvent;
23import org.eclipse.swt.events.KeyEvent;
24import org.eclipse.swt.events.KeyListener;
25import org.eclipse.swt.events.MouseEvent;
b21305c2 26import org.eclipse.swt.events.MouseListener;
9ccc6d01
FC
27import org.eclipse.swt.events.MouseWheelListener;
28import org.eclipse.swt.events.SelectionAdapter;
29import org.eclipse.swt.events.SelectionEvent;
b21305c2
FC
30import org.eclipse.swt.events.SelectionListener;
31import org.eclipse.swt.graphics.Point;
7800a42f
XR
32import org.eclipse.swt.graphics.Rectangle;
33import org.eclipse.swt.layout.FillLayout;
9ccc6d01
FC
34import org.eclipse.swt.layout.GridData;
35import org.eclipse.swt.layout.GridLayout;
36import org.eclipse.swt.widgets.Composite;
b21305c2
FC
37import org.eclipse.swt.widgets.Control;
38import org.eclipse.swt.widgets.Display;
9ccc6d01 39import org.eclipse.swt.widgets.Event;
7800a42f 40import org.eclipse.swt.widgets.Label;
9ccc6d01 41import org.eclipse.swt.widgets.Listener;
b21305c2 42import org.eclipse.swt.widgets.Menu;
7800a42f 43import org.eclipse.swt.widgets.Shell;
9ccc6d01
FC
44import org.eclipse.swt.widgets.Slider;
45import org.eclipse.swt.widgets.Table;
46import org.eclipse.swt.widgets.TableColumn;
47import org.eclipse.swt.widgets.TableItem;
7800a42f 48import org.eclipse.ui.PlatformUI;
9ccc6d01
FC
49
50/**
51 * <b><u>TmfVirtualTable</u></b>
52 * <p>
53 * TmfVirtualTable allows for the tabular display of arbitrarily large data sets
54 * (well, up to Integer.MAX_VALUE or ~2G rows).
3934297e 55 *
9ccc6d01
FC
56 * It is essentially a Composite of Table and Slider, where the number of rows
57 * in the table is set to fill the table display area. The slider is rank-based.
3934297e 58 *
9ccc6d01
FC
59 * It differs from Table with the VIRTUAL style flag where an empty entry is
60 * created for each virtual row. This does not scale well for very large data sets.
3934297e 61 *
b21305c2
FC
62 * Styles:
63 * H_SCROLL, V_SCROLL, SINGLE, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL
02023181 64 * @author Matthew Khouzam, Francois Chouinard, Patrick Tasse, Xavier Raynaud
3934297e 65 * @version $Revision: 1.0
9ccc6d01
FC
66 */
67public class TmfVirtualTable extends Composite {
68
631d853f 69 // The table
02023181
MK
70 /**
71 * Field fTable.
72 */
631d853f 73 private Table fTable;
02023181
MK
74 /**
75 * Field fTableRows.
76 */
631d853f 77 private int fTableRows = 0; // Number of table rows
02023181
MK
78 /**
79 * Field fFullyVisibleRows.
80 */
631d853f 81 private int fFullyVisibleRows = 0; // Number of fully visible table rows
02023181
MK
82 /**
83 * Field fFrozenRowCount.
84 */
631d853f
PT
85 private int fFrozenRowCount = 0; // Number of frozen table rows at top of table
86
02023181
MK
87 /**
88 * Field fTableTopEventRank.
89 */
631d853f 90 private int fTableTopEventRank = 0; // Global rank of the first entry displayed
02023181
MK
91 /**
92 * Field fSelectedEventRank.
93 */
631d853f 94 private int fSelectedEventRank = 0; // Global rank of the selected event
02023181
MK
95 /**
96 * Field fPendingSelection.
97 */
631d853f
PT
98 private boolean fPendingSelection = false; // Pending selection update
99
02023181
MK
100 /**
101 * Field fTableItemCount.
102 */
631d853f
PT
103 private int fTableItemCount = 0;
104
105 // The slider
02023181
MK
106 /**
107 * Field fSlider.
108 */
631d853f
PT
109 private Slider fSlider;
110
02023181
MK
111 /**
112 * Field fLinuxItemHeight.
113 */
631d853f 114 private int fLinuxItemHeight = 0; // Calculated item height for Linux workaround
02023181
MK
115 /**
116 * Field tooltipProvider.
117 */
631d853f 118 private TooltipProvider tooltipProvider = null;
02023181
MK
119 /**
120 * Field doubleClickListener.
121 */
631d853f
PT
122 private IDoubleClickListener doubleClickListener = null;
123
124 // ------------------------------------------------------------------------
125 // Constructor
126 // ------------------------------------------------------------------------
127
128 /**
3934297e
AM
129 * Standard constructor
130 *
631d853f 131 * @param parent
3934297e 132 * The parent composite object
631d853f 133 * @param style
3934297e 134 * The style to use
631d853f
PT
135 */
136 public TmfVirtualTable(Composite parent, int style) {
137 super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL) & (~SWT.SINGLE) & (~SWT.FULL_SELECTION) & (~SWT.HIDE_SELECTION) & (~SWT.CHECK));
138
139 // Create the controls
140 createTable(style & (SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.CHECK));
141 createSlider(style & SWT.V_SCROLL);
142
143 // Prevent the slider from being traversed
144 setTabList(new Control[] { fTable });
145
146 // Set the layout
147 GridLayout gridLayout = new GridLayout();
148 gridLayout.numColumns = 2;
149 gridLayout.horizontalSpacing = 0;
150 gridLayout.verticalSpacing = 0;
151 gridLayout.marginWidth = 0;
152 gridLayout.marginHeight = 0;
153 setLayout(gridLayout);
154
155 GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
156 fTable.setLayoutData(tableGridData);
157
158 GridData sliderGridData = new GridData(SWT.FILL, SWT.FILL, false, true);
159 fSlider.setLayoutData(sliderGridData);
160
161 // Add the listeners
162 fTable.addMouseWheelListener(new MouseWheelListener() {
163 @Override
164 public void mouseScrolled(MouseEvent event) {
165 if (fTableItemCount <= fFullyVisibleRows) {
166 return;
167 }
168 fTableTopEventRank -= event.count;
169 if (fTableTopEventRank < 0) {
170 fTableTopEventRank = 0;
171 }
172 int latestFirstRowOffset = fTableItemCount - fFullyVisibleRows;
173 if (fTableTopEventRank > latestFirstRowOffset) {
174 fTableTopEventRank = latestFirstRowOffset;
175 }
176
177 fSlider.setSelection(fTableTopEventRank);
178 refreshTable();
179 }
180 });
181
182 fTable.addListener(SWT.MouseWheel, new Listener() {
183 // disable mouse scroll of horizontal scroll bar
184 @Override
b21305c2 185 public void handleEvent(Event event) {
631d853f
PT
186 event.doit = false;
187 }
188 });
189
190 fTable.addControlListener(new ControlAdapter() {
191 @Override
192 public void controlResized(ControlEvent event) {
193 int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight());
194 fFullyVisibleRows = tableHeight / getItemHeight();
195 if (fTableItemCount > 0) {
196 fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows)));
197 }
198 }
199 });
200 // Implement a "fake" tooltip
201 final String TOOLTIP_DATA_KEY = "_TABLEITEM"; //$NON-NLS-1$
202 final Listener labelListener = new Listener () {
203 @Override
f4c52cea 204 public void handleEvent (Event event) {
631d853f
PT
205 Label label = (Label)event.widget;
206 Shell shell = label.getShell ();
207 switch (event.type) {
208 case SWT.MouseDown:
209 Event e = new Event ();
210 e.item = (TableItem) label.getData (TOOLTIP_DATA_KEY);
211 // Assuming table is single select, set the selection as if
212 // the mouse down event went through to the table
213 fTable.setSelection (new TableItem [] {(TableItem) e.item});
214 fTable.notifyListeners (SWT.Selection, e);
215 shell.dispose ();
216 fTable.setFocus();
217 break;
218 case SWT.MouseExit:
219 case SWT.MouseWheel:
220 shell.dispose ();
221 break;
abbdd66a
AM
222 default:
223 break;
631d853f
PT
224 }
225 }
226 };
227
228 Listener tableListener = new Listener () {
229 Shell tip = null;
230 Label label = null;
231 @Override
f4c52cea 232 public void handleEvent (Event event) {
631d853f
PT
233 switch (event.type) {
234 case SWT.Dispose:
235 case SWT.KeyDown:
236 case SWT.MouseMove: {
420bceb2
PT
237 if (tip == null) {
238 break;
239 }
631d853f
PT
240 tip.dispose ();
241 tip = null;
242 label = null;
243 break;
244 }
245 case SWT.MouseHover: {
246 TableItem item = fTable.getItem (new Point(event.x, event.y));
247 if (item != null) {
420bceb2 248 for (int i=0; i < fTable.getColumnCount(); i++) {
631d853f
PT
249 Rectangle bounds = item.getBounds(i);
250 if (bounds.contains(event.x,event.y)){
420bceb2
PT
251 if (tip != null && !tip.isDisposed()) {
252 tip.dispose();
253 }
631d853f
PT
254 if (tooltipProvider == null) {
255 return;
631d853f 256 }
abbdd66a
AM
257 String tooltipText = tooltipProvider.getTooltip(i, item.getData());
258 if (tooltipText == null) {
259 return;
260 }
261 tip = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
262 tip.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
263 FillLayout layout = new FillLayout();
264 layout.marginWidth = 2;
265 tip.setLayout(layout);
266 label = new Label(tip, SWT.WRAP);
267 label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
268 label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
269 label.setData(TOOLTIP_DATA_KEY, item);
270 label.setText(tooltipText);
271
272 label.addListener(SWT.MouseExit, labelListener);
273 label.addListener(SWT.MouseDown, labelListener);
274 label.addListener(SWT.MouseWheel, labelListener);
275 Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
276 Point pt = fTable.toDisplay(bounds.x, bounds.y);
277 tip.setBounds(pt.x, pt.y, size.x, size.y);
278 tip.setVisible(true);
631d853f
PT
279 }
280 }
281 }
abbdd66a 282 break;
631d853f 283 }
abbdd66a
AM
284 default:
285 break;
631d853f
PT
286 }
287 }
288 };
289 fTable.addListener(SWT.Dispose, tableListener);
290 fTable.addListener(SWT.KeyDown, tableListener);
291 fTable.addListener(SWT.MouseMove, tableListener);
292 fTable.addListener(SWT.MouseHover, tableListener);
293 addControlListener(new ControlAdapter() {
294 @Override
295 public void controlResized(ControlEvent event) {
296 resize();
420bceb2
PT
297 if (fTableItemCount > 0) {
298 fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows)));
299 }
631d853f
PT
300 }
301 });
302
303 // And display
304 refresh();
305 }
306
307 // ------------------------------------------------------------------------
308 // Table handling
309 // ------------------------------------------------------------------------
310
311 /**
312 * Create the table and add listeners
02023181 313 * @param style int can be H_SCROLL, V_SCROLL, SINGLE, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL
631d853f
PT
314 */
315 private void createTable(int style) {
316 fTable = new Table(this, style | SWT.NO_SCROLL);
317
318 fTable.addSelectionListener(new SelectionAdapter() {
319 @Override
320 public void widgetSelected(SelectionEvent event) {
321 if (fTable.getSelectionIndices().length > 0) {
322 handleTableSelection();
323 }
324 }
325 });
9ccc6d01 326
2cc874d6 327 fTable.addKeyListener(new KeyListener() {
631d853f
PT
328 @Override
329 public void keyPressed(KeyEvent event) {
330 handleTableKeyEvent(event);
331 }
332 @Override
333 public void keyReleased(KeyEvent event) {
334 }
335 });
7800a42f
XR
336
337 fTable.addListener(
631d853f
PT
338 SWT.MouseDoubleClick, new Listener() {
339 @Override
340 public void handleEvent(Event event) {
341 if (doubleClickListener != null) {
342 TableItem item = fTable.getItem (new Point (event.x, event.y));
343 if (item != null) {
344 for(int i=0;i<fTable.getColumnCount();i++){
345 Rectangle bounds = item.getBounds(i);
346 if (bounds.contains(event.x,event.y)){
347 doubleClickListener.handleDoubleClick(TmfVirtualTable.this, item, i);
348 break;
349 }
350 }
351 }
352 }
353 }
354 }
355 );
356 }
357
358 /**
359 * Update the rows and selected item
360 */
361 private void handleTableSelection() {
362 int selectedRow = fTable.getSelectionIndices()[0];
363 if (selectedRow < fFrozenRowCount) {
364 fSelectedEventRank = selectedRow;
365 } else {
366 fSelectedEventRank = fTableTopEventRank + selectedRow;
367 }
368
369 /*
370 * Feature in Windows. When a partially visible table item is selected,
371 * after ~500 ms the top index is changed to ensure the selected item is
372 * fully visible. This leaves a blank space at the bottom of the virtual
373 * table. The workaround is to update the top event rank, refresh the
374 * table and reset the top index to 0 after a sufficient delay.
375 */
376 if (selectedRow >= fFullyVisibleRows) {
377 final Display display = fTable.getDisplay();
378 Thread thread = new Thread("Top index check") { //$NON-NLS-1$
379 @Override
380 public void run() {
381 try {
382 Thread.sleep(600);
383 } catch (InterruptedException e) {
384 }
385 display.asyncExec(new Runnable() {
386 @Override
b21305c2 387 public void run() {
420bceb2
PT
388 if (fTable.isDisposed()) {
389 return;
390 }
631d853f
PT
391 int topIndex = fTable.getTopIndex();
392 if (topIndex != 0) {
393 fTableTopEventRank += topIndex;
394 refreshTable();
395 fSlider.setSelection(fTableTopEventRank);
396 fTable.setTopIndex(0);
397 }
398 }
399 });
400 }
401 };
402 thread.start();
403 }
404 }
405
406 /**
407 * Handle key-based navigation in table.
3934297e 408 *
631d853f
PT
409 * @param event
410 */
411 private void handleTableKeyEvent(KeyEvent event) {
412
413 int lastEventRank = fTableItemCount - 1;
414 int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
415
416 int previousSelectedEventRank = fSelectedEventRank;
417 int selectedRow = fSelectedEventRank - fTableTopEventRank;
418 boolean needsRefresh = false;
419
420 // In all case, perform the following steps:
421 // - Update the selected entry rank (within valid range)
422 // - Update the selected row
423 // - Update the page's top entry if necessary (which also adjusts the selected row)
424 // - If the top displayed entry was changed, table refresh is needed
425 switch (event.keyCode) {
426
427 case SWT.ARROW_DOWN: {
428 event.doit = false;
429 if (fSelectedEventRank < lastEventRank) {
430 fSelectedEventRank++;
431 selectedRow = fSelectedEventRank - fTableTopEventRank;
75c271cf 432 if (selectedRow == fFullyVisibleRows) {
631d853f
PT
433 fTableTopEventRank++;
434 needsRefresh = true;
75c271cf
PT
435 } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) {
436 fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank));
437 needsRefresh = true;
631d853f
PT
438 }
439 }
440 break;
441 }
442
443 case SWT.ARROW_UP: {
444 event.doit = false;
445 if (fSelectedEventRank > 0) {
446 fSelectedEventRank--;
447 selectedRow = fSelectedEventRank - fTableTopEventRank;
75c271cf 448 if (selectedRow == fFrozenRowCount - 1 && fTableTopEventRank > 0) {
631d853f
PT
449 fTableTopEventRank--;
450 needsRefresh = true;
75c271cf
PT
451 } else if (selectedRow < fFrozenRowCount || selectedRow > fFullyVisibleRows) {
452 fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank));
453 needsRefresh = true;
631d853f
PT
454 }
455 }
456 break;
457 }
458
459 case SWT.END: {
460 event.doit = false;
461 fTableTopEventRank = lastPageTopEntryRank;
462 fSelectedEventRank = lastEventRank;
463 needsRefresh = true;
464 break;
465 }
466
467 case SWT.HOME: {
468 event.doit = false;
469 fSelectedEventRank = fFrozenRowCount;
470 fTableTopEventRank = 0;
471 needsRefresh = true;
472 break;
473 }
474
475 case SWT.PAGE_DOWN: {
476 event.doit = false;
477 if (fSelectedEventRank < lastEventRank) {
478 fSelectedEventRank += fFullyVisibleRows;
479 if (fSelectedEventRank > lastEventRank) {
480 fSelectedEventRank = lastEventRank;
481 }
482 selectedRow = fSelectedEventRank - fTableTopEventRank;
75c271cf 483 if (selectedRow > fFullyVisibleRows + fFrozenRowCount - 1 && selectedRow < 2 * fFullyVisibleRows) {
631d853f
PT
484 fTableTopEventRank += fFullyVisibleRows;
485 if (fTableTopEventRank > lastPageTopEntryRank) {
486 fTableTopEventRank = lastPageTopEntryRank;
487 }
488 needsRefresh = true;
75c271cf
PT
489 } else if (selectedRow < fFrozenRowCount || selectedRow >= 2 * fFullyVisibleRows) {
490 fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank));
491 needsRefresh = true;
631d853f
PT
492 }
493 }
494 break;
495 }
496
497 case SWT.PAGE_UP: {
498 event.doit = false;
499 if (fSelectedEventRank > 0) {
500 fSelectedEventRank -= fFullyVisibleRows;
501 if (fSelectedEventRank < fFrozenRowCount) {
502 fSelectedEventRank = fFrozenRowCount;
503 }
504 selectedRow = fSelectedEventRank - fTableTopEventRank;
75c271cf 505 if (selectedRow < fFrozenRowCount && selectedRow > -fFullyVisibleRows) {
631d853f
PT
506 fTableTopEventRank -= fFullyVisibleRows;
507 if (fTableTopEventRank < 0) {
508 fTableTopEventRank = 0;
509 }
510 needsRefresh = true;
75c271cf
PT
511 } else if (selectedRow <= -fFullyVisibleRows || selectedRow >= fFullyVisibleRows) {
512 fTableTopEventRank = Math.max(0, Math.min(fSelectedEventRank - fFrozenRowCount, lastPageTopEntryRank));
513 needsRefresh = true;
631d853f
PT
514 }
515 }
516 break;
517 }
518 default: {
519 return;
520 }
521 }
522
523 boolean done = true;
524 if (needsRefresh) {
525 done = refreshTable(); // false if table items not updated yet in this thread
526 } else {
527 fTable.select(selectedRow);
528 }
529
530 if (fFullyVisibleRows < fTableItemCount) {
531 fSlider.setSelection(fTableTopEventRank);
532 }
533
420bceb2 534 if (fSelectedEventRank != previousSelectedEventRank && fSelectedEventRank < fTableItemCount) {
631d853f
PT
535 if (done) {
536 Event e = new Event();
537 e.item = fTable.getSelection()[0];
538 fTable.notifyListeners(SWT.Selection, e);
539 } else {
540 fPendingSelection = true;
541 }
542 }
543 }
544
02023181
MK
545 /**
546 * Method setDataItem.
547 * @param index int
548 * @param item TableItem
549 * @return boolean
550 */
631d853f
PT
551 private boolean setDataItem(int index, TableItem item) {
552 if (index != -1) {
553 Event event = new Event();
554 event.item = item;
555 if (index < fFrozenRowCount) {
556 event.index = index;
557 } else {
558 event.index = index + fTableTopEventRank;
559 }
560 event.doit = true;
561 fTable.notifyListeners(SWT.SetData, event);
562 return event.doit; // false if table item not updated yet in this thread
563 }
564 return true;
565 }
566
567 // ------------------------------------------------------------------------
568 // Slider handling
569 // ------------------------------------------------------------------------
570
02023181
MK
571 /**
572 * Method createSlider.
573 * @param style int
574 */
631d853f
PT
575 private void createSlider(int style) {
576 fSlider = new Slider(this, SWT.VERTICAL | SWT.NO_FOCUS);
577 fSlider.setMinimum(0);
578 fSlider.setMaximum(0);
579 if ((style & SWT.V_SCROLL) == 0) {
580 fSlider.setVisible(false);
581 }
582
583 fSlider.addListener(SWT.Selection, new Listener() {
584 @Override
585 public void handleEvent(Event event) {
586 switch (event.detail) {
587 case SWT.ARROW_DOWN:
588 case SWT.ARROW_UP:
589 case SWT.NONE:
590 case SWT.END:
591 case SWT.HOME:
592 case SWT.PAGE_DOWN:
593 case SWT.PAGE_UP: {
594 fTableTopEventRank = fSlider.getSelection();
595 refreshTable();
596 break;
597 }
abbdd66a
AM
598 default:
599 break;
631d853f
PT
600 }
601 }
602 });
603 }
604
605 // ------------------------------------------------------------------------
606 // Simulated Table API
607 // ------------------------------------------------------------------------
608
02023181
MK
609 /**
610 * Method setHeaderVisible.
611 * @param b boolean
612 */
631d853f
PT
613 public void setHeaderVisible(boolean b) {
614 fTable.setHeaderVisible(b);
615 }
616
02023181
MK
617 /**
618 * Method setLinesVisible.
619 * @param b boolean
620 */
631d853f
PT
621 public void setLinesVisible(boolean b) {
622 fTable.setLinesVisible(b);
623 }
624
02023181 625 /**
3934297e 626 * Method getSelection.
02023181
MK
627 * @return TableItem[] the items that are selected.
628 */
631d853f
PT
629 public TableItem[] getSelection() {
630 return fTable.getSelection();
631 }
632
02023181
MK
633 /**
634 * Method addListener.
635 * @param eventType int
636 * @param listener Listener
637 */
631d853f 638 @Override
828e5592
PT
639 public void addListener(int eventType, Listener listener) {
640 fTable.addListener(eventType, listener);
641 }
631d853f 642
02023181
MK
643 /**
644 * Method addKeyListener.
645 * @param listener KeyListener
646 */
631d853f
PT
647 @Override
648 public void addKeyListener(KeyListener listener) {
649 fTable.addKeyListener(listener);
650 }
b21305c2 651
828e5592 652
02023181
MK
653 /**
654 * Method addMouseListener.
655 * @param listener MouseListener
656 */
828e5592 657 @Override
631d853f
PT
658 public void addMouseListener(MouseListener listener) {
659 fTable.addMouseListener(listener);
660 }
661
02023181
MK
662 /**
663 * Method addSelectionListener.
664 * @param listener SelectionListener
665 */
631d853f
PT
666 public void addSelectionListener(SelectionListener listener) {
667 fTable.addSelectionListener(listener);
668 }
669
02023181
MK
670 /**
671 * Method setMenu sets the menu
672 * @param menu Menu the menu
673 */
631d853f
PT
674 @Override
675 public void setMenu(Menu menu) {
676 fTable.setMenu(menu);
677 }
678
48da630d
XR
679 /**
680 * Gets the menu of this table
681 * @return a Menu
682 */
683 @Override
684 public Menu getMenu() {
685 return fTable.getMenu();
686 }
687
02023181 688 /**
3934297e 689 * Method clearAll empties a table.
02023181 690 */
631d853f
PT
691 public void clearAll() {
692 setItemCount(0);
693 }
694
02023181
MK
695 /**
696 * Method setItemCount
697 * @param nbItems int the number of items in the table
3934297e 698 *
02023181 699 */
631d853f
PT
700 public void setItemCount(int nbItems) {
701 nbItems = Math.max(0, nbItems);
702
703 if (nbItems != fTableItemCount) {
704 fTableItemCount = nbItems;
705 fTable.remove(fTableItemCount, fTable.getItemCount() - 1);
706 fSlider.setMaximum(nbItems);
707 resize();
708 int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight());
709 fFullyVisibleRows = tableHeight / getItemHeight();
710 if (fTableItemCount > 0) {
711 fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows)));
712 }
713 }
714 }
715
02023181
MK
716 /**
717 * Method getItemCount.
718 * @return int the number of items in the table
719 */
631d853f
PT
720 public int getItemCount() {
721 return fTableItemCount;
722 }
723
02023181
MK
724 /**
725 * Method getItemHeight.
726 * @return int the height of a table item in pixels. (may vary from one os to another)
727 */
631d853f
PT
728 public int getItemHeight() {
729 /*
730 * Bug in Linux. The method getItemHeight doesn't always return the correct value.
731 */
732 if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$
733 if (fLinuxItemHeight != 0) {
734 return fLinuxItemHeight;
735 }
736 if (fTable.getItemCount() > 1) {
737 int itemHeight = fTable.getItem(1).getBounds().y - fTable.getItem(0).getBounds().y;
738 if (itemHeight > 0) {
739 fLinuxItemHeight = itemHeight;
740 return fLinuxItemHeight;
741 }
742 }
743 } else {
744 fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore
745 }
746 return fTable.getItemHeight();
747 }
748
02023181
MK
749 /**
750 * Method getHeaderHeight.
751 * @return int get the height of the header in pixels.
752 */
ea08e8ed
PT
753 public int getHeaderHeight() {
754 return fTable.getHeaderHeight();
755 }
756
02023181
MK
757 /**
758 * Method getTopIndex.
759 * @return int get the first data item index, if you have a header it is offset.
760 */
631d853f
PT
761 public int getTopIndex() {
762 return fTableTopEventRank + fFrozenRowCount;
763 }
764
02023181
MK
765 /**
766 * Method setTopIndex.
3934297e 767 * @param i int suggested top index for the table.
02023181 768 */
631d853f
PT
769 public void setTopIndex(int i) {
770 if (fTableItemCount > 0) {
771 i = Math.min(i, fTableItemCount - 1);
772 i = Math.max(i, fFrozenRowCount);
773
774 fTableTopEventRank = i - fFrozenRowCount;
775 if (fFullyVisibleRows < fTableItemCount) {
776 fSlider.setSelection(fTableTopEventRank);
777 }
778
779 refreshTable();
780 }
781 }
782
02023181
MK
783 /**
784 * Method indexOf. Return the index of a table item
785 * @param ti TableItem the table item to search for in the table
3934297e 786 * @return int the index of the first match. (there should only be one match)
02023181 787 */
631d853f
PT
788 public int indexOf(TableItem ti) {
789 int index = fTable.indexOf(ti);
790 if (index < fFrozenRowCount) {
791 return index;
631d853f 792 }
abbdd66a 793 return (index - fFrozenRowCount) + getTopIndex();
631d853f
PT
794 }
795
02023181
MK
796 /**
797 * Method getColumns.
3934297e 798 * @return TableColumn[] the table columns
02023181 799 */
631d853f
PT
800 public TableColumn[] getColumns() {
801 return fTable.getColumns();
802 }
803
02023181
MK
804 /**
805 * Method getItem.
806 * @param point Point the coordinates in the table
3934297e 807 * @return TableItem the corresponding table item
02023181 808 */
631d853f
PT
809 public TableItem getItem(Point point) {
810 return fTable.getItem(point);
811 }
812
02023181
MK
813 /**
814 * Method resize.
815 */
631d853f
PT
816 private void resize() {
817 // Compute the numbers of rows that fit the new area
818 int tableHeight = Math.max(0, getSize().y - fTable.getHeaderHeight());
819 int itemHeight = getItemHeight();
820 fTableRows = Math.min((tableHeight + itemHeight - 1) / itemHeight, fTableItemCount);
821
822 if (fTableTopEventRank + fFullyVisibleRows > fTableItemCount) {
823 // If we are at the end, get elements before to populate
824 fTableTopEventRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
825 refreshTable();
826 } else if (fTableRows > fTable.getItemCount() || fTableItemCount < fTable.getItemCount()) {
827 // Only refresh if new table items are needed or if table items need to be deleted
828 refreshTable();
829 }
830
831 }
832
833 // ------------------------------------------------------------------------
834 // Controls interactions
835 // ------------------------------------------------------------------------
836
02023181
MK
837 /**
838 * Method setFocus.
839 * @return boolean is this visible?
840 */
631d853f
PT
841 @Override
842 public boolean setFocus() {
843 boolean isVisible = isVisible();
844 if (isVisible) {
845 fTable.setFocus();
846 }
847 return isVisible;
848 }
849
02023181
MK
850 /**
851 * Method refresh.
852 */
631d853f
PT
853 public void refresh() {
854 boolean done = refreshTable();
855 if (fPendingSelection && done) {
856 fPendingSelection = false;
857 if (fTable.getSelection().length > 0) {
858 Event e = new Event();
859 e.item = fTable.getSelection()[0];
860 fTable.notifyListeners(SWT.Selection, e);
861 }
862 }
863 }
864
02023181
MK
865 /**
866 * Method setColumnHeaders.
3934297e 867 * @param columnData ColumnData[] the columndata array.
02023181 868 */
631d853f
PT
869 public void setColumnHeaders(ColumnData columnData[]) {
870 for (int i = 0; i < columnData.length; i++) {
871 TableColumn column = new TableColumn(fTable, columnData[i].alignment, i);
872 column.setText(columnData[i].header);
873 if (columnData[i].width > 0) {
874 column.setWidth(columnData[i].width);
875 } else {
876 column.pack();
877 }
878 }
879 }
880
02023181
MK
881 /**
882 * Method removeAll.
883 * @return int 0 the number of elements in the table
884 */
631d853f
PT
885 public int removeAll() {
886 setItemCount(0);
887 fSlider.setMaximum(0);
888 fTable.removeAll();
889 fSelectedEventRank = fFrozenRowCount;
890 return 0;
891 }
892
02023181
MK
893 /**
894 * Method refreshTable.
3934297e 895 * @return boolean did all the items regresh properly?
02023181 896 */
631d853f
PT
897 private boolean refreshTable() {
898 boolean done = true;
899 for (int i = 0; i < fTableRows; i++) {
900 if (i + fTableTopEventRank < fTableItemCount) {
901 TableItem tableItem;
902 if (i < fTable.getItemCount()) {
903 tableItem = fTable.getItem(i);
904 } else {
905 tableItem = new TableItem(fTable, SWT.NONE);
906 }
907 done &= setDataItem(i, tableItem); // false if table item not updated yet in this thread
908 } else {
909 if (fTable.getItemCount() > fTableItemCount - fTableTopEventRank) {
910 fTable.remove(fTableItemCount - fTableTopEventRank);
911 }
912 }
913 }
914
915 int lastRowOffset = fTableTopEventRank + fTableRows - 1;
916 if (fSelectedEventRank < fFrozenRowCount) {
917 fTable.select(fSelectedEventRank);
918 } else if (!done) {
919 fTable.deselectAll();
920 } else if ((fSelectedEventRank >= fTableTopEventRank + fFrozenRowCount) && (fSelectedEventRank <= lastRowOffset)) {
921 int selectedRow = fSelectedEventRank - fTableTopEventRank;
922 fTable.select(selectedRow);
923 } else {
924 fTable.deselectAll();
925 }
926 return done;
927 }
928
02023181
MK
929 /**
930 * Method setSelection.
3934297e 931 * @param i int the item number to select in the table.
02023181 932 */
631d853f
PT
933 public void setSelection(int i) {
934 if (fTableItemCount > 0) {
935 i = Math.min(i, fTableItemCount - 1);
936 i = Math.max(i, 0);
937
938 fSelectedEventRank = i;
939 if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) ||
940 (i >= fTableTopEventRank + fFullyVisibleRows)) {
faa38350
PT
941 int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
942 fTableTopEventRank = Math.max(0, Math.min(lastPageTopEntryRank, i - fFrozenRowCount - fFullyVisibleRows / 2));
631d853f
PT
943 }
944 if (fFullyVisibleRows < fTableItemCount) {
945 fSlider.setSelection(fTableTopEventRank);
946 }
947
948 refreshTable();
949
950 }
951 }
952
02023181
MK
953 /**
954 * Method getSelectionIndex.
955 * @return int the table index of the selected event. not necessarrily the index of the event due to filtering.
956 */
631d853f
PT
957 public int getSelectionIndex() {
958 int index = fTable.getSelectionIndex();
959 if (index == -1) {
960 return fSelectedEventRank;
961 }
962 if (index < fFrozenRowCount) {
963 return index;
631d853f 964 }
abbdd66a 965 return (index - fFrozenRowCount) + getTopIndex();
631d853f
PT
966 }
967
02023181
MK
968 /**
969 * Method setFrozenRowCount.
970 * @param count int the number of rows to freeze from the top row
971 */
631d853f
PT
972 public void setFrozenRowCount(int count) {
973 fFrozenRowCount = count;
974 refreshTable();
975 }
976
02023181
MK
977 /**
978 * Method createTableEditor.
979 * @return a TableEditor of the table
980 */
631d853f
PT
981 public TableEditor createTableEditor() {
982 return new TableEditor(fTable);
983 }
984
02023181
MK
985 /**
986 * Method createTableEditorControl.
987 * @param control Class<? extends Control>
988 * @return Control
989 */
631d853f
PT
990 public Control createTableEditorControl(Class<? extends Control> control) {
991 try {
420bceb2 992 return control.getConstructor(Composite.class, int.class).newInstance(new Object[] {fTable, SWT.NONE});
631d853f
PT
993 } catch (Exception e) {
994 Activator.getDefault().logError("Error creating table editor control", e); //$NON-NLS-1$
995 }
996 return null;
997 }
998
999 /**
1000 * @return the tooltipProvider
02023181 1001 */
631d853f
PT
1002 public TooltipProvider getTooltipProvider() {
1003 return tooltipProvider;
1004 }
1005
1006 /**
1007 * @param tooltipProvider the tooltipProvider to set
1008 */
1009 public void setTooltipProvider(TooltipProvider tooltipProvider) {
1010 this.tooltipProvider = tooltipProvider;
1011 }
1012
1013 /**
1014 * @return the doubleClickListener
02023181 1015 */
631d853f
PT
1016 public IDoubleClickListener getDoubleClickListener() {
1017 return doubleClickListener;
1018 }
1019
1020 /**
1021 * @param doubleClickListener the doubleClickListener to set
1022 */
1023 public void setDoubleClickListener(IDoubleClickListener doubleClickListener) {
1024 this.doubleClickListener = doubleClickListener;
1025 }
1026
9ccc6d01 1027}
This page took 0.085599 seconds and 5 git commands to generate.