Fix for bug 381909: Custom traces don't support context clone.
[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
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
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).
55 *
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.
58 *
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.
b21305c2
FC
61 *
62 * Styles:
63 * H_SCROLL, V_SCROLL, SINGLE, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL
9ccc6d01
FC
64 */
65public class TmfVirtualTable extends Composite {
66
631d853f
PT
67 // The table
68 private Table fTable;
69 private int fTableRows = 0; // Number of table rows
70 private int fFullyVisibleRows = 0; // Number of fully visible table rows
71 private int fFrozenRowCount = 0; // Number of frozen table rows at top of table
72
73 private int fTableTopEventRank = 0; // Global rank of the first entry displayed
74 private int fSelectedEventRank = 0; // Global rank of the selected event
75 private boolean fPendingSelection = false; // Pending selection update
76
77 private int fTableItemCount = 0;
78
79 // The slider
80 private Slider fSlider;
81
82 private int fLinuxItemHeight = 0; // Calculated item height for Linux workaround
83 private TooltipProvider tooltipProvider = null;
84 private IDoubleClickListener doubleClickListener = null;
85
86 // ------------------------------------------------------------------------
87 // Constructor
88 // ------------------------------------------------------------------------
89
90 /**
91 * @param parent
92 * @param style
93 */
94 public TmfVirtualTable(Composite parent, int style) {
95 super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL) & (~SWT.SINGLE) & (~SWT.FULL_SELECTION) & (~SWT.HIDE_SELECTION) & (~SWT.CHECK));
96
97 // Create the controls
98 createTable(style & (SWT.H_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION | SWT.HIDE_SELECTION | SWT.CHECK));
99 createSlider(style & SWT.V_SCROLL);
100
101 // Prevent the slider from being traversed
102 setTabList(new Control[] { fTable });
103
104 // Set the layout
105 GridLayout gridLayout = new GridLayout();
106 gridLayout.numColumns = 2;
107 gridLayout.horizontalSpacing = 0;
108 gridLayout.verticalSpacing = 0;
109 gridLayout.marginWidth = 0;
110 gridLayout.marginHeight = 0;
111 setLayout(gridLayout);
112
113 GridData tableGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
114 fTable.setLayoutData(tableGridData);
115
116 GridData sliderGridData = new GridData(SWT.FILL, SWT.FILL, false, true);
117 fSlider.setLayoutData(sliderGridData);
118
119 // Add the listeners
120 fTable.addMouseWheelListener(new MouseWheelListener() {
121 @Override
122 public void mouseScrolled(MouseEvent event) {
123 if (fTableItemCount <= fFullyVisibleRows) {
124 return;
125 }
126 fTableTopEventRank -= event.count;
127 if (fTableTopEventRank < 0) {
128 fTableTopEventRank = 0;
129 }
130 int latestFirstRowOffset = fTableItemCount - fFullyVisibleRows;
131 if (fTableTopEventRank > latestFirstRowOffset) {
132 fTableTopEventRank = latestFirstRowOffset;
133 }
134
135 fSlider.setSelection(fTableTopEventRank);
136 refreshTable();
137 }
138 });
139
140 fTable.addListener(SWT.MouseWheel, new Listener() {
141 // disable mouse scroll of horizontal scroll bar
142 @Override
b21305c2 143 public void handleEvent(Event event) {
631d853f
PT
144 event.doit = false;
145 }
146 });
147
148 fTable.addControlListener(new ControlAdapter() {
149 @Override
150 public void controlResized(ControlEvent event) {
151 int tableHeight = Math.max(0, fTable.getClientArea().height - fTable.getHeaderHeight());
152 fFullyVisibleRows = tableHeight / getItemHeight();
153 if (fTableItemCount > 0) {
154 fSlider.setThumb(Math.max(1, Math.min(fTableRows, fFullyVisibleRows)));
155 }
156 }
157 });
158 // Implement a "fake" tooltip
159 final String TOOLTIP_DATA_KEY = "_TABLEITEM"; //$NON-NLS-1$
160 final Listener labelListener = new Listener () {
161 @Override
f4c52cea 162 public void handleEvent (Event event) {
631d853f
PT
163 Label label = (Label)event.widget;
164 Shell shell = label.getShell ();
165 switch (event.type) {
166 case SWT.MouseDown:
167 Event e = new Event ();
168 e.item = (TableItem) label.getData (TOOLTIP_DATA_KEY);
169 // Assuming table is single select, set the selection as if
170 // the mouse down event went through to the table
171 fTable.setSelection (new TableItem [] {(TableItem) e.item});
172 fTable.notifyListeners (SWT.Selection, e);
173 shell.dispose ();
174 fTable.setFocus();
175 break;
176 case SWT.MouseExit:
177 case SWT.MouseWheel:
178 shell.dispose ();
179 break;
180 }
181 }
182 };
183
184 Listener tableListener = new Listener () {
185 Shell tip = null;
186 Label label = null;
187 @Override
f4c52cea 188 public void handleEvent (Event event) {
631d853f
PT
189 switch (event.type) {
190 case SWT.Dispose:
191 case SWT.KeyDown:
192 case SWT.MouseMove: {
193 if (tip == null) break;
194 tip.dispose ();
195 tip = null;
196 label = null;
197 break;
198 }
199 case SWT.MouseHover: {
200 TableItem item = fTable.getItem (new Point(event.x, event.y));
201 if (item != null) {
202 for(int i=0;i<fTable.getColumnCount();i++){
203 Rectangle bounds = item.getBounds(i);
204 if (bounds.contains(event.x,event.y)){
205 if (tip != null && !tip.isDisposed()) tip.dispose();
206 if (tooltipProvider == null) {
207 return;
208 } else {
209 String tooltipText = tooltipProvider.getTooltip(i, item.getData());
210 if (tooltipText == null) return;
211 tip = new Shell(fTable.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
212 tip.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
213 FillLayout layout = new FillLayout();
214 layout.marginWidth = 2;
215 tip.setLayout(layout);
216 label = new Label(tip, SWT.WRAP);
217 label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
218 label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
219 label.setData(TOOLTIP_DATA_KEY, item);
220 label.setText(tooltipText);
221
222 label.addListener(SWT.MouseExit, labelListener);
223 label.addListener(SWT.MouseDown, labelListener);
224 label.addListener(SWT.MouseWheel, labelListener);
225 Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT);
226 Point pt = fTable.toDisplay(bounds.x, bounds.y);
227 tip.setBounds(pt.x, pt.y, size.x, size.y);
228 tip.setVisible(true);
229 }
230 break;
231 }
232 }
233 }
234 }
235 }
236 }
237 };
238 fTable.addListener(SWT.Dispose, tableListener);
239 fTable.addListener(SWT.KeyDown, tableListener);
240 fTable.addListener(SWT.MouseMove, tableListener);
241 fTable.addListener(SWT.MouseHover, tableListener);
242 addControlListener(new ControlAdapter() {
243 @Override
244 public void controlResized(ControlEvent event) {
245 resize();
246 }
247 });
248
249 // And display
250 refresh();
251 }
252
253 // ------------------------------------------------------------------------
254 // Table handling
255 // ------------------------------------------------------------------------
256
257 /**
258 * Create the table and add listeners
259 */
260 private void createTable(int style) {
261 fTable = new Table(this, style | SWT.NO_SCROLL);
262
263 fTable.addSelectionListener(new SelectionAdapter() {
264 @Override
265 public void widgetSelected(SelectionEvent event) {
266 if (fTable.getSelectionIndices().length > 0) {
267 handleTableSelection();
268 }
269 }
270 });
9ccc6d01 271
2cc874d6 272 fTable.addKeyListener(new KeyListener() {
631d853f
PT
273 @Override
274 public void keyPressed(KeyEvent event) {
275 handleTableKeyEvent(event);
276 }
277 @Override
278 public void keyReleased(KeyEvent event) {
279 }
280 });
7800a42f
XR
281
282 fTable.addListener(
631d853f
PT
283 SWT.MouseDoubleClick, new Listener() {
284 @Override
285 public void handleEvent(Event event) {
286 if (doubleClickListener != null) {
287 TableItem item = fTable.getItem (new Point (event.x, event.y));
288 if (item != null) {
289 for(int i=0;i<fTable.getColumnCount();i++){
290 Rectangle bounds = item.getBounds(i);
291 if (bounds.contains(event.x,event.y)){
292 doubleClickListener.handleDoubleClick(TmfVirtualTable.this, item, i);
293 break;
294 }
295 }
296 }
297 }
298 }
299 }
300 );
301 }
302
303 /**
304 * Update the rows and selected item
305 */
306 private void handleTableSelection() {
307 int selectedRow = fTable.getSelectionIndices()[0];
308 if (selectedRow < fFrozenRowCount) {
309 fSelectedEventRank = selectedRow;
310 } else {
311 fSelectedEventRank = fTableTopEventRank + selectedRow;
312 }
313
314 /*
315 * Feature in Windows. When a partially visible table item is selected,
316 * after ~500 ms the top index is changed to ensure the selected item is
317 * fully visible. This leaves a blank space at the bottom of the virtual
318 * table. The workaround is to update the top event rank, refresh the
319 * table and reset the top index to 0 after a sufficient delay.
320 */
321 if (selectedRow >= fFullyVisibleRows) {
322 final Display display = fTable.getDisplay();
323 Thread thread = new Thread("Top index check") { //$NON-NLS-1$
324 @Override
325 public void run() {
326 try {
327 Thread.sleep(600);
328 } catch (InterruptedException e) {
329 }
330 display.asyncExec(new Runnable() {
331 @Override
b21305c2 332 public void run() {
631d853f
PT
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
828e5592
PT
541 public void addListener(int eventType, Listener listener) {
542 fTable.addListener(eventType, listener);
543 }
631d853f
PT
544
545 @Override
546 public void addKeyListener(KeyListener listener) {
547 fTable.addKeyListener(listener);
548 }
b21305c2 549
828e5592
PT
550
551 @Override
631d853f
PT
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
ea08e8ed
PT
610 public int getHeaderHeight() {
611 return fTable.getHeaderHeight();
612 }
613
631d853f
PT
614 public int getTopIndex() {
615 return fTableTopEventRank + fFrozenRowCount;
616 }
617
618 public void setTopIndex(int i) {
619 if (fTableItemCount > 0) {
620 i = Math.min(i, fTableItemCount - 1);
621 i = Math.max(i, fFrozenRowCount);
622
623 fTableTopEventRank = i - fFrozenRowCount;
624 if (fFullyVisibleRows < fTableItemCount) {
625 fSlider.setSelection(fTableTopEventRank);
626 }
627
628 refreshTable();
629 }
630 }
631
632 public int indexOf(TableItem ti) {
633 int index = fTable.indexOf(ti);
634 if (index < fFrozenRowCount) {
635 return index;
636 } else {
637 return (index - fFrozenRowCount) + getTopIndex();
638 }
639 }
640
641 public TableColumn[] getColumns() {
642 return fTable.getColumns();
643 }
644
645 public TableItem getItem(Point point) {
646 return fTable.getItem(point);
647 }
648
649 private void resize() {
650 // Compute the numbers of rows that fit the new area
651 int tableHeight = Math.max(0, getSize().y - fTable.getHeaderHeight());
652 int itemHeight = getItemHeight();
653 fTableRows = Math.min((tableHeight + itemHeight - 1) / itemHeight, fTableItemCount);
654
655 if (fTableTopEventRank + fFullyVisibleRows > fTableItemCount) {
656 // If we are at the end, get elements before to populate
657 fTableTopEventRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
658 refreshTable();
659 } else if (fTableRows > fTable.getItemCount() || fTableItemCount < fTable.getItemCount()) {
660 // Only refresh if new table items are needed or if table items need to be deleted
661 refreshTable();
662 }
663
664 }
665
666 // ------------------------------------------------------------------------
667 // Controls interactions
668 // ------------------------------------------------------------------------
669
670 @Override
671 public boolean setFocus() {
672 boolean isVisible = isVisible();
673 if (isVisible) {
674 fTable.setFocus();
675 }
676 return isVisible;
677 }
678
679 public void refresh() {
680 boolean done = refreshTable();
681 if (fPendingSelection && done) {
682 fPendingSelection = false;
683 if (fTable.getSelection().length > 0) {
684 Event e = new Event();
685 e.item = fTable.getSelection()[0];
686 fTable.notifyListeners(SWT.Selection, e);
687 }
688 }
689 }
690
691 public void setColumnHeaders(ColumnData columnData[]) {
692 for (int i = 0; i < columnData.length; i++) {
693 TableColumn column = new TableColumn(fTable, columnData[i].alignment, i);
694 column.setText(columnData[i].header);
695 if (columnData[i].width > 0) {
696 column.setWidth(columnData[i].width);
697 } else {
698 column.pack();
699 }
700 }
701 }
702
703 public int removeAll() {
704 setItemCount(0);
705 fSlider.setMaximum(0);
706 fTable.removeAll();
707 fSelectedEventRank = fFrozenRowCount;
708 return 0;
709 }
710
711 private boolean refreshTable() {
712 boolean done = true;
713 for (int i = 0; i < fTableRows; i++) {
714 if (i + fTableTopEventRank < fTableItemCount) {
715 TableItem tableItem;
716 if (i < fTable.getItemCount()) {
717 tableItem = fTable.getItem(i);
718 } else {
719 tableItem = new TableItem(fTable, SWT.NONE);
720 }
721 done &= setDataItem(i, tableItem); // false if table item not updated yet in this thread
722 } else {
723 if (fTable.getItemCount() > fTableItemCount - fTableTopEventRank) {
724 fTable.remove(fTableItemCount - fTableTopEventRank);
725 }
726 }
727 }
728
729 int lastRowOffset = fTableTopEventRank + fTableRows - 1;
730 if (fSelectedEventRank < fFrozenRowCount) {
731 fTable.select(fSelectedEventRank);
732 } else if (!done) {
733 fTable.deselectAll();
734 } else if ((fSelectedEventRank >= fTableTopEventRank + fFrozenRowCount) && (fSelectedEventRank <= lastRowOffset)) {
735 int selectedRow = fSelectedEventRank - fTableTopEventRank;
736 fTable.select(selectedRow);
737 } else {
738 fTable.deselectAll();
739 }
740 return done;
741 }
742
743 public void setSelection(int i) {
744 if (fTableItemCount > 0) {
745 i = Math.min(i, fTableItemCount - 1);
746 i = Math.max(i, 0);
747
748 fSelectedEventRank = i;
749 if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) ||
750 (i >= fTableTopEventRank + fFullyVisibleRows)) {
751 fTableTopEventRank = Math.max(0, i - fFrozenRowCount - fFullyVisibleRows / 2);
752 }
753 if (fFullyVisibleRows < fTableItemCount) {
754 fSlider.setSelection(fTableTopEventRank);
755 }
756
757 refreshTable();
758
759 }
760 }
761
762 public int getSelectionIndex() {
763 int index = fTable.getSelectionIndex();
764 if (index == -1) {
765 return fSelectedEventRank;
766 }
767 if (index < fFrozenRowCount) {
768 return index;
769 } else {
770 return (index - fFrozenRowCount) + getTopIndex();
771 }
772 }
773
774 public void setFrozenRowCount(int count) {
775 fFrozenRowCount = count;
776 refreshTable();
777 }
778
779 public TableEditor createTableEditor() {
780 return new TableEditor(fTable);
781 }
782
783 public Control createTableEditorControl(Class<? extends Control> control) {
784 try {
785 return (Control) control.getConstructor(Composite.class, int.class).newInstance(new Object[] {fTable, SWT.NONE});
786 } catch (Exception e) {
787 Activator.getDefault().logError("Error creating table editor control", e); //$NON-NLS-1$
788 }
789 return null;
790 }
791
792 /**
793 * @return the tooltipProvider
794 */
795 public TooltipProvider getTooltipProvider() {
796 return tooltipProvider;
797 }
798
799 /**
800 * @param tooltipProvider the tooltipProvider to set
801 */
802 public void setTooltipProvider(TooltipProvider tooltipProvider) {
803 this.tooltipProvider = tooltipProvider;
804 }
805
806 /**
807 * @return the doubleClickListener
808 */
809 public IDoubleClickListener getDoubleClickListener() {
810 return doubleClickListener;
811 }
812
813 /**
814 * @param doubleClickListener the doubleClickListener to set
815 */
816 public void setDoubleClickListener(IDoubleClickListener doubleClickListener) {
817 this.doubleClickListener = doubleClickListener;
818 }
819
9ccc6d01 820}
This page took 0.068487 seconds and 5 git commands to generate.