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