/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.ui.preferences; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import java.util.Map.Entry; import net.sourceforge.phpdt.core.IJavaProject; import net.sourceforge.phpdt.core.JavaCore; import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener; //import net.sourceforge.phpeclipse.PHPeclipsePlugin; import net.sourceforge.phpeclipse.ui.WebUI; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; //import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Widget; /** * Abstract options configuration block providing a general implementation for * setting up an options configuration page. * * @since 2.1 */ public abstract class OptionsConfigurationBlock { protected static class ControlData { private String fKey; private String[] fValues; public ControlData(String key, String[] values) { fKey = key; fValues = values; } public String getKey() { return fKey; } public String getValue(boolean selection) { int index = selection ? 0 : 1; return fValues[index]; } public String getValue(int index) { return fValues[index]; } public int getSelection(String value) { if (value != null) { for (int i = 0; i < fValues.length; i++) { if (value.equals(fValues[i])) { return i; } } } return fValues.length - 1; // assume the last option is the least // severe } } protected Map fWorkingValues; protected ArrayList fCheckBoxes; protected ArrayList fComboBoxes; protected ArrayList fTextBoxes; protected HashMap fLabels; private SelectionListener fSelectionListener; private ModifyListener fTextModifyListener; protected IStatusChangeListener fContext; protected IJavaProject fProject; // project or null protected String[] fAllKeys; private Shell fShell; public OptionsConfigurationBlock(IStatusChangeListener context, IJavaProject project, String[] allKeys) { fContext = context; fProject = project; fAllKeys = allKeys; fWorkingValues = getOptions(true); testIfOptionsComplete(fWorkingValues, allKeys); fCheckBoxes = new ArrayList(); fComboBoxes = new ArrayList(); fTextBoxes = new ArrayList(2); fLabels = new HashMap(); } private void testIfOptionsComplete(Map workingValues, String[] allKeys) { for (int i = 0; i < allKeys.length; i++) { if (workingValues.get(allKeys[i]) == null) { WebUI .logErrorMessage("preference option missing: " + allKeys[i] + " (" + this.getClass().getName() + ')'); //$NON-NLS-1$//$NON-NLS-2$ } } } protected Map getOptions(boolean inheritJavaCoreOptions) { if (fProject != null) { return fProject.getOptions(inheritJavaCoreOptions); } else { return JavaCore.getOptions(); } } protected Map getDefaultOptions() { return JavaCore.getDefaultOptions(); } public final boolean hasProjectSpecificOptions() { if (fProject != null) { Map settings = fProject.getOptions(false); String[] allKeys = fAllKeys; for (int i = 0; i < allKeys.length; i++) { if (settings.get(allKeys[i]) != null) { return true; } } } return false; } protected void setOptions(Map map) { if (fProject != null) { Map oldOptions = fProject.getOptions(false); fProject.setOptions(map); firePropertyChangeEvents(oldOptions, map); } else { JavaCore.setOptions((Hashtable) map); } } /** * Computes the differences between the given old and new options and fires * corresponding property change events on the Java plugin's mockup * preference store. * * @param oldOptions * The old options * @param newOptions * The new options */ private void firePropertyChangeEvents(Map oldOptions, Map newOptions) { oldOptions = new HashMap(oldOptions); Object source = fProject.getProject(); MockupPreferenceStore store = WebUI.getDefault() .getMockupPreferenceStore(); Iterator iter = newOptions.entrySet().iterator(); while (iter.hasNext()) { Entry entry = (Entry) iter.next(); String name = (String) entry.getKey(); Object oldValue = oldOptions.get(name); Object newValue = entry.getValue(); if ((oldValue != null && !oldValue.equals(newValue)) || (oldValue == null && newValue != null)) store.firePropertyChangeEvent(source, name, oldValue, newValue); oldOptions.remove(name); } iter = oldOptions.entrySet().iterator(); while (iter.hasNext()) { Entry entry = (Entry) iter.next(); store.firePropertyChangeEvent(source, (String) entry.getKey(), entry.getValue(), null); } } protected Shell getShell() { return fShell; } protected void setShell(Shell shell) { fShell = shell; } protected abstract Control createContents(Composite parent); protected Button addCheckBox(Composite parent, String label, String key, String[] values, int indent) { ControlData data = new ControlData(key, values); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); gd.horizontalSpan = 3; gd.horizontalIndent = indent; Button checkBox = new Button(parent, SWT.CHECK); checkBox.setText(label); checkBox.setData(data); checkBox.setLayoutData(gd); checkBox.addSelectionListener(getSelectionListener()); String currValue = (String) fWorkingValues.get(key); checkBox.setSelection(data.getSelection(currValue) == 0); fCheckBoxes.add(checkBox); return checkBox; } protected Combo addComboBox(Composite parent, String label, String key, String[] values, String[] valueLabels, int indent) { ControlData data = new ControlData(key, values); GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); gd.horizontalIndent = indent; Label labelControl = new Label(parent, SWT.LEFT | SWT.WRAP); labelControl.setText(label); labelControl.setLayoutData(gd); Combo comboBox = new Combo(parent, SWT.READ_ONLY); comboBox.setItems(valueLabels); comboBox.setData(data); comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); comboBox.addSelectionListener(getSelectionListener()); fLabels.put(comboBox, labelControl); Label placeHolder = new Label(parent, SWT.NONE); placeHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); String currValue = (String) fWorkingValues.get(key); comboBox.select(data.getSelection(currValue)); fComboBoxes.add(comboBox); return comboBox; } // protected void addInversedComboBox(Composite parent, String label, // String key, String[] values, String[] valueLabels, int indent) { // ControlData data = new ControlData(key, values); // // GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); // gd.horizontalIndent = indent; // gd.horizontalSpan = 3; // // Composite composite = new Composite(parent, SWT.NONE); // GridLayout layout = new GridLayout(); // layout.marginHeight = 0; // layout.marginWidth = 0; // layout.numColumns = 2; // composite.setLayout(layout); // composite.setLayoutData(gd); // // Combo comboBox = new Combo(composite, SWT.READ_ONLY); // comboBox.setItems(valueLabels); // comboBox.setData(data); // comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); // comboBox.addSelectionListener(getSelectionListener()); // // Label labelControl = new Label(composite, SWT.LEFT | SWT.WRAP); // labelControl.setText(label); // labelControl.setLayoutData(new GridData()); // // fLabels.put(comboBox, labelControl); // // String currValue = (String) fWorkingValues.get(key); // comboBox.select(data.getSelection(currValue)); // // fComboBoxes.add(comboBox); // } protected Text addTextField(Composite parent, String label, String key, int indent, int widthHint) { Label labelControl = new Label(parent, SWT.NONE); labelControl.setText(label); labelControl.setLayoutData(new GridData()); Text textBox = new Text(parent, SWT.BORDER | SWT.SINGLE); textBox.setData(key); textBox.setLayoutData(new GridData()); fLabels.put(textBox, labelControl); String currValue = (String) fWorkingValues.get(key); if (currValue != null) { textBox.setText(currValue); } textBox.addModifyListener(getTextModifyListener()); GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); if (widthHint != 0) { data.widthHint = widthHint; } data.horizontalIndent = indent; data.horizontalSpan = 2; textBox.setLayoutData(data); fTextBoxes.add(textBox); return textBox; } protected SelectionListener getSelectionListener() { if (fSelectionListener == null) { fSelectionListener = new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { controlChanged(e.widget); } }; } return fSelectionListener; } protected ModifyListener getTextModifyListener() { if (fTextModifyListener == null) { fTextModifyListener = new ModifyListener() { public void modifyText(ModifyEvent e) { textChanged((Text) e.widget); } }; } return fTextModifyListener; } protected void controlChanged(Widget widget) { ControlData data = (ControlData) widget.getData(); String newValue = null; if (widget instanceof Button) { newValue = data.getValue(((Button) widget).getSelection()); } else if (widget instanceof Combo) { newValue = data.getValue(((Combo) widget).getSelectionIndex()); } else { return; } fWorkingValues.put(data.getKey(), newValue); validateSettings(data.getKey(), newValue); } protected void textChanged(Text textControl) { String key = (String) textControl.getData(); String number = textControl.getText(); fWorkingValues.put(key, number); validateSettings(key, number); } // protected boolean checkValue(String key, String value) { // return value.equals(fWorkingValues.get(key)); // } /* * (non-javadoc) Update fields and validate. @param changedKey Key that * changed, or null, if all changed. */ protected abstract void validateSettings(String changedKey, String newValue); protected String[] getTokens(String text, String separator) { StringTokenizer tok = new StringTokenizer(text, separator); //$NON-NLS-1$ int nTokens = tok.countTokens(); String[] res = new String[nTokens]; for (int i = 0; i < res.length; i++) { res[i] = tok.nextToken().trim(); } return res; } public boolean performOk(boolean enabled) { String[] allKeys = fAllKeys; Map actualOptions = getOptions(false); // preserve other options boolean hasChanges = false; for (int i = 0; i < allKeys.length; i++) { String key = allKeys[i]; String oldVal = (String) actualOptions.get(key); String val = null; if (enabled) { val = (String) fWorkingValues.get(key); if (val != null && !val.equals(oldVal)) { hasChanges = true; actualOptions.put(key, val); } } else { if (oldVal != null) { actualOptions.remove(key); hasChanges = true; } } } if (hasChanges) { boolean doBuild = false; String[] strings = getFullBuildDialogStrings(fProject == null); if (strings != null) { MessageDialog dialog = new MessageDialog(getShell(), strings[0], null, strings[1], MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 2); int res = dialog.open(); if (res == 0) { doBuild = true; } else if (res != 1) { return false; // cancel pressed } } setOptions(actualOptions); if (doBuild) { boolean res = doFullBuild(); if (!res) { return false; } } } return true; } protected abstract String[] getFullBuildDialogStrings( boolean workspaceSettings); protected boolean doFullBuild() { Job buildJob = new Job(PreferencesMessages .getString("OptionsConfigurationBlock.job.title")) { //$NON-NLS-1$ /* * (non-Javadoc) * * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) */ protected IStatus run(IProgressMonitor monitor) { try { if (fProject != null) { monitor .setTaskName(PreferencesMessages .getFormattedString( "OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$ fProject.getProject().build( IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor, 1)); WebUI.getWorkspace().build( IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(monitor, 1)); } else { monitor .setTaskName(PreferencesMessages .getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$ WebUI.getWorkspace().build( IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor, 2)); } } catch (CoreException e) { return e.getStatus(); } catch (OperationCanceledException e) { return Status.CANCEL_STATUS; } finally { monitor.done(); } return Status.OK_STATUS; } public boolean belongsTo(Object family) { return ResourcesPlugin.FAMILY_MANUAL_BUILD == family; } }; buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory() .buildRule()); buildJob.setUser(true); buildJob.schedule(); return true; } public void performDefaults() { fWorkingValues = getDefaultOptions(); updateControls(); validateSettings(null, null); } protected void updateControls() { // update the UI for (int i = fCheckBoxes.size() - 1; i >= 0; i--) { updateCheckBox((Button) fCheckBoxes.get(i)); } for (int i = fComboBoxes.size() - 1; i >= 0; i--) { updateCombo((Combo) fComboBoxes.get(i)); } for (int i = fTextBoxes.size() - 1; i >= 0; i--) { updateText((Text) fTextBoxes.get(i)); } } protected void updateCombo(Combo curr) { ControlData data = (ControlData) curr.getData(); String currValue = (String) fWorkingValues.get(data.getKey()); curr.select(data.getSelection(currValue)); } protected void updateCheckBox(Button curr) { ControlData data = (ControlData) curr.getData(); String currValue = (String) fWorkingValues.get(data.getKey()); curr.setSelection(data.getSelection(currValue) == 0); } protected void updateText(Text curr) { String key = (String) curr.getData(); String currValue = (String) fWorkingValues.get(key); if (currValue != null) { curr.setText(currValue); } } // protected Button getCheckBox(String key) { // for (int i = fCheckBoxes.size() - 1; i >= 0; i--) { // Button curr = (Button) fCheckBoxes.get(i); // ControlData data = (ControlData) curr.getData(); // if (key.equals(data.getKey())) { // return curr; // } // } // return null; // } protected Combo getComboBox(String key) { for (int i = fComboBoxes.size() - 1; i >= 0; i--) { Combo curr = (Combo) fComboBoxes.get(i); ControlData data = (ControlData) curr.getData(); if (key.equals(data.getKey())) { return curr; } } return null; } // protected void setComboEnabled(String key, boolean enabled) { // Combo combo = getComboBox(key); // Label label = (Label) fLabels.get(combo); // combo.setEnabled(enabled); // label.setEnabled(enabled); // } }