Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 006815d371c33c49c6adacad9b2da80445c2cbe8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*******************************************************************************
 * Copyright (c) 2008, 2015 Ketan Padegaonkar 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 accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Ketan Padegaonkar - initial API and implementation
 *     Patrick Tasse - Fix radio menu item click behavior (Bug 451126 & Bug 397649)
 *******************************************************************************/
package org.eclipse.swtbot.swt.finder.widgets;

import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withMnemonic;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
import org.eclipse.swtbot.swt.finder.finders.MenuFinder;
import org.eclipse.swtbot.swt.finder.results.BoolResult;
import org.eclipse.swtbot.swt.finder.results.VoidResult;
import org.eclipse.swtbot.swt.finder.results.WidgetResult;
import org.eclipse.swtbot.swt.finder.utils.MessageFormat;
import org.eclipse.swtbot.swt.finder.utils.SWTUtils;
import org.hamcrest.Matcher;
import org.hamcrest.SelfDescribing;

/**
 * @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com>
 * @version $Id$
 */
public class SWTBotMenu extends AbstractSWTBot<MenuItem> {

	/**
	 * @param w the widget.
	 * @param description the description of the widget, this will be reported by {@link #toString()}
	 * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
	 */
	public SWTBotMenu(MenuItem w, SelfDescribing description) throws WidgetNotFoundException {
		super(w, description);
	}

	/**
	 * @param w the widget.
	 * @throws WidgetNotFoundException if the widget is <code>null</code> or widget has been disposed.
	 */
	public SWTBotMenu(MenuItem w) throws WidgetNotFoundException {
		this(w, null);
	}

	/**
	 * Clicks on the menu item
	 */
	public SWTBotMenu click() {
		log.debug(MessageFormat.format("Clicking on {0}", this)); //$NON-NLS-1$
		waitForEnabled();
		if (SWTUtils.hasStyle(widget, SWT.CHECK)) {
			toggleCheckSelection();
		} else if (SWTUtils.hasStyle(widget, SWT.RADIO)) {
			setRadioSelection();
		}
		notify(SWT.Selection);
		log.debug(MessageFormat.format("Clicked on {0}", this)); //$NON-NLS-1$
		return this;
	}

	/**
	 * Toggle the selection of the check menu item.
	 */
	private void toggleCheckSelection() {
		syncExec(new VoidResult() {
			public void run() {
				widget.setSelection(!widget.getSelection());
			}
		});
	}

	/**
	 * Set the selection of the radio menu item and clear the selection of any
	 * other radio menu item in the same group.
	 */
	private void setRadioSelection() {
		final SWTBotMenu otherSelectedRadioItem = otherSelectedRadioItem();
		if (otherSelectedRadioItem != null) {
			otherSelectedRadioItem.notify(SWT.Deactivate);
			asyncExec(new VoidResult() {
				public void run() {
					otherSelectedRadioItem.widget.setSelection(false);
				}
			});
			otherSelectedRadioItem.notify(SWT.Selection);
		}
		syncExec(new VoidResult() {
			public void run() {
				widget.setSelection(true);
			}
		});
	}

	private SWTBotMenu otherSelectedRadioItem() {
		MenuItem other = syncExec(new WidgetResult<MenuItem>() {
			public MenuItem run() {
				if (hasStyle(widget.getParent(), SWT.NO_RADIO_GROUP))
					return null;
				Widget[] siblings = SWTUtils.siblings(widget);
				boolean ownGroup = false;
				MenuItem selected = null;
				for (Widget sibling : siblings) {
					if (sibling == widget) {
						ownGroup = true;
					} else if (((sibling instanceof MenuItem) && hasStyle(sibling, SWT.RADIO))) {
						if (((MenuItem) sibling).getSelection()) {
							selected = (MenuItem) sibling;
						}
					} else if ((sibling instanceof MenuItem) && hasStyle(sibling, SWT.SEPARATOR)) {
						ownGroup = false;
						selected = null;
					}
					if (ownGroup && selected != null) {
						return selected;
					}
				}
				return null;
			}
		});

		if (other != null)
			return new SWTBotMenu(other);
		return null;
	}

	/**
	 * Gets the menu item matching the given name.
	 *
	 * @param menuName the name of the menu item that is to be found
	 * @return the first menu that matches the menuName
	 * @throws WidgetNotFoundException if the widget is not found.
	 */
	public SWTBotMenu menu(final String menuName) throws WidgetNotFoundException {
		final Matcher<? extends Widget> matcher = withMnemonic(menuName);
		MenuItem menuItem = syncExec(new WidgetResult<MenuItem>() {
			public MenuItem run() {
				Menu bar = widget.getMenu();
				Matcher<MenuItem> withMnemonic = withMnemonic(menuName);
				List<MenuItem> menus = new MenuFinder().findMenus(bar, withMnemonic, true);
				if (!menus.isEmpty())
					return menus.get(0);
				return null;
			}
		});
		return new SWTBotMenu(menuItem, matcher);
	}

	@Override
	public boolean isEnabled() {
		return syncExec(new BoolResult() {
			public Boolean run() {
				return widget.isEnabled();
			}
		});
	}

	/**
	 * Gets if this menu item is checked.
	 *
	 * @return <code>true</code> if the menu is checked, <code>false</code> otherwise.
	 * @see MenuItem#getSelection()
	 * @since 1.2
	 */
	public boolean isChecked() {
		return syncExec(new BoolResult() {
			public Boolean run() {
				return widget.getSelection();
			}
		});
	}
}

Back to the top