1 /*******************************************************************************
 
   2  * Copyright (c) 2003 Berthold Daum.
 
   3  * All rights reserved. This program and the accompanying materials 
 
   4  * are made available under the terms of the Common Public License v1.0
 
   5  * which accompanies this distribution, and is available at
 
   6  * http://www.eclipse.org/legal/cpl-v10.html
 
  10  *******************************************************************************/
 
  11 package net.sourceforge.phpeclipse.ui.overlaypages;
 
  13 import java.util.ArrayList;
 
  14 import java.util.Iterator;
 
  15 import java.util.List;
 
  17 import org.eclipse.core.resources.IResource;
 
  18 import org.eclipse.core.runtime.CoreException;
 
  19 import org.eclipse.core.runtime.IAdaptable;
 
  20 import org.eclipse.core.runtime.QualifiedName;
 
  21 import org.eclipse.jface.preference.FieldEditor;
 
  22 import org.eclipse.jface.preference.FieldEditorPreferencePage;
 
  23 import org.eclipse.jface.preference.IPreferenceNode;
 
  24 import org.eclipse.jface.preference.IPreferencePage;
 
  25 import org.eclipse.jface.preference.IPreferenceStore;
 
  26 import org.eclipse.jface.preference.PreferenceDialog;
 
  27 import org.eclipse.jface.preference.PreferenceManager;
 
  28 import org.eclipse.jface.preference.PreferenceNode;
 
  29 import org.eclipse.jface.resource.ImageDescriptor;
 
  30 import org.eclipse.swt.SWT;
 
  31 import org.eclipse.swt.custom.BusyIndicator;
 
  32 import org.eclipse.swt.events.SelectionAdapter;
 
  33 import org.eclipse.swt.events.SelectionEvent;
 
  34 import org.eclipse.swt.layout.GridData;
 
  35 import org.eclipse.swt.layout.GridLayout;
 
  36 import org.eclipse.swt.widgets.Button;
 
  37 import org.eclipse.swt.widgets.Composite;
 
  38 import org.eclipse.swt.widgets.Control;
 
  39 import org.eclipse.ui.IWorkbenchPropertyPage;
 
  42  * @author Berthold Daum
 
  44 public abstract class FieldEditorOverlayPage extends FieldEditorPreferencePage
 
  45                 implements IWorkbenchPropertyPage {
 
  47          * * Name of resource property for the selection of workbench or project
 
  50         public static final String USEPROJECTSETTINGS = "useProjectSettings"; //$NON-NLS-1$
 
  52         private static final String FALSE = "false"; //$NON-NLS-1$
 
  54         private static final String TRUE = "true"; //$NON-NLS-1$
 
  56         private boolean fUseFileSettings = false;
 
  58         // Stores all created field editors
 
  59         private List editors = new ArrayList();
 
  61         // Stores owning element of properties
 
  62         private IAdaptable element;
 
  64         // Additional buttons for property pages
 
  65         private Button useWorkspaceSettingsButton, useProjectSettingsButton,
 
  68         // Overlay preference store for property pages
 
  69         private IPreferenceStore overlayStore;
 
  71         // The image descriptor of this pages title image
 
  72         private ImageDescriptor image;
 
  75         private String pageId;
 
  83         public FieldEditorOverlayPage(int style) {
 
  93         public FieldEditorOverlayPage(int style, boolean isFileSettings) {
 
  95                 fUseFileSettings = isFileSettings;
 
 106         public FieldEditorOverlayPage(String title, int style) {
 
 110         public FieldEditorOverlayPage(String title, int style,
 
 111                         boolean isFileSettings) {
 
 113                 fUseFileSettings = isFileSettings;
 
 126         public FieldEditorOverlayPage(String title, ImageDescriptor image, int style) {
 
 127                 super(title, image, style);
 
 132          * Returns the id of the current preference page as defined in plugin.xml
 
 133          * Subclasses must implement.
 
 135          * @return - the qualifier
 
 137         protected abstract String getPageId();
 
 140          * Receives the object that owns the properties shown in this property page.
 
 142          * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
 
 144         public void setElement(IAdaptable element) {
 
 145                 this.element = element;
 
 149          * Delivers the object that owns the properties shown in this property page.
 
 151          * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
 
 153         public IAdaptable getElement() {
 
 158          * Returns true if this instance represents a property page
 
 160          * @return - true for property pages, false for preference pages
 
 162         public boolean isPropertyPage() {
 
 163                 return getElement() != null;
 
 167          * We override the addField method. This allows us to store each field
 
 168          * editor added by subclasses in a list for later processing.
 
 170          * @see org.eclipse.jface.preference.FieldEditorPreferencePage#addField(org.eclipse.jface.preference.FieldEditor)
 
 172         protected void addField(FieldEditor editor) {
 
 174                 super.addField(editor);
 
 178          * We override the createControl method. In case of property pages we create
 
 179          * a new PropertyStore as local preference store. After all control have
 
 180          * been create, we enable/disable these controls.
 
 182          * @see org.eclipse.jface.preference.PreferencePage#createControl()
 
 184         public void createControl(Composite parent) {
 
 185                 // Special treatment for property pages
 
 186                 if (isPropertyPage()) {
 
 188                         pageId = getPageId();
 
 189                         // Create an overlay preference store and fill it with properties
 
 190                         overlayStore = new PropertyStore((IResource) getElement(), super
 
 191                                         .getPreferenceStore(), pageId);
 
 192                         // Set overlay store as current preference store
 
 194                 super.createControl(parent);
 
 195                 // Update state of all subclass controls
 
 196                 if (isPropertyPage())
 
 197                         updateFieldEditors();
 
 201          * We override the createContents method. In case of property pages we
 
 202          * insert two radio buttons at the top of the page.
 
 204          * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
 
 206         protected Control createContents(Composite parent) {
 
 207                 if (isPropertyPage())
 
 208                         createSelectionGroup(parent);
 
 209                 return super.createContents(parent);
 
 213          * Creates and initializes a selection group with two choice buttons and one
 
 217          *            the parent composite
 
 219         private void createSelectionGroup(Composite parent) {
 
 220                 Composite comp = new Composite(parent, SWT.NONE);
 
 221                 GridLayout layout = new GridLayout(2, false);
 
 222                 layout.marginHeight = 0;
 
 223                 layout.marginWidth = 0;
 
 224                 comp.setLayout(layout);
 
 225                 comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 226                 Composite radioGroup = new Composite(comp, SWT.NONE);
 
 227                 radioGroup.setLayout(new GridLayout());
 
 228                 radioGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 229                 useWorkspaceSettingsButton = createRadioButton(radioGroup, Messages
 
 230                                 .getString("OverlayPage.Use_Workspace_Settings")); //$NON-NLS-1$
 
 231                 if (fUseFileSettings) {
 
 232                         useProjectSettingsButton = createRadioButton(radioGroup, Messages
 
 233                                         .getString("OverlayPage.Use_File_Settings")); //$NON-NLS-1$
 
 235                         useProjectSettingsButton = createRadioButton(radioGroup, Messages
 
 236                                         .getString("OverlayPage.Use_Project_Settings")); //$NON-NLS-1$
 
 238                 configureButton = new Button(comp, SWT.PUSH);
 
 239                 configureButton.setText(Messages
 
 240                                 .getString("OverlayPage.Configure_Workspace_Settings")); //$NON-NLS-1$
 
 241                 configureButton.addSelectionListener(new SelectionAdapter() {
 
 242                         public void widgetSelected(SelectionEvent e) {
 
 243                                 configureWorkspaceSettings();
 
 246                 // Set workspace/project radio buttons
 
 248                         String use = ((IResource) getElement())
 
 249                                         .getPersistentProperty(new QualifiedName(pageId,
 
 250                                                         USEPROJECTSETTINGS));
 
 251                         if (TRUE.equals(use)) {
 
 252                                 useProjectSettingsButton.setSelection(true);
 
 253                                 configureButton.setEnabled(false);
 
 255                                 useWorkspaceSettingsButton.setSelection(true);
 
 256                 } catch (CoreException e) {
 
 257                         useWorkspaceSettingsButton.setSelection(true);
 
 262          * Convenience method creating a radio button
 
 265          *            the parent composite
 
 268          * @return - the new button
 
 270         private Button createRadioButton(Composite parent, String label) {
 
 271                 final Button button = new Button(parent, SWT.RADIO);
 
 272                 button.setText(label);
 
 273                 button.addSelectionListener(new SelectionAdapter() {
 
 274                         public void widgetSelected(SelectionEvent e) {
 
 276                                                 .setEnabled(button == useWorkspaceSettingsButton);
 
 277                                 updateFieldEditors();
 
 284          * Returns in case of property pages the overlay store, in case of
 
 285          * preference pages the standard preference store
 
 287          * @see org.eclipse.jface.preference.PreferencePage#getPreferenceStore()
 
 289         public IPreferenceStore getPreferenceStore() {
 
 290                 if (isPropertyPage())
 
 292                 return super.getPreferenceStore();
 
 296          * Enables or disables the field editors and buttons of this page
 
 298         private void updateFieldEditors() {
 
 299                 // We iterate through all field editors
 
 300                 boolean enabled = useProjectSettingsButton.getSelection();
 
 301                 updateFieldEditors(enabled);
 
 305          * Enables or disables the field editors and buttons of this page Subclasses
 
 311         protected void updateFieldEditors(boolean enabled) {
 
 312                 Composite parent = getFieldEditorParent();
 
 313                 Iterator it = editors.iterator();
 
 314                 while (it.hasNext()) {
 
 315                         FieldEditor editor = (FieldEditor) it.next();
 
 316                         editor.setEnabled(enabled, parent);
 
 321          * We override the performOk method. In case of property pages we copy the
 
 322          * values in the overlay store into the property values of the selected
 
 323          * project. We also save the state of the radio buttons.
 
 325          * @see org.eclipse.jface.preference.IPreferencePage#performOk()
 
 327         public boolean performOk() {
 
 328                 boolean result = super.performOk();
 
 329                 if (result && isPropertyPage()) {
 
 330                         // Save state of radiobuttons in project properties
 
 331                         IResource resource = (IResource) getElement();
 
 333                                 String value = (useProjectSettingsButton.getSelection()) ? TRUE
 
 335                                 resource.setPersistentProperty(new QualifiedName(pageId,
 
 336                                                 USEPROJECTSETTINGS), value);
 
 337                         } catch (CoreException e) {
 
 344          * We override the performDefaults method. In case of property pages we
 
 345          * switch back to the workspace settings and disable the field editors.
 
 347          * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
 
 349         protected void performDefaults() {
 
 350                 if (isPropertyPage()) {
 
 351                         useWorkspaceSettingsButton.setSelection(true);
 
 352                         useProjectSettingsButton.setSelection(false);
 
 353                         configureButton.setEnabled(true);
 
 354                         updateFieldEditors();
 
 356                 super.performDefaults();
 
 360          * Creates a new preferences page and opens it
 
 362          * @see com.bdaum.SpellChecker.preferences.SpellCheckerPreferencePage#configureWorkspaceSettings()
 
 364         protected void configureWorkspaceSettings() {
 
 366                         // create a new instance of the current class
 
 367                         IPreferencePage page = (IPreferencePage) this.getClass()
 
 369                         page.setTitle(getTitle());
 
 370                         page.setImageDescriptor(image);
 
 372                         showPreferencePage(pageId, page);
 
 373                 } catch (InstantiationException e) {
 
 375                 } catch (IllegalAccessException e) {
 
 381          * Show a single preference pages
 
 384          *            the preference page identification
 
 386          *            the preference page
 
 388         protected void showPreferencePage(String id, IPreferencePage page) {
 
 389                 final IPreferenceNode targetNode = new PreferenceNode(id, page);
 
 390                 PreferenceManager manager = new PreferenceManager();
 
 391                 manager.addToRoot(targetNode);
 
 392                 final PreferenceDialog dialog = new PreferenceDialog(getControl()
 
 393                                 .getShell(), manager);
 
 394                 BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
 
 397                                 dialog.setMessage(targetNode.getLabelText());