tmf: Bug 494810: SelectionEvent not sent after using vertical slider
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / virtualtable / TmfVirtualTable.java
index fdbe8c4a19dea6b502cc9851a0209416a7e7b94e..d878e7e5f0ee2508fb5259f2a7ee8ccffde7b7e0 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2015 Ericsson and others.
+ * Copyright (c) 2010, 2016 Ericsson and others.
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -20,6 +20,8 @@ import org.eclipse.swt.SWTException;
 import org.eclipse.swt.custom.TableEditor;
 import org.eclipse.swt.events.ControlAdapter;
 import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.FocusAdapter;
+import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.KeyAdapter;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
@@ -169,7 +171,7 @@ public class TmfVirtualTable extends Composite {
         fTable.addMouseWheelListener(new MouseWheelListener() {
             @Override
             public void mouseScrolled(MouseEvent event) {
-                if (fTableItemCount <= fFullyVisibleRows) {
+                if (fTableItemCount <= fFullyVisibleRows || event.count == 0) {
                     return;
                 }
                 fTableTopEventRank -= event.count;
@@ -657,6 +659,16 @@ public class TmfVirtualTable extends Composite {
             }
         });
 
+        /*
+         * The SWT.NO_FOCUS style is only a hint and is not always respected. If
+         * the slider gains focus, give it back to the table.
+         */
+        fSlider.addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent e) {
+                fTable.setFocus();
+            }
+        });
     }
 
     // ------------------------------------------------------------------------
@@ -1074,12 +1086,31 @@ public class TmfVirtualTable extends Composite {
         }
         if (start <= end) {
             fTable.setSelection(start, end);
+            /* Reset origin in case partially visible item selected */
+            fTable.setTopIndex(0);
             if (startRank == fSelectedEventRank) {
                 fTable.select(start);
             } else {
                 fTable.select(end);
             }
         } else {
+            /*
+             * In GTK2, when the table is given focus, one table item is
+             * highlighted even if there is no selection. In that case the
+             * highlighted item is the last selected item. Make that last
+             * selected item the top or bottom item depending on if the
+             * out-of-range selection is above or below the visible items.
+             */
+            if (SWT.getPlatform().equals("gtk") && fTableRows > 0) { //$NON-NLS-1$
+                fTable.setRedraw(false);
+                if (start < Integer.MAX_VALUE) {
+                    fTable.setSelection(0);
+                } else {
+                    fTable.setSelection(fTableRows - 1);
+                    fTable.setTopIndex(0);
+                }
+                fTable.setRedraw(true);
+            }
             fTable.deselectAll();
         }
     }
@@ -1097,21 +1128,45 @@ public class TmfVirtualTable extends Composite {
      * </ul>
      */
     public void setSelection(int index) {
-        if (fTableItemCount > 0) {
-            int i = Math.min(index, fTableItemCount - 1);
-            i = Math.max(i, 0);
+        setSelectionRange(index, index);
+    }
 
-            fSelectedEventRank = i;
-            fSelectedBeginRank = fSelectedEventRank;
-            if ((i < fTableTopEventRank + fFrozenRowCount && i >= fFrozenRowCount) ||
-                    (i >= fTableTopEventRank + fFullyVisibleRows)) {
+    /**
+     * Selects a range of items starting at the given zero-relative index in the
+     * receiver. The current selection is first cleared, then the new items are
+     * selected, and if necessary the receiver is scrolled to make the new
+     * selection visible.
+     *
+     * @param beginIndex
+     *            The index of the first item in the selection range
+     * @param endIndex
+     *            The index of the last item in the selection range
+     *
+     * @exception SWTException
+     *                <ul>
+     *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+     *                disposed</li>
+     *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+     *                thread that created the receiver</li>
+     *                </ul>
+     * @since 2.0
+     */
+    public void setSelectionRange(int beginIndex, int endIndex) {
+        if (fTableItemCount > 0) {
+            int begin = Math.max(Math.min(beginIndex, fTableItemCount - 1), 0);
+            int end =   Math.max(Math.min(endIndex, fTableItemCount - 1), 0);
+            int selection = fSelectedBeginRank != begin ? begin : end;
+
+            fSelectedBeginRank = begin;
+            fSelectedEventRank = end;
+            if ((selection < fTableTopEventRank + fFrozenRowCount && selection >= fFrozenRowCount) ||
+                    (selection >= fTableTopEventRank + fFullyVisibleRows)) {
                 int lastPageTopEntryRank = Math.max(0, fTableItemCount - fFullyVisibleRows);
-                fTableTopEventRank = Math.max(0, Math.min(lastPageTopEntryRank, i - fFrozenRowCount - fFullyVisibleRows / 2));
+                fTableTopEventRank = Math.max(0, Math.min(lastPageTopEntryRank, selection - fFrozenRowCount - fFullyVisibleRows / 2));
             }
             if (fFullyVisibleRows < fTableItemCount) {
                 fSlider.setSelection(fTableTopEventRank);
             }
-
             refreshTable();
         }
     }
This page took 0.025787 seconds and 5 git commands to generate.