1616import java .lang .reflect .Method ;
1717import org .eclipse .core .commands .ExecutionEvent ;
1818import org .eclipse .swt .SWT ;
19+ import org .eclipse .swt .custom .CTabFolder ;
20+ import org .eclipse .swt .custom .CTabItem ;
1921import org .eclipse .swt .widgets .Control ;
2022import org .eclipse .swt .widgets .Display ;
2123import org .eclipse .swt .widgets .Shell ;
@@ -38,20 +40,90 @@ public class TraversePageHandler extends WidgetMethodHandler {
3840 public final Object execute (final ExecutionEvent event ) {
3941 Control focusControl = Display .getCurrent ().getFocusControl ();
4042 if (focusControl != null ) {
43+ boolean forward = "next" .equals (methodName ); //$NON-NLS-1$
4144 int traversal = "next" .equals (methodName ) ? SWT .TRAVERSE_PAGE_NEXT : SWT .TRAVERSE_PAGE_PREVIOUS ; //$NON-NLS-1$
4245 Control control = focusControl ;
4346 do {
44- if (control .traverse (traversal ))
47+ if (control instanceof CTabFolder folder && isFinalItemInCTabFolder (folder , forward )
48+ && !areHiddenItems (folder )) {
49+
50+ loopToSecondToFirstItemInCTabFolder (folder , forward );
51+ traversal = getTraversalDirection (!forward ); // we are in the second-to-last item in the given
52+ // direction. Now, use the Traverse-event to move back by one
53+ }
54+ if (control .traverse (traversal )) {
4555 return null ;
46- if (control instanceof Shell )
56+ }
57+ if (control instanceof Shell ) {
4758 return null ;
59+ }
4860 control = control .getParent ();
4961 } while (control != null );
5062 }
5163
5264 return null ;
5365 }
5466
67+
68+ private int getTraversalDirection (boolean direction ) {
69+ return direction ? SWT .TRAVERSE_PAGE_NEXT : SWT .TRAVERSE_PAGE_PREVIOUS ;
70+ }
71+
72+ /**
73+ * Sets the current selection to the second-to-last item in the given direction.
74+ *
75+ * @param folder
76+ * @param forward
77+ */
78+ private void loopToSecondToFirstItemInCTabFolder (CTabFolder folder , boolean forward ) {
79+ if (forward ) {
80+ folder .showItem (folder .getItem (0 ));
81+ folder .setSelection (1 );
82+ } else {
83+ int itemCount = folder .getItemCount ();
84+ folder .setSelection (itemCount - 2 );
85+ }
86+ }
87+
88+ /**
89+ * {@return Returns whether the folder has currently selected the final item in
90+ * the given direction.}
91+ *
92+ * @param folder the CTabFolder which we want to inspect
93+ * @param forward whether we want to traverse forwards of backwards
94+ */
95+ private boolean isFinalItemInCTabFolder (CTabFolder folder , boolean forward ) {
96+ folder .update ();
97+
98+ CTabItem currentFolder = folder .getSelection ();
99+ CTabItem lastFolder = null ;
100+ if (forward ) {
101+ int itemCount = folder .getItemCount ();
102+
103+ lastFolder = folder .getItem (itemCount - 1 );
104+
105+ } else {
106+ lastFolder = folder .getItem (0 );
107+ }
108+ return currentFolder .equals (lastFolder );
109+ }
110+
111+ /**
112+ * checks if there are any hidden items
113+ *
114+ * @param folder
115+ * @return if there are any items which are not shown in the folder (tabs in the
116+ * >> column)
117+ */
118+ private boolean areHiddenItems (CTabFolder folder ) {
119+ for (CTabItem i : folder .getItems ()) {
120+ if (!i .isShowing ()) {
121+ return true ;
122+ }
123+ }
124+ return false ;
125+ }
126+
55127 /**
56128 * Looks up the traverse(int) method on the given focus control.
57129 *
0 commit comments