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 traversalDirection = translateToTraversalDirection (forward );
42
42
Control control = focusControl ;
43
43
do {
44
- if (control .traverse (traversal ))
44
+ if (control instanceof CTabFolder folder && isFinalItemInCTabFolder (folder , forward )
45
+ && !hasHiddenItem (folder )) {
46
+ loopToFirstOrLastItem (folder , forward );
47
+ traversalDirection = translateToTraversalDirection (!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
+ }
50
+ if (control .traverse (traversalDirection ))
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 hasHiddenItem (CTabFolder folder ) {
61
+ return Arrays .stream (folder .getItems ()).anyMatch (i -> !i .isShowing ());
62
+ }
63
+
64
+ private int translateToTraversalDirection (boolean forward ) {
65
+ return forward ? 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
*
@@ -70,5 +118,4 @@ protected Method getMethodToExecute() {
70
118
}
71
119
return null ;
72
120
}
73
-
74
- }
121
+ }
0 commit comments