1212 * IBM Corporation - initial API and implementation
1313 *******************************************************************************/
1414package org .eclipse .ui .internal .handlers ;
15-
1615import java .lang .reflect .Method ;
1716import org .eclipse .core .commands .ExecutionEvent ;
1817import org .eclipse .swt .SWT ;
18+ import org .eclipse .swt .custom .CTabFolder ;
19+ import org .eclipse .swt .custom .CTabItem ;
1920import org .eclipse .swt .widgets .Control ;
2021import org .eclipse .swt .widgets .Display ;
2122import org .eclipse .swt .widgets .Shell ;
22-
2323/**
2424 * This handler is an adaptation of the widget method handler that implements
2525 * page traversal via {@link SWT#TRAVERSE_PAGE_NEXT} and
2828 * @since 3.5
2929 */
3030public class TraversePageHandler extends WidgetMethodHandler {
31-
3231 /**
3332 * The parameters for traverse(int).
3433 */
3534 private static final Class <?>[] METHOD_PARAMETERS = { int .class };
36-
3735 @ Override
3836 public final Object execute (final ExecutionEvent event ) {
3937 Control focusControl = Display .getCurrent ().getFocusControl ();
4038 if (focusControl != null ) {
41- int traversal = "next" .equals (methodName ) ? SWT .TRAVERSE_PAGE_NEXT : SWT .TRAVERSE_PAGE_PREVIOUS ; //$NON-NLS-1$
39+ boolean forward = "next" .equals (methodName ); //$NON-NLS-1$
40+ int traversal = getTraversalDirection (forward );
4241 Control control = focusControl ;
42+
4343 do {
44+ if (control instanceof CTabFolder folder && isFinalItemInCTabFolder (folder , forward )
45+ && !areHiddenItems (folder )) {
46+ loopToSecondToFirstItemInCTabFolder (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+ }
4450 if (control .traverse (traversal ))
4551 return null ;
4652 if (control instanceof Shell )
4753 return null ;
4854 control = control .getParent ();
4955 } while (control != null );
5056 }
51-
5257 return null ;
5358 }
5459
60+ private boolean areHiddenItems (CTabFolder folder ) {
61+ CTabItem [] items = folder .getItems ();
62+ for (CTabItem i : items ) {
63+ if (!i .isShowing ()) {
64+ return true ;
65+ }
66+ }
67+
68+ return false ;
69+ }
70+ private int getTraversalDirection (boolean direction ) {
71+ return direction ? SWT .TRAVERSE_PAGE_NEXT : SWT .TRAVERSE_PAGE_PREVIOUS ;
72+ }
73+
74+ /**
75+ * Sets the current selection to the second-to-last item in the given direction.
76+ *
77+ * @param folder the CTabFolder which we want to inspect
78+ * @param forward whether we want to traverse forwards of backwards
79+ */
80+ private void loopToSecondToFirstItemInCTabFolder (CTabFolder folder , boolean forward ) {
81+ if (forward ) {
82+ folder .showItem (folder .getItem (0 ));
83+ folder .setSelection (1 );
84+ } else {
85+ int itemCount = folder .getItemCount ();
86+ folder .setSelection (itemCount - 2 );
87+ }
88+ }
89+
90+ /**https://github.com/jannisCode/eclipse.jdt.ui.git
91+ * {@return Returns whether the folder has currently selected the final item in
92+ * the given direction.}
93+ *
94+ * @param folder the CTabFolder which we want to inspect
95+ * @param forward whether we want to traverse forwards of backwards
96+ */
97+ private boolean isFinalItemInCTabFolder (CTabFolder folder , boolean forward ) {
98+ CTabItem currentFolder = folder .getSelection ();
99+ CTabItem lastFolder = null ;
100+ if (forward ) {
101+ int itemCount = folder .getItemCount ();
102+ lastFolder = folder .getItem (itemCount - 1 );
103+ } else {
104+ lastFolder = folder .getItem (0 );
105+ }
106+ return currentFolder .equals (lastFolder );
107+ }
108+
55109 /**
56110 * Looks up the traverse(int) method on the given focus control.
57111 *
@@ -70,5 +124,4 @@ protected Method getMethodToExecute() {
70124 }
71125 return null ;
72126 }
73-
74- }
127+ }
0 commit comments