1 /*******************************************************************************
2  * Copyright (c) 2005, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.ui.dialogs;
15 
16 import java.util.Collection;
17 import java.util.List;
18 import org.eclipse.core.runtime.IAdaptable;
19 import org.eclipse.jface.preference.IPreferenceNode;
20 import org.eclipse.jface.preference.IPreferencePage;
21 import org.eclipse.jface.preference.PreferenceDialog;
22 import org.eclipse.jface.preference.PreferenceManager;
23 import org.eclipse.jface.preference.PreferencePage;
24 import org.eclipse.swt.widgets.Shell;
25 import org.eclipse.ui.internal.dialogs.FilteredPreferenceDialog;
26 import org.eclipse.ui.internal.dialogs.PropertyDialog;
27 import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager;
28 import org.eclipse.ui.internal.dialogs.PropertyPageManager;
29 import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog;
30 
31 /**
32  * The PreferencesUtil class is the class that opens a properties or preference
33  * dialog on a set of ids.
34  *
35  * @since 3.1
36  */
37 public final class PreferencesUtil {
38 
39 	/**
40 	 * Constant denoting no option.
41 	 *
42 	 * @since 3.5
43 	 */
44 	public static final int OPTION_NONE = 0;
45 
46 	/**
47 	 * Constant for configuring a preferences or properties dialog in which the user
48 	 * cannot "unfilter" to show a larger set of pages than was passed to
49 	 * {@link #createPreferenceDialogOn(Shell, String, String[], Object, int)} or
50 	 * {@link #createPropertyDialogOn(Shell, IAdaptable, String, String[], Object, int)}
51 	 * .
52 	 *
53 	 * @since 3.5
54 	 */
55 	public static final int OPTION_FILTER_LOCKED = 1;
56 
57 	/**
58 	 * Apply the data to the first page if there is any.
59 	 *
60 	 * @param data         The data to be applied
61 	 * @param displayedIds The ids to filter to.
62 	 * @param dialog       The dialog to apply to.
63 	 * @param options
64 	 */
applyOptions(Object data, String[] displayedIds, FilteredPreferenceDialog dialog, int options)65 	private static void applyOptions(Object data, String[] displayedIds, FilteredPreferenceDialog dialog, int options) {
66 		if (data != null) {
67 			dialog.setPageData(data);
68 			IPreferencePage page = dialog.getCurrentPage();
69 			if (page instanceof PreferencePage) {
70 				((PreferencePage) page).applyData(data);
71 			}
72 		}
73 
74 		if (displayedIds != null) {
75 			dialog.showOnly(displayedIds);
76 		}
77 
78 		if ((options & OPTION_FILTER_LOCKED) != 0) {
79 			dialog.setLocked(true);
80 		}
81 	}
82 
83 	/**
84 	 * Creates a workbench preference dialog and selects particular preference page.
85 	 * If there is already a preference dialog open this dialog is used and its
86 	 * selection is set to the page with id preferencePageId. Show the other pages
87 	 * as filtered results using whatever filtering criteria the search uses. It is
88 	 * the responsibility of the caller to then call <code>open()</code>. The call
89 	 * to <code>open()</code> will not return until the dialog closes, so this is
90 	 * the last chance to manipulate the dialog.
91 	 *
92 	 * @param shell            The Shell to parent the dialog off of if it is not
93 	 *                         already created. May be <code>null</code> in which
94 	 *                         case the active workbench window will be used if
95 	 *                         available.
96 	 * @param preferencePageId The identifier of the preference page to open; may be
97 	 *                         <code>null</code>. If it is <code>null</code>, then
98 	 *                         the preference page is not selected or modified in
99 	 *                         any way.
100 	 * @param displayedIds     The ids of the other pages to be displayed using the
101 	 *                         same filtering criterea as search. If this is
102 	 *                         <code>null</code>, then the all preference pages are
103 	 *                         shown.
104 	 * @param data             Data that will be passed to all of the preference
105 	 *                         pages to be applied as specified within the page as
106 	 *                         they are created. If the data is <code>null</code>
107 	 *                         nothing will be called.
108 	 *
109 	 * @return a preference dialog.
110 	 * @since 3.1
111 	 * @see PreferenceDialog#PreferenceDialog(Shell, PreferenceManager)
112 	 */
createPreferenceDialogOn(Shell shell, String preferencePageId, String[] displayedIds, Object data)113 	public static PreferenceDialog createPreferenceDialogOn(Shell shell, String preferencePageId, String[] displayedIds,
114 			Object data) {
115 		return createPreferenceDialogOn(shell, preferencePageId, displayedIds, data, OPTION_NONE);
116 	}
117 
118 	/**
119 	 * Creates a workbench preference dialog to a particular preference page. Show
120 	 * the other pages as filtered results using whatever filtering criteria the
121 	 * search uses. It is the responsibility of the caller to then call
122 	 * <code>open()</code>. The call to <code>open()</code> will not return until
123 	 * the dialog closes, so this is the last chance to manipulate the dialog.
124 	 *
125 	 * @param shell          The shell to use to parent the dialog if required.
126 	 * @param propertyPageId The identifier of the preference page to open; may be
127 	 *                       <code>null</code>. If it is <code>null</code>, then the
128 	 *                       dialog is opened with no selected page.
129 	 * @param element        IAdaptable An adaptable element to open the dialog on.
130 	 * @param displayedIds   The ids of the other pages to be displayed using the
131 	 *                       same filtering criterea as search. If this is
132 	 *                       <code>null</code>, then the all preference pages are
133 	 *                       shown.
134 	 * @param data           Data that will be passed to all of the preference pages
135 	 *                       to be applied as specified within the page as they are
136 	 *                       created. If the data is <code>null</code> nothing will
137 	 *                       be called.
138 	 *
139 	 * @return A preference dialog showing properties for the selection or
140 	 *         <code>null</code> if it could not be created.
141 	 * @since 3.1
142 	 */
createPropertyDialogOn(Shell shell, final IAdaptable element, String propertyPageId, String[] displayedIds, Object data)143 	public static PreferenceDialog createPropertyDialogOn(Shell shell, final IAdaptable element, String propertyPageId,
144 			String[] displayedIds, Object data) {
145 		return createPropertyDialogOn(shell, element, propertyPageId, displayedIds, data, OPTION_NONE);
146 	}
147 
148 	/**
149 	 * Creates a workbench preference dialog and selects particular preference page.
150 	 * If there is already a preference dialog open this dialog is used and its
151 	 * selection is set to the page with id preferencePageId. Show the other pages
152 	 * as filtered results using whatever filtering criteria the search uses. It is
153 	 * the responsibility of the caller to then call <code>open()</code>. The call
154 	 * to <code>open()</code> will not return until the dialog closes, so this is
155 	 * the last chance to manipulate the dialog.
156 	 *
157 	 * @param shell            The Shell to parent the dialog off of if it is not
158 	 *                         already created. May be <code>null</code> in which
159 	 *                         case the active workbench window will be used if
160 	 *                         available.
161 	 * @param preferencePageId The identifier of the preference page to open; may be
162 	 *                         <code>null</code>. If it is <code>null</code>, then
163 	 *                         the preference page is not selected or modified in
164 	 *                         any way.
165 	 * @param displayedIds     The ids of the other pages to be displayed using the
166 	 *                         same filtering criterea as search. If this is
167 	 *                         <code>null</code>, then the all preference pages are
168 	 *                         shown.
169 	 * @param data             Data that will be passed to all of the preference
170 	 *                         pages to be applied as specified within the page as
171 	 *                         they are created. If the data is <code>null</code>
172 	 *                         nothing will be called.
173 	 * @param options          a bitwise OR of option constants
174 	 *
175 	 * @return a preference dialog.
176 	 * @since 3.5
177 	 * @see PreferenceDialog#PreferenceDialog(Shell, PreferenceManager)
178 	 */
createPreferenceDialogOn(Shell shell, String preferencePageId, String[] displayedIds, Object data, int options)179 	public static PreferenceDialog createPreferenceDialogOn(Shell shell, String preferencePageId, String[] displayedIds,
180 			Object data, int options) {
181 		FilteredPreferenceDialog dialog = WorkbenchPreferenceDialog.createDialogOn(shell, preferencePageId);
182 
183 		applyOptions(data, displayedIds, dialog, options);
184 
185 		return dialog;
186 	}
187 
188 	/**
189 	 * Creates a workbench preference dialog to a particular preference page. Show
190 	 * the other pages as filtered results using whatever filtering criteria the
191 	 * search uses. It is the responsibility of the caller to then call
192 	 * <code>open()</code>. The call to <code>open()</code> will not return until
193 	 * the dialog closes, so this is the last chance to manipulate the dialog.
194 	 *
195 	 * @param shell          The shell to use to parent the dialog if required.
196 	 * @param propertyPageId The identifier of the preference page to open; may be
197 	 *                       <code>null</code>. If it is <code>null</code>, then the
198 	 *                       dialog is opened with no selected page.
199 	 * @param element        IAdaptable An adaptable element to open the dialog on.
200 	 * @param displayedIds   The ids of the other pages to be displayed using the
201 	 *                       same filtering criteria as search. If this is
202 	 *                       <code>null</code>, then the all preference pages are
203 	 *                       shown.
204 	 * @param data           Data that will be passed to all of the preference pages
205 	 *                       to be applied as specified within the page as they are
206 	 *                       created. If the data is <code>null</code> nothing will
207 	 *                       be called.
208 	 * @param options        a bitwise OR of option constants
209 	 *
210 	 * @return A preference dialog showing properties for the selection or
211 	 *         <code>null</code> if it could not be created.
212 	 * @since 3.5
213 	 */
createPropertyDialogOn(Shell shell, final IAdaptable element, String propertyPageId, String[] displayedIds, Object data, int options)214 	public static PreferenceDialog createPropertyDialogOn(Shell shell, final IAdaptable element, String propertyPageId,
215 			String[] displayedIds, Object data, int options) {
216 
217 		FilteredPreferenceDialog dialog = PropertyDialog.createDialogOn(shell, propertyPageId, element);
218 
219 		if (dialog == null) {
220 			return null;
221 		}
222 
223 		applyOptions(data, displayedIds, dialog, options);
224 
225 		return dialog;
226 
227 	}
228 
229 	/**
230 	 * Creates a workbench preference dialog to a particular preference page. Show
231 	 * the other pages as filtered results using whatever filtering criteria the
232 	 * search uses. It is the responsibility of the caller to then call
233 	 * <code>open()</code>. The call to <code>open()</code> will not return until
234 	 * the dialog closes, so this is the last chance to manipulate the dialog.
235 	 *
236 	 * @param shell          The shell to use to parent the dialog if required.
237 	 * @param propertyPageId The identifier of the preference page to open; may be
238 	 *                       <code>null</code>. If it is <code>null</code>, then the
239 	 *                       dialog is opened with no selected page.
240 	 * @param element        An element to open the dialog on.
241 	 * @param displayedIds   The IDs of the other pages to be displayed using the
242 	 *                       same filtering criteria as search. If this is
243 	 *                       <code>null</code>, then the all preference pages are
244 	 *                       shown.
245 	 * @param data           Data that will be passed to all of the preference pages
246 	 *                       to be applied as specified within the page as they are
247 	 *                       created. If the data is <code>null</code> nothing will
248 	 *                       be called.
249 	 * @param options        a bitwise OR of option constants
250 	 *
251 	 * @return A preference dialog showing properties for the selection or
252 	 *         <code>null</code> if it could not be created.
253 	 * @since 3.6
254 	 */
createPropertyDialogOn(Shell shell, final Object element, String propertyPageId, String[] displayedIds, Object data, int options)255 	public static PreferenceDialog createPropertyDialogOn(Shell shell, final Object element, String propertyPageId,
256 			String[] displayedIds, Object data, int options) {
257 		FilteredPreferenceDialog dialog = PropertyDialog.createDialogOn(shell, propertyPageId, element);
258 		if (dialog == null)
259 			return null;
260 		applyOptions(data, displayedIds, dialog, options);
261 		return dialog;
262 	}
263 
264 	/**
265 	 * Indicates whether the specified element has at least one property page
266 	 * contributor.
267 	 *
268 	 * @param element an adapter element of a property page
269 	 * @return true for having at least one contributor; false otherwise
270 	 * @since 3.4
271 	 */
hasPropertiesContributors(Object element)272 	public static boolean hasPropertiesContributors(Object element) {
273 		if (element == null || !(element instanceof IAdaptable))
274 			return false;
275 		Collection contributors = PropertyPageContributorManager.getManager().getApplicableContributors(element);
276 		return contributors != null && contributors.size() > 0;
277 	}
278 
279 	/**
280 	 * Return all of the properties page contributors for an element.
281 	 *
282 	 * @param element the element to process
283 	 * @return {@link IPreferenceNode}[]
284 	 * @since 3.4
285 	 */
propertiesContributorsFor(Object element)286 	public static IPreferenceNode[] propertiesContributorsFor(Object element) {
287 		PropertyPageManager pageManager = new PropertyPageManager();
288 		if (element == null) {
289 			return null;
290 		}
291 		// load pages for the selection
292 		// fill the manager with contributions from the matching contributors
293 		PropertyPageContributorManager.getManager().contribute(pageManager, element);
294 		// testing if there are pages in the manager
295 		List pages = pageManager.getElements(PreferenceManager.PRE_ORDER);
296 		IPreferenceNode[] nodes = new IPreferenceNode[pages.size()];
297 		pages.toArray(nodes);
298 		return nodes;
299 	}
300 
301 }
302