|
12 | 12 | * IBM Corporation - initial API and implementation |
13 | 13 | *******************************************************************************/ |
14 | 14 | package org.eclipse.ui.internal.handlers; |
15 | | - |
16 | 15 | import java.lang.reflect.Method; |
| 16 | +import java.util.Arrays; |
17 | 17 | import org.eclipse.core.commands.ExecutionEvent; |
18 | 18 | import org.eclipse.swt.SWT; |
| 19 | +import org.eclipse.swt.custom.CTabFolder; |
| 20 | +import org.eclipse.swt.custom.CTabItem; |
19 | 21 | import org.eclipse.swt.widgets.Control; |
20 | 22 | import org.eclipse.swt.widgets.Display; |
21 | 23 | import org.eclipse.swt.widgets.Shell; |
22 | | - |
23 | 24 | /** |
24 | 25 | * This handler is an adaptation of the widget method handler that implements |
25 | 26 | * page traversal via {@link SWT#TRAVERSE_PAGE_NEXT} and |
|
28 | 29 | * @since 3.5 |
29 | 30 | */ |
30 | 31 | public class TraversePageHandler extends WidgetMethodHandler { |
31 | | - |
32 | 32 | /** |
33 | 33 | * The parameters for traverse(int). |
34 | 34 | */ |
35 | 35 | private static final Class<?>[] METHOD_PARAMETERS = { int.class }; |
36 | | - |
37 | 36 | @Override |
38 | 37 | public final Object execute(final ExecutionEvent event) { |
39 | 38 | Control focusControl = Display.getCurrent().getFocusControl(); |
40 | 39 | if (focusControl != null) { |
41 | | - int traversal = "next".equals(methodName) ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS; //$NON-NLS-1$ |
| 40 | + boolean forward = "next".equals(methodName); //$NON-NLS-1$ |
| 41 | + int traversal = getTraversalDirection(forward); |
42 | 42 | Control control = focusControl; |
43 | 43 | do { |
| 44 | + if (control instanceof CTabFolder folder && isFinalItemInCTabFolder(folder, forward) |
| 45 | + && !areHiddenItems(folder)) { |
| 46 | + loopToFirstOrLastItem(folder, forward); |
| 47 | + traversal = getTraversalDirection(!forward); // we are in the second-to-last item in the given |
| 48 | + // direction. Now, use the Traverse-event to move back by one |
| 49 | + } |
44 | 50 | if (control.traverse(traversal)) |
45 | 51 | return null; |
46 | 52 | if (control instanceof Shell) |
47 | 53 | return null; |
48 | 54 | control = control.getParent(); |
49 | 55 | } while (control != null); |
50 | 56 | } |
51 | | - |
52 | 57 | return null; |
53 | 58 | } |
54 | 59 |
|
| 60 | + private boolean areHiddenItems(CTabFolder folder) { |
| 61 | + return Arrays.stream(folder.getItems()).anyMatch(i -> !i.isShowing()); |
| 62 | + } |
| 63 | + |
| 64 | + private int getTraversalDirection(boolean direction) { |
| 65 | + return direction ? SWT.TRAVERSE_PAGE_NEXT : SWT.TRAVERSE_PAGE_PREVIOUS; |
| 66 | + } |
| 67 | + |
| 68 | + /** |
| 69 | + * Sets the current selection to the first or last item the given direction. |
| 70 | + * |
| 71 | + * @param folder the CTabFolder which we want to inspect |
| 72 | + * @param forward whether we want to traverse forwards of backwards |
| 73 | + */ |
| 74 | + private void loopToFirstOrLastItem(CTabFolder folder, boolean forward) { |
| 75 | + if (forward) { |
| 76 | + folder.showItem(folder.getItem(0)); |
| 77 | + folder.setSelection(1); |
| 78 | + } else { |
| 79 | + int itemCount = folder.getItemCount(); |
| 80 | + folder.setSelection(itemCount - 2); |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + /** |
| 85 | + * {@return Returns whether the folder has currently selected the final item in |
| 86 | + * the given direction.} |
| 87 | + * |
| 88 | + * @param folder the CTabFolder which we want to inspect |
| 89 | + * @param forward whether we want to traverse forwards of backwards |
| 90 | + */ |
| 91 | + private boolean isFinalItemInCTabFolder(CTabFolder folder, boolean forward) { |
| 92 | + CTabItem currentFolder = folder.getSelection(); |
| 93 | + CTabItem lastFolder = null; |
| 94 | + if (forward) { |
| 95 | + int itemCount = folder.getItemCount(); |
| 96 | + lastFolder = folder.getItem(itemCount - 1); |
| 97 | + } else { |
| 98 | + lastFolder = folder.getItem(0); |
| 99 | + } |
| 100 | + return currentFolder.equals(lastFolder); |
| 101 | + } |
| 102 | + |
55 | 103 | /** |
56 | 104 | * Looks up the traverse(int) method on the given focus control. |
57 | 105 | * |
|
0 commit comments