| /******************************************************************************* |
| * Copyright (c) 2000, 2016 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| * Alex Blewitt - Bug 474070 |
| *******************************************************************************/ |
| package org.eclipse.help.ui; |
| |
| import java.util.Hashtable; |
| |
| import org.eclipse.help.ui.internal.Messages; |
| import org.eclipse.help.ui.internal.views.EngineDescriptor; |
| import org.eclipse.help.ui.internal.views.ScopeSet; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferencePage; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * Clients that contribute search scope root page to the search engine |
| * definition must extend this class and implement |
| * <code>createScopeContents</code> method. The page will come preset with the |
| * engine name, image and description, as well as the master switch that turns |
| * the engine on or off. When the engine master switch is set to false, all the |
| * children in the client composite will be disabled. |
| * |
| * @since 3.1 |
| */ |
| public abstract class RootScopePage extends PreferencePage implements |
| ISearchScopePage { |
| private IEngineDescriptor ed; |
| |
| private String scopeSetName; |
| |
| private Button masterButton; |
| |
| private Text labelText; |
| |
| private Text descText; |
| |
| private Hashtable<Control, Boolean> disabledStates = new Hashtable<>(); |
| |
| private Label spacer; |
| |
| private Composite contentContainer; |
| |
| /** |
| * The default constructor. |
| */ |
| public RootScopePage() { |
| } |
| |
| @Override |
| public void init(IEngineDescriptor ed, String scopeSetName) { |
| this.ed = ed; |
| this.scopeSetName = scopeSetName; |
| } |
| |
| /** |
| * Creates the initial contents of the page and allocates the area for the |
| * clients. Classes that extend this class should implement |
| * <code>createScopeContents(Composite)</code> instead. |
| * |
| * @param parent |
| * the page parent |
| * @return the page client control |
| */ |
| @Override |
| protected final Control createContents(Composite parent) { |
| initializeDefaults(getPreferenceStore()); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, |
| "org.eclipse.help.ui.searchScope"); //$NON-NLS-1$ |
| contentContainer = new Composite(parent, SWT.NULL); |
| GridLayout layout = new GridLayout(); |
| GridData gd; |
| //if (ed.isUserDefined()) |
| layout.numColumns = 2; |
| contentContainer.setLayout(layout); |
| if (isInPreferenceDialog()) { |
| masterButton = new Button(contentContainer, SWT.CHECK); |
| masterButton.setText(Messages.RootScopePage_masterButton); |
| gd = new GridData(); |
| gd.horizontalSpan = 2;// ed.isUserDefined() ? 2 : 1; |
| masterButton.setLayoutData(gd); |
| |
| spacer = new Label(contentContainer, SWT.NULL); |
| gd = new GridData(); |
| gd.horizontalSpan = 2;// ed.isUserDefined() ? 2 : 1; |
| spacer.setLayoutData(gd); |
| boolean masterValue = getPreferenceStore().getBoolean(ScopeSet.getMasterKey(ed.getId())); |
| masterButton.setSelection(masterValue); |
| masterButton.addSelectionListener(new SelectionAdapter() { |
| |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| masterValueChanged(masterButton.getSelection()); |
| } |
| }); |
| |
| Label label = new Label(contentContainer, SWT.NULL); |
| label.setText(Messages.RootScopePage_name); |
| labelText = new Text(contentContainer, SWT.BORDER); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.widthHint = 200; |
| labelText.setLayoutData(gd); |
| labelText.setEditable(ed.isUserDefined()); |
| label = new Label(contentContainer, SWT.NULL); |
| label.setText(Messages.RootScopePage_desc); |
| gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); |
| label.setLayoutData(gd); |
| descText = new Text(contentContainer, SWT.BORDER | SWT.MULTI | SWT.WRAP); |
| gd = new GridData(GridData.FILL_HORIZONTAL); |
| descText.setEditable(ed.isUserDefined()); |
| gd.widthHint = 200; |
| gd.heightHint = 48; |
| descText.setLayoutData(gd); |
| } |
| |
| int ccol = createScopeContents(contentContainer); |
| // adjust number of columns if needed |
| if (ccol > layout.numColumns && isInPreferenceDialog()) { |
| layout.numColumns = ccol; |
| gd = (GridData) masterButton.getLayoutData(); |
| gd.horizontalSpan = layout.numColumns; |
| gd = (GridData) spacer.getLayoutData(); |
| gd.horizontalSpan = layout.numColumns; |
| |
| gd = (GridData) labelText.getLayoutData(); |
| gd.horizontalSpan = layout.numColumns - 1; |
| gd = (GridData) descText.getLayoutData(); |
| gd.horizontalSpan = layout.numColumns - 1; |
| |
| } |
| updateControls(true); |
| return contentContainer; |
| } |
| |
| /** |
| * Called when the value of the master switch has changed. The default |
| * implementation disables the scope contents control when the master switch |
| * is off. Subclass can override this behaviour. |
| * |
| * @param value |
| * <code>true</code> if the master switch is on, |
| * <code>false</code> otherwise. |
| */ |
| |
| protected void masterValueChanged(boolean value) { |
| updateEnableState(value); |
| } |
| |
| private void updateEnableState(boolean enabled) { |
| Control[] children = contentContainer.getChildren(); |
| |
| boolean first = disabledStates.isEmpty(); |
| for (int i = 0; i < children.length; i++) { |
| Control child = children[i]; |
| if (child == masterButton) |
| continue; |
| if (!enabled) { |
| disabledStates.put(child, Boolean.valueOf(child.isEnabled())); |
| child.setEnabled(false); |
| } else { |
| Boolean savedState = disabledStates.get(child); |
| if (!first) |
| child.setEnabled(savedState != null ? savedState |
| .booleanValue() : true); |
| } |
| } |
| } |
| |
| /** |
| * Returns the scope set name passed to the page during initialization. |
| * |
| * @return the name of the current scope set |
| */ |
| |
| protected String getScopeSetName() { |
| return scopeSetName; |
| } |
| |
| /** |
| * Returns the descriptor of the engine associated with this page. |
| * |
| * @return the engine descriptor |
| */ |
| |
| protected IEngineDescriptor getEngineDescriptor() { |
| return ed; |
| } |
| |
| /** |
| * Tests whether the search engine has been selected to participate in the |
| * search. |
| * |
| * @return <code>true</code> if the search engine is enabled, </code>false</code> |
| * otherwise. |
| */ |
| |
| protected boolean isEngineEnabled() { |
| if (!isInPreferenceDialog()) { |
| return true; |
| } |
| return masterButton.getSelection(); |
| } |
| |
| /** |
| * Stores the value of the master switch in the preference store. Subclasses |
| * may override but must call 'super'. |
| * |
| * @return <code>true</code> if the wizard can be closed, |
| * <code>false</code> otherwise. |
| */ |
| |
| @Override |
| public boolean performOk() { |
| getPreferenceStore().setValue(ScopeSet.getMasterKey(ed.getId()), |
| isEngineEnabled()); |
| if (labelText != null) { |
| ed.setLabel(labelText.getText()); |
| ed.setDescription(descText.getText()); |
| } |
| return true; |
| } |
| |
| /** |
| * Sets the value of the master switch to the initial value from the |
| * extension. Subclasses may override but must call 'super'. |
| */ |
| @Override |
| protected void performDefaults() { |
| getPreferenceStore().setToDefault(ScopeSet.getMasterKey(ed.getId())); |
| updateControls(false); |
| super.performDefaults(); |
| } |
| |
| private void updateControls(boolean first) { |
| if (isInPreferenceDialog()) { |
| boolean value = getPreferenceStore().getBoolean(ScopeSet.getMasterKey(ed.getId())); |
| boolean cvalue = masterButton.getSelection(); |
| if (value != cvalue) { |
| masterButton.setSelection(value); |
| masterValueChanged(value); |
| } else if (first) { |
| masterValueChanged(value); |
| } |
| labelText.setText(ed.getLabel()); |
| descText.setText(ed.getDescription()); |
| } |
| } |
| |
| private boolean isInPreferenceDialog() { |
| return getContainer() != null; |
| } |
| |
| /** |
| * Initializes default values of the store to be used when the user presses |
| * 'Defaults' button. Subclasses may override but must call 'super'. |
| * |
| * @param store |
| * the preference store |
| */ |
| |
| protected void initializeDefaults(IPreferenceStore store) { |
| Boolean value = (Boolean) ed.getParameters().get( |
| EngineDescriptor.P_MASTER); |
| store.setDefault(ScopeSet.getMasterKey(ed.getId()), value |
| .booleanValue()); |
| } |
| |
| /** |
| * Abstract method that subclasses must implement in order to provide root |
| * page content. The parent uses <code>GridLayout</code> to position and |
| * size the widgets. Widgets created in this method should use |
| * <code>GridData</code> to configure the way they fit in the overall |
| * page. |
| * <p> |
| * The common widgets created by this page will set number of columns they |
| * need for themselves only. Clients that implement this method should |
| * return the required number of columns so that the root page widgets can |
| * be adjusted if more columns are needed than initially set. |
| * |
| * @param parent |
| * the page parent |
| * @return number of columns required by the client content |
| */ |
| protected abstract int createScopeContents(Composite parent); |
| } |