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