Remove bookmarks file on drag&drop trace copy.
[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 @Override
161 public void handleEvent (Event event) {
162 Label label = (Label)event.widget;
163 Shell shell = label.getShell ();
164 switch (event.type) {
165 case SWT.MouseDown:
166 Event e = new Event ();
167 e.item = (TableItem) label.getData (TOOLTIP_DATA_KEY);
168 // Assuming table is single select, set the selection as if
169 // the mouse down event went through to the table
170 fTable.setSelection (new TableItem [] {(TableItem) e.item});
171 fTable.notifyListeners (SWT.Selection, e);
172 shell.dispose ();
173 fTable.setFocus();
174 break;
175 case SWT.MouseExit:
176 case SWT.MouseWheel:
177 shell.dispose ();
178 break;
179 }
180 }
181 };
182
183 Listener tableListener = new Listener () {
184 Shell tip = null;
185 Label label = null;
186 @Override
187 public void handleEvent (Event event) {
188 switch (event.type) {
189 case SWT.Dispose:
190 case SWT.KeyDown:
191 case SWT.MouseMove: {
192 if (tip == null) break;
193 tip.dispose ();
194 tip = null;
195 label = null;
196 break;
197 }
198 case SWT.MouseHover: {
199 TableItem item = fTable.getItem (new Point(event.x, event.y));
200 if (item != null) {
201 for(int i=0;i<fTable.getColumnCount();i++){
202 Rectangle bounds = item.getBounds(i);
203 if (bounds.contains(event.x,event.y)){
204 if (tip != null && !tip.isDisposed()) tip.dispose();
205 if (tooltipProvider == null) {
206 return;
207 } else {
208 String tooltipText = tooltipProvider.getTooltip(i, item.getData());
209 if (tooltipText == null) return;
210 tip = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
211 tip.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
212 FillLayout layout = new FillLayout();
213 layout.marginWidth = 2;
214 tip.setLayout(layout);
215 label = new Label(tip, SWT.WRAP);
216 label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
217 label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
218 label.setData(TOOLTIP_DATA_KEY, item);
219 label.setText(tooltipText);
220
221 label.addListener(SWT.MouseExit, labelListener);
222 label.addListener(SWT.MouseDown, labelListener);
223 label.addListener(SWT.MouseWheel, labelListener);
224 Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
225 Point pt = fTable.toDisplay(bounds.x, bounds.y);
226 tip.setBounds(pt.x, pt.y, size.x, size.y);
227 tip.setVisible(true);
228 }
229 break;
230 }
231 }
232 }
233 }
234 }
235 }
236 };
237 fTable.addListener(SWT.Dispose, tableListener);
238 fTable.addListener(SWT.KeyDown, tableListener);
239 fTable.addListener(SWT.MouseMove, tableListener);
240 fTable.addListener(SWT.MouseHover, tableListener);
241 addControlListener(new ControlAdapter() {
242 @Override
243 public void controlResized(ControlEvent event) {
244 resize();
245 }
246 });
247
248 // And display
249 refresh();
250 }
251
252 // ------------------------------------------------------------------------
253 // Table handling
254 // ------------------------------------------------------------------------
255
256 /**
257 * Create the table and add listeners
258 */
259 private void createTable(int style) {
260 fTable = new Table(this, style | SWT.NO_SCROLL);
261
262 fTable.addSelectionListener(new SelectionAdapter() {
263 @Override
264 public void widgetSelected(SelectionEvent event) {
265 if (fTable.getSelectionIndices().length > 0) {
266 handleTableSelection();
267 }
268 }
269 });
270
271 fTable.addKeyListener(new KeyListener() {
272 @Override
273 public void keyPressed(KeyEvent event) {
274 handleTableKeyEvent(event);
275 }
276 @Override
277 public void keyReleased(KeyEvent event) {
278 }
279 });
280
281 fTable.addListener(
282 SWT.MouseDoubleClick, new Listener() {
283 @Override
284 public void handleEvent(Event event) {
285 if (doubleClickListener != null) {
286 TableItem item = fTable.getItem (new Point (event.x, event.y));
287 if (item != null) {
288 for(int i=0;i<fTable.getColumnCount();i++){
289 Rectangle bounds = item.getBounds(i);
290 if (bounds.contains(event.x,event.y)){
291 doubleClickListener.handleDoubleClick(TmfVirtualTable.this, item, i);
292 break;
293 }
294 }
295 }
296 }
297 }
298 }
299 );
300 }
301
302 /**
303 * Update the rows and selected item
304 */
305 private void handleTableSelection() {
306 int selectedRow = fTable.getSelectionIndices()[0];
307 if (selectedRow < fFrozenRowCount) {
308 fSelectedEventRank = selectedRow;
309 } else {
310 fSelectedEventRank = fTableTopEventRank + selectedRow;
311 }
312
313 /*
314 * Feature in Windows. When a partially visible table item is selected,
315 * after ~500 ms the top index is changed to ensure the selected item is
316 * fully visible. This leaves a blank space at the bottom of the virtual
317 * table. The workaround is to update the top event rank, refresh the
318 * table and reset the top index to 0 after a sufficient delay.
319 */
320 if (selectedRow >= fFullyVisibleRows) {
321 final Display display = fTable.getDisplay();
322 Thread thread = new Thread("Top index check") { //$NON-NLS-1$
323 @Override
324 public void run() {
325 try {
326 Thread.sleep(600);
327 } catch (InterruptedException e) {
328 e.printStackTrace();
329 }
330 display.asyncExec(new Runnable() {
331 @Override
332 public void run() {
333 if (fTable.isDisposed()) return;
334 int topIndex = fTable.getTopIndex();
335 if (topIndex != 0) {
336 fTableTopEventRank += topIndex;
337 refreshTable();
338 fSlider.setSelection(fTableTopEventRank);
339 fTable.setTopIndex(0);
340 }
341 }
342 });
343 }
344 };
345 thread.start();
346 }
347 }
348
349 /**
350 * Handle key-based navigation in table.
351 *
352 * @param event
353 */
354 private void handleTableKeyEvent(KeyEvent event) {
355
356 int lastEventRank = fTableItemCount - 1;
357 int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
358
359 int previousSelectedEventRank = fSelectedEventRank;
360 int selectedRow = fSelectedEventRank - fTableTopEventRank;
361 boolean needsRefresh = false;
362
363 // In all case, perform the following steps:
364 // - Update the selected entry rank (within valid range)
365 // - Update the selected row
366 // - Update the page's top entry if necessary (which also adjusts the selected row)
367 // - If the top displayed entry was changed, table refresh is needed
368 switch (event.keyCode) {
369
370 case SWT.ARROW_DOWN: {
371 event.doit = false;
372 if (fSelectedEventRank < lastEventRank) {
373 fSelectedEventRank++;
374 selectedRow = fSelectedEventRank - fTableTopEventRank;
375 if (selectedRow >= fFullyVisibleRows) {
376 fTableTopEventRank++;
377 needsRefresh = true;
378 }
379 }
380 break;
381 }
382
383 case SWT.ARROW_UP: {
384 event.doit = false;
385 if (fSelectedEventRank > 0) {
386 fSelectedEventRank--;
387 selectedRow = fSelectedEventRank - fTableTopEventRank;
388 if (selectedRow < fFrozenRowCount && fTableTopEventRank > 0) {
389 fTableTopEventRank--;
390 needsRefresh = true;
391 }
392 }
393 break;
394 }
395
396 case SWT.END: {
397 event.doit = false;
398 fTableTopEventRank = lastPageTopEntryRank;
399 fSelectedEventRank = lastEventRank;
400 needsRefresh = true;
401 break;
402 }
403
404 case SWT.HOME: {
405 event.doit = false;
406 fSelectedEventRank = fFrozenRowCount;
407 fTableTopEventRank = 0;
408 needsRefresh = true;
409 break;
410 }
411
412 case SWT.PAGE_DOWN: {
413 event.doit = false;
414 if (fSelectedEventRank < lastEventRank) {
415 fSelectedEventRank += fFullyVisibleRows;
416 if (fSelectedEventRank > lastEventRank) {
417 fSelectedEventRank = lastEventRank;
418 }
419 selectedRow = fSelectedEventRank - fTableTopEventRank;
420 if (selectedRow > fFullyVisibleRows - 1) {
421 fTableTopEventRank += fFullyVisibleRows;
422 if (fTableTopEventRank > lastPageTopEntryRank) {
423 fTableTopEventRank = lastPageTopEntryRank;
424 }
425 needsRefresh = true;
426 }
427 }
428 break;
429 }
430
431 case SWT.PAGE_UP: {
432 event.doit = false;
433 if (fSelectedEventRank > 0) {
434 fSelectedEventRank -= fFullyVisibleRows;
435 if (fSelectedEventRank < fFrozenRowCount) {
436 fSelectedEventRank = fFrozenRowCount;
437 }
438 selectedRow = fSelectedEventRank - fTableTopEventRank;
439 if (selectedRow < 0) {
440 fTableTopEventRank -= fFullyVisibleRows;
441 if (fTableTopEventRank < 0) {
442 fTableTopEventRank = 0;
443 }
444 needsRefresh = true;
445 }
446 }
447 break;
448 }
449 default: {
450 return;
451 }
452 }
453
454 boolean done = true;
455 if (needsRefresh) {
456 done = refreshTable(); // false if table items not updated yet in this thread
457 } else {
458 fTable.select(selectedRow);
459 }
460
461 if (fFullyVisibleRows < fTableItemCount) {
462 fSlider.setSelection(fTableTopEventRank);
463 }
464
465 if (fSelectedEventRank != previousSelectedEventRank && fTable.getSelection().length > 0) {
466 if (done) {
467 Event e = new Event();
468 e.item = fTable.getSelection()[0];
469 fTable.notifyListeners(SWT.Selection, e);
470 } else {
471 fPendingSelection = true;
472 }
473 }
474 }
475
476 private boolean setDataItem(int index, TableItem item) {
477 if (index != -1) {
478 Event event = new Event();
479 event.item = item;
480 if (index < fFrozenRowCount) {
481 event.index = index;
482 } else {
483 event.index = index + fTableTopEventRank;
484 }
485 event.doit = true;
486 fTable.notifyListeners(SWT.SetData, event);
487 return event.doit; // false if table item not updated yet in this thread
488 }
489 return true;
490 }
491
492 // ------------------------------------------------------------------------
493 // Slider handling
494 // ------------------------------------------------------------------------
495
496 private void createSlider(int style) {
497 fSlider = new Slider(this, SWT.VERTICAL | SWT.NO_FOCUS);
498 fSlider.setMinimum(0);
499 fSlider.setMaximum(0);
500 if ((style & SWT.V_SCROLL) == 0) {
501 fSlider.setVisible(false);
502 }
503
504 fSlider.addListener(SWT.Selection, new Listener() {
505 @Override
506 public void handleEvent(Event event) {
507 switch (event.detail) {
508 case SWT.ARROW_DOWN:
509 case SWT.ARROW_UP:
510 case SWT.NONE:
511 case SWT.END:
512 case SWT.HOME:
513 case SWT.PAGE_DOWN:
514 case SWT.PAGE_UP: {
515 fTableTopEventRank = fSlider.getSelection();
516 refreshTable();
517 break;
518 }
519 }
520 }
521 });
522 }
523
524 // ------------------------------------------------------------------------
525 // Simulated Table API
526 // ------------------------------------------------------------------------
527
528 public void setHeaderVisible(boolean b) {
529 fTable.setHeaderVisible(b);
530 }
531
532 public void setLinesVisible(boolean b) {
533 fTable.setLinesVisible(b);
534 }
535
536 public TableItem[] getSelection() {
537 return fTable.getSelection();
538 }
539
540 @Override
541 public void addListener(int eventType, Listener listener) {
542 fTable.addListener(eventType, listener);
543 }
544
545 @Override
546 public void addKeyListener(KeyListener listener) {
547 fTable.addKeyListener(listener);
548 }
549
550
551 @Override
552 public void addMouseListener(MouseListener listener) {
553 fTable.addMouseListener(listener);
554 }
555
556 public void addSelectionListener(SelectionListener listener) {
557 fTable.addSelectionListener(listener);
558 }
559
560 @Override
561 public void setMenu(Menu menu) {
562 fTable.setMenu(menu);
563 }
564
565 public void clearAll() {
566 setItemCount(0);
567 }
568
569 public void setItemCount(int nbItems) {
570 nbItems = Math.max(0, nbItems);
571
572 if (nbItems != fTableItemCount) {
573 fTableItemCount = nbItems;
574 fTable.remove(fTableItemCount, fTable.getItemCount() - 1);
575 fSlider.setMaximum(nbItems);
576 resize();
577 int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight());
578 fFullyVisibleRows = tableHeight / getItemHeight();
579 if (fTableItemCount > 0) {
580 fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows)));
581 }
582 }
583 }
584
585 public int getItemCount() {
586 return fTableItemCount;
587 }
588
589 public int getItemHeight() {
590 /*
591 * Bug in Linux. The method getItemHeight doesn't always return the correct value.
592 */
593 if (fLinuxItemHeight >= 0 && System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$
594 if (fLinuxItemHeight != 0) {
595 return fLinuxItemHeight;
596 }
597 if (fTable.getItemCount() > 1) {
598 int itemHeight = fTable.getItem(1).getBounds().y - fTable.getItem(0).getBounds().y;
599 if (itemHeight > 0) {
600 fLinuxItemHeight = itemHeight;
601 return fLinuxItemHeight;
602 }
603 }
604 } else {
605 fLinuxItemHeight = -1; // Not Linux, don't perform os.name check anymore
606 }
607 return fTable.getItemHeight();
608 }
609
610 public int getTopIndex() {
611 return fTableTopEventRank + fFrozenRowCount;
612 }
613
614 public void setTopIndex(int i) {
615 if (fTableItemCount > 0) {
616 i = Math.min(i, fTableItemCount - 1);
617 i = Math.max(i, fFrozenRowCount);
618
619 fTableTopEventRank = i - fFrozenRowCount;
620 if (fFullyVisibleRows < fTableItemCount) {
621 fSlider.setSelection(fTableTopEventRank);
622 }
623
624 refreshTable();
625 }
626 }
627
628 public int indexOf(TableItem ti) {
629 int index = fTable.indexOf(ti);
630 if (index < fFrozenRowCount) {
631 return index;
632 } else {
633 return (index - fFrozenRowCount) + getTopIndex();
634 }
635 }
636
637 public TableColumn[] getColumns() {
638 return fTable.getColumns();
639 }
640
641 public TableItem getItem(Point point) {
642 return fTable.getItem(point);
643 }
644
645 private void resize() {
646 // Compute the numbers of rows that fit the new area
647 int tableHeight = Math.max(0, getSize().y - fTable.getHeaderHeight());
648 int itemHeight = getItemHeight();
649 fTableRows = Math.min((tableHeight + itemHeight - 1) / itemHeight, fTableItemCount);
650
651 if (fTableTopEventRank + fFullyVisibleRows > fTableItemCount) {
652 // If we are at the end, get elements before to populate
653 fTableTopEventRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
654 refreshTable();
655 } else if (fTableRows > fTable.getItemCount() || fTableItemCount < fTable.getItemCount()) {
656 // Only refresh if new table items are needed or if table items need to be deleted
657 refreshTable();
658 }
659
660 }
661
662 // ------------------------------------------------------------------------
663 // Controls interactions
664 // ------------------------------------------------------------------------
665
666 @Override
667 public boolean setFocus() {
668 boolean isVisible = isVisible();
669 if (isVisible) {
670 fTable.setFocus();
671 }
672 return isVisible;
673 }
674
675 public void refresh() {
676 boolean done = refreshTable();
677 if (fPendingSelection && done) {
678 fPendingSelection = false;
679 if (fTable.getSelection().length > 0) {
680 Event e = new Event();
681 e.item = fTable.getSelection()[0];
682 fTable.notifyListeners(SWT.Selection, e);
683 }
684 }
685 }
686
687 public void setColumnHeaders(ColumnData columnData[]) {
688 for (int i = 0; i < columnData.length; i++) {
689 TableColumn column = new TableColumn(fTable, columnData[i].alignment, i);
690 column.setText(columnData[i].header);
691 if (columnData[i].width > 0) {
692 column.setWidth(columnData[i].width);
693 } else {
694 column.pack();
695 }
696 }
697 }
698
699 public int removeAll() {
700 setItemCount(0);
701 fSlider.setMaximum(0);
702 fTable.removeAll();
703 fSelectedEventRank = fFrozenRowCount;
704 return 0;
705 }
706
707 private boolean refreshTable() {
708 boolean done = true;
709 for (int i = 0; i < fTableRows; i++) {
710 if (i + fTableTopEventRank < fTableItemCount) {
711 TableItem tableItem;
712 if (i < fTable.getItemCount()) {
713 tableItem = fTable.getItem(i);
714 } else {
715 tableItem = new TableItem(fTable, SWT.NONE);
716 }
717 done &= setDataItem(i, tableItem); // false if table item not updated yet in this thread
718 } else {
719 if (fTable.getItemCount() > fTableItemCount - fTableTopEventRank) {
720 fTable.remove(fTableItemCount - fTableTopEventRank);
721 }
722 }
723 }
724
725 int lastRowOffset = fTableTopEventRank + fTableRows - 1;
726 if ((fSelectedEventRank >= fTableTopEventRank + fFrozenRowCount) && (fSelectedEventRank <= lastRowOffset)) {
727 int selectedRow = fSelectedEventRank - fTableTopEventRank;
728 fTable.select(selectedRow);
729 } else if (fSelectedEventRank < fFrozenRowCount) {
730 fTable.select(fSelectedEventRank);
731 } else {
732 fTable.deselectAll();
733 }
734 return done;
735 }
736
737 public void setSelection(int i) {
738 if (fTableItemCount > 0) {
739 i = Math.min(i, fTableItemCount - 1);
740 i = Math.max(i, 0);
741
742 fSelectedEventRank = i;
743 if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) ||
744 (i >= fTableTopEventRank + fFullyVisibleRows)) {
745 fTableTopEventRank = Math.max(0, i - fFrozenRowCount - fFullyVisibleRows / 2);
746 }
747 if (fFullyVisibleRows < fTableItemCount) {
748 fSlider.setSelection(fTableTopEventRank);
749 }
750
751 refreshTable();
752
753 }
754 }
755
756 public int getSelectionIndex() {
757 int index = fTable.getSelectionIndex();
758 if (index == -1) {
759 return fSelectedEventRank;
760 }
761 if (index < fFrozenRowCount) {
762 return index;
763 } else {
764 return (index - fFrozenRowCount) + getTopIndex();
765 }
766 }
767
768 public void setFrozenRowCount(int count) {
769 fFrozenRowCount = count;
770 refreshTable();
771 }
772
773 public TableEditor createTableEditor() {
774 return new TableEditor(fTable);
775 }
776
777 public Control createTableEditorControl(Class<? extends Control> control) {
778 try {
779 return (Control) control.getConstructor(Composite.class, int.class).newInstance(new Object[] {fTable, SWT.NONE});
780 } catch (Exception e) {
781 e.printStackTrace();
782 }
783 return null;
784 }
785
786 /**
787 * @return the tooltipProvider
788 */
789 public TooltipProvider getTooltipProvider() {
790 return tooltipProvider;
791 }
792
793 /**
794 * @param tooltipProvider the tooltipProvider to set
795 */
796 public void setTooltipProvider(TooltipProvider tooltipProvider) {
797 this.tooltipProvider = tooltipProvider;
798 }
799
800 /**
801 * @return the doubleClickListener
802 */
803 public IDoubleClickListener getDoubleClickListener() {
804 return doubleClickListener;
805 }
806
807 /**
808 * @param doubleClickListener the doubleClickListener to set
809 */
810 public void setDoubleClickListener(IDoubleClickListener doubleClickListener) {
811 this.doubleClickListener = doubleClickListener;
812 }
813
814 }
This page took 0.05244 seconds and 5 git commands to generate.