1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.preferences;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.Hashtable;
16 import java.util.Iterator;
18 import java.util.StringTokenizer;
19 import java.util.Map.Entry;
21 import net.sourceforge.phpdt.core.IJavaProject;
22 import net.sourceforge.phpdt.core.JavaCore;
23 import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
24 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
25 import net.sourceforge.phpeclipse.ui.WebUI;
27 import org.eclipse.core.resources.IncrementalProjectBuilder;
28 import org.eclipse.core.resources.ResourcesPlugin;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.core.runtime.IProgressMonitor;
31 import org.eclipse.core.runtime.IStatus;
32 import org.eclipse.core.runtime.OperationCanceledException;
33 import org.eclipse.core.runtime.Status;
34 import org.eclipse.core.runtime.SubProgressMonitor;
35 import org.eclipse.core.runtime.jobs.Job;
36 import org.eclipse.jface.dialogs.IDialogConstants;
37 import org.eclipse.jface.dialogs.MessageDialog;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.events.ModifyEvent;
40 import org.eclipse.swt.events.ModifyListener;
41 import org.eclipse.swt.events.SelectionEvent;
42 import org.eclipse.swt.events.SelectionListener;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Button;
46 import org.eclipse.swt.widgets.Combo;
47 import org.eclipse.swt.widgets.Composite;
48 import org.eclipse.swt.widgets.Control;
49 import org.eclipse.swt.widgets.Label;
50 import org.eclipse.swt.widgets.Shell;
51 import org.eclipse.swt.widgets.Text;
52 import org.eclipse.swt.widgets.Widget;
55 * Abstract options configuration block providing a general implementation for
56 * setting up an options configuration page.
60 public abstract class OptionsConfigurationBlock {
62 protected static class ControlData {
65 private String[] fValues;
67 public ControlData(String key, String[] values) {
72 public String getKey() {
76 public String getValue(boolean selection) {
77 int index = selection ? 0 : 1;
78 return fValues[index];
81 public String getValue(int index) {
82 return fValues[index];
85 public int getSelection(String value) {
87 for (int i = 0; i < fValues.length; i++) {
88 if (value.equals(fValues[i])) {
93 return fValues.length - 1; // assume the last option is the least
98 protected Map fWorkingValues;
100 protected ArrayList fCheckBoxes;
102 protected ArrayList fComboBoxes;
104 protected ArrayList fTextBoxes;
106 protected HashMap fLabels;
108 private SelectionListener fSelectionListener;
110 private ModifyListener fTextModifyListener;
112 protected IStatusChangeListener fContext;
114 protected IJavaProject fProject; // project or null
116 protected String[] fAllKeys;
118 private Shell fShell;
120 public OptionsConfigurationBlock(IStatusChangeListener context,
121 IJavaProject project, String[] allKeys) {
126 fWorkingValues = getOptions(true);
127 testIfOptionsComplete(fWorkingValues, allKeys);
129 fCheckBoxes = new ArrayList();
130 fComboBoxes = new ArrayList();
131 fTextBoxes = new ArrayList(2);
132 fLabels = new HashMap();
135 private void testIfOptionsComplete(Map workingValues, String[] allKeys) {
136 for (int i = 0; i < allKeys.length; i++) {
137 if (workingValues.get(allKeys[i]) == null) {
139 .logErrorMessage("preference option missing: " + allKeys[i] + " (" + this.getClass().getName() + ')'); //$NON-NLS-1$//$NON-NLS-2$
144 protected Map getOptions(boolean inheritJavaCoreOptions) {
145 if (fProject != null) {
146 return fProject.getOptions(inheritJavaCoreOptions);
148 return JavaCore.getOptions();
152 protected Map getDefaultOptions() {
153 return JavaCore.getDefaultOptions();
156 public final boolean hasProjectSpecificOptions() {
157 if (fProject != null) {
158 Map settings = fProject.getOptions(false);
159 String[] allKeys = fAllKeys;
160 for (int i = 0; i < allKeys.length; i++) {
161 if (settings.get(allKeys[i]) != null) {
169 protected void setOptions(Map map) {
170 if (fProject != null) {
171 Map oldOptions = fProject.getOptions(false);
172 fProject.setOptions(map);
173 firePropertyChangeEvents(oldOptions, map);
175 JavaCore.setOptions((Hashtable) map);
180 * Computes the differences between the given old and new options and fires
181 * corresponding property change events on the Java plugin's mockup
189 private void firePropertyChangeEvents(Map oldOptions, Map newOptions) {
190 oldOptions = new HashMap(oldOptions);
191 Object source = fProject.getProject();
192 MockupPreferenceStore store = WebUI.getDefault()
193 .getMockupPreferenceStore();
194 Iterator iter = newOptions.entrySet().iterator();
195 while (iter.hasNext()) {
196 Entry entry = (Entry) iter.next();
198 String name = (String) entry.getKey();
199 Object oldValue = oldOptions.get(name);
200 Object newValue = entry.getValue();
202 if ((oldValue != null && !oldValue.equals(newValue))
203 || (oldValue == null && newValue != null))
204 store.firePropertyChangeEvent(source, name, oldValue, newValue);
205 oldOptions.remove(name);
208 iter = oldOptions.entrySet().iterator();
209 while (iter.hasNext()) {
210 Entry entry = (Entry) iter.next();
211 store.firePropertyChangeEvent(source, (String) entry.getKey(),
212 entry.getValue(), null);
216 protected Shell getShell() {
220 protected void setShell(Shell shell) {
224 protected abstract Control createContents(Composite parent);
226 protected Button addCheckBox(Composite parent, String label, String key,
227 String[] values, int indent) {
228 ControlData data = new ControlData(key, values);
230 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
231 gd.horizontalSpan = 3;
232 gd.horizontalIndent = indent;
234 Button checkBox = new Button(parent, SWT.CHECK);
235 checkBox.setText(label);
236 checkBox.setData(data);
237 checkBox.setLayoutData(gd);
238 checkBox.addSelectionListener(getSelectionListener());
240 String currValue = (String) fWorkingValues.get(key);
241 checkBox.setSelection(data.getSelection(currValue) == 0);
243 fCheckBoxes.add(checkBox);
248 protected Combo addComboBox(Composite parent, String label, String key,
249 String[] values, String[] valueLabels, int indent) {
250 ControlData data = new ControlData(key, values);
252 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
253 gd.horizontalIndent = indent;
255 Label labelControl = new Label(parent, SWT.LEFT | SWT.WRAP);
256 labelControl.setText(label);
257 labelControl.setLayoutData(gd);
259 Combo comboBox = new Combo(parent, SWT.READ_ONLY);
260 comboBox.setItems(valueLabels);
261 comboBox.setData(data);
262 comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
263 comboBox.addSelectionListener(getSelectionListener());
265 fLabels.put(comboBox, labelControl);
267 Label placeHolder = new Label(parent, SWT.NONE);
268 placeHolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
270 String currValue = (String) fWorkingValues.get(key);
271 comboBox.select(data.getSelection(currValue));
273 fComboBoxes.add(comboBox);
277 protected void addInversedComboBox(Composite parent, String label,
278 String key, String[] values, String[] valueLabels, int indent) {
279 ControlData data = new ControlData(key, values);
281 GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
282 gd.horizontalIndent = indent;
283 gd.horizontalSpan = 3;
285 Composite composite = new Composite(parent, SWT.NONE);
286 GridLayout layout = new GridLayout();
287 layout.marginHeight = 0;
288 layout.marginWidth = 0;
289 layout.numColumns = 2;
290 composite.setLayout(layout);
291 composite.setLayoutData(gd);
293 Combo comboBox = new Combo(composite, SWT.READ_ONLY);
294 comboBox.setItems(valueLabels);
295 comboBox.setData(data);
296 comboBox.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
297 comboBox.addSelectionListener(getSelectionListener());
299 Label labelControl = new Label(composite, SWT.LEFT | SWT.WRAP);
300 labelControl.setText(label);
301 labelControl.setLayoutData(new GridData());
303 fLabels.put(comboBox, labelControl);
305 String currValue = (String) fWorkingValues.get(key);
306 comboBox.select(data.getSelection(currValue));
308 fComboBoxes.add(comboBox);
311 protected Text addTextField(Composite parent, String label, String key,
312 int indent, int widthHint) {
313 Label labelControl = new Label(parent, SWT.NONE);
314 labelControl.setText(label);
315 labelControl.setLayoutData(new GridData());
317 Text textBox = new Text(parent, SWT.BORDER | SWT.SINGLE);
318 textBox.setData(key);
319 textBox.setLayoutData(new GridData());
321 fLabels.put(textBox, labelControl);
323 String currValue = (String) fWorkingValues.get(key);
324 if (currValue != null) {
325 textBox.setText(currValue);
327 textBox.addModifyListener(getTextModifyListener());
329 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
330 if (widthHint != 0) {
331 data.widthHint = widthHint;
333 data.horizontalIndent = indent;
334 data.horizontalSpan = 2;
335 textBox.setLayoutData(data);
337 fTextBoxes.add(textBox);
341 protected SelectionListener getSelectionListener() {
342 if (fSelectionListener == null) {
343 fSelectionListener = new SelectionListener() {
344 public void widgetDefaultSelected(SelectionEvent e) {
347 public void widgetSelected(SelectionEvent e) {
348 controlChanged(e.widget);
352 return fSelectionListener;
355 protected ModifyListener getTextModifyListener() {
356 if (fTextModifyListener == null) {
357 fTextModifyListener = new ModifyListener() {
358 public void modifyText(ModifyEvent e) {
359 textChanged((Text) e.widget);
363 return fTextModifyListener;
366 protected void controlChanged(Widget widget) {
367 ControlData data = (ControlData) widget.getData();
368 String newValue = null;
369 if (widget instanceof Button) {
370 newValue = data.getValue(((Button) widget).getSelection());
371 } else if (widget instanceof Combo) {
372 newValue = data.getValue(((Combo) widget).getSelectionIndex());
376 fWorkingValues.put(data.getKey(), newValue);
378 validateSettings(data.getKey(), newValue);
381 protected void textChanged(Text textControl) {
382 String key = (String) textControl.getData();
383 String number = textControl.getText();
384 fWorkingValues.put(key, number);
385 validateSettings(key, number);
388 protected boolean checkValue(String key, String value) {
389 return value.equals(fWorkingValues.get(key));
393 * (non-javadoc) Update fields and validate. @param changedKey Key that
394 * changed, or null, if all changed.
396 protected abstract void validateSettings(String changedKey, String newValue);
398 protected String[] getTokens(String text, String separator) {
399 StringTokenizer tok = new StringTokenizer(text, separator); //$NON-NLS-1$
400 int nTokens = tok.countTokens();
401 String[] res = new String[nTokens];
402 for (int i = 0; i < res.length; i++) {
403 res[i] = tok.nextToken().trim();
408 public boolean performOk(boolean enabled) {
409 String[] allKeys = fAllKeys;
410 Map actualOptions = getOptions(false);
412 // preserve other options
413 boolean hasChanges = false;
414 for (int i = 0; i < allKeys.length; i++) {
415 String key = allKeys[i];
416 String oldVal = (String) actualOptions.get(key);
419 val = (String) fWorkingValues.get(key);
420 if (val != null && !val.equals(oldVal)) {
422 actualOptions.put(key, val);
425 if (oldVal != null) {
426 actualOptions.remove(key);
433 boolean doBuild = false;
434 String[] strings = getFullBuildDialogStrings(fProject == null);
435 if (strings != null) {
436 MessageDialog dialog = new MessageDialog(getShell(),
437 strings[0], null, strings[1], MessageDialog.QUESTION,
438 new String[] { IDialogConstants.YES_LABEL,
439 IDialogConstants.NO_LABEL,
440 IDialogConstants.CANCEL_LABEL }, 2);
441 int res = dialog.open();
444 } else if (res != 1) {
445 return false; // cancel pressed
448 setOptions(actualOptions);
450 boolean res = doFullBuild();
459 protected abstract String[] getFullBuildDialogStrings(
460 boolean workspaceSettings);
462 protected boolean doFullBuild() {
464 Job buildJob = new Job(PreferencesMessages
465 .getString("OptionsConfigurationBlock.job.title")) { //$NON-NLS-1$
469 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
471 protected IStatus run(IProgressMonitor monitor) {
473 if (fProject != null) {
475 .setTaskName(PreferencesMessages
477 "OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$
478 fProject.getProject().build(
479 IncrementalProjectBuilder.FULL_BUILD,
480 new SubProgressMonitor(monitor, 1));
481 WebUI.getWorkspace().build(
482 IncrementalProjectBuilder.INCREMENTAL_BUILD,
483 new SubProgressMonitor(monitor, 1));
486 .setTaskName(PreferencesMessages
487 .getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$
488 WebUI.getWorkspace().build(
489 IncrementalProjectBuilder.FULL_BUILD,
490 new SubProgressMonitor(monitor, 2));
492 } catch (CoreException e) {
493 return e.getStatus();
494 } catch (OperationCanceledException e) {
495 return Status.CANCEL_STATUS;
499 return Status.OK_STATUS;
502 public boolean belongsTo(Object family) {
503 return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
507 buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory()
509 buildJob.setUser(true);
514 public void performDefaults() {
515 fWorkingValues = getDefaultOptions();
517 validateSettings(null, null);
520 protected void updateControls() {
522 for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
523 updateCheckBox((Button) fCheckBoxes.get(i));
525 for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
526 updateCombo((Combo) fComboBoxes.get(i));
528 for (int i = fTextBoxes.size() - 1; i >= 0; i--) {
529 updateText((Text) fTextBoxes.get(i));
533 protected void updateCombo(Combo curr) {
534 ControlData data = (ControlData) curr.getData();
536 String currValue = (String) fWorkingValues.get(data.getKey());
537 curr.select(data.getSelection(currValue));
540 protected void updateCheckBox(Button curr) {
541 ControlData data = (ControlData) curr.getData();
543 String currValue = (String) fWorkingValues.get(data.getKey());
544 curr.setSelection(data.getSelection(currValue) == 0);
547 protected void updateText(Text curr) {
548 String key = (String) curr.getData();
550 String currValue = (String) fWorkingValues.get(key);
551 if (currValue != null) {
552 curr.setText(currValue);
556 protected Button getCheckBox(String key) {
557 for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
558 Button curr = (Button) fCheckBoxes.get(i);
559 ControlData data = (ControlData) curr.getData();
560 if (key.equals(data.getKey())) {
567 protected Combo getComboBox(String key) {
568 for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
569 Combo curr = (Combo) fComboBoxes.get(i);
570 ControlData data = (ControlData) curr.getData();
571 if (key.equals(data.getKey())) {
578 protected void setComboEnabled(String key, boolean enabled) {
579 Combo combo = getComboBox(key);
580 Label label = (Label) fLabels.get(combo);
581 combo.setEnabled(enabled);
582 label.setEnabled(enabled);