001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.ui.preferences;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.IdentityHashMap;
015: import java.util.List;
016: import java.util.Map;
017: import java.util.StringTokenizer;
018:
019: import org.eclipse.core.runtime.preferences.DefaultScope;
020: import org.eclipse.core.runtime.preferences.IEclipsePreferences;
021: import org.eclipse.core.runtime.preferences.IScopeContext;
022: import org.eclipse.core.runtime.preferences.InstanceScope;
023:
024: import org.eclipse.core.resources.IProject;
025: import org.eclipse.core.resources.ProjectScope;
026:
027: import org.eclipse.swt.SWT;
028: import org.eclipse.swt.events.ModifyEvent;
029: import org.eclipse.swt.events.ModifyListener;
030: import org.eclipse.swt.events.SelectionEvent;
031: import org.eclipse.swt.events.SelectionListener;
032: import org.eclipse.swt.layout.GridData;
033: import org.eclipse.swt.layout.GridLayout;
034: import org.eclipse.swt.widgets.Button;
035: import org.eclipse.swt.widgets.Combo;
036: import org.eclipse.swt.widgets.Composite;
037: import org.eclipse.swt.widgets.Control;
038: import org.eclipse.swt.widgets.Label;
039: import org.eclipse.swt.widgets.Link;
040: import org.eclipse.swt.widgets.Shell;
041: import org.eclipse.swt.widgets.Text;
042: import org.eclipse.swt.widgets.Widget;
043:
044: import org.eclipse.jface.dialogs.IDialogConstants;
045: import org.eclipse.jface.dialogs.IDialogSettings;
046: import org.eclipse.jface.dialogs.MessageDialog;
047: import org.eclipse.jface.resource.JFaceResources;
048:
049: import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
050: import org.eclipse.ui.preferences.IWorkingCopyManager;
051: import org.eclipse.ui.preferences.WorkingCopyManager;
052:
053: import org.eclipse.ui.forms.events.ExpansionAdapter;
054: import org.eclipse.ui.forms.events.ExpansionEvent;
055: import org.eclipse.ui.forms.widgets.ExpandableComposite;
056:
057: import org.eclipse.jdt.core.JavaCore;
058:
059: import org.eclipse.jdt.ui.JavaUI;
060:
061: import org.eclipse.jdt.internal.ui.JavaPlugin;
062: import org.eclipse.jdt.internal.ui.util.CoreUtility;
063: import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
064:
065: import org.osgi.service.prefs.BackingStoreException;
066:
067: /**
068: * Abstract options configuration block providing a general implementation for setting up
069: * an options configuration page.
070: *
071: * @since 2.1
072: */
073: public abstract class OptionsConfigurationBlock {
074:
075: public static final class Key {
076:
077: private String fQualifier;
078: private String fKey;
079:
080: public Key(String qualifier, String key) {
081: fQualifier = qualifier;
082: fKey = key;
083: }
084:
085: public String getName() {
086: return fKey;
087: }
088:
089: private IEclipsePreferences getNode(IScopeContext context,
090: IWorkingCopyManager manager) {
091: IEclipsePreferences node = context.getNode(fQualifier);
092: if (manager != null) {
093: return manager.getWorkingCopy(node);
094: }
095: return node;
096: }
097:
098: public String getStoredValue(IScopeContext context,
099: IWorkingCopyManager manager) {
100: return getNode(context, manager).get(fKey, null);
101: }
102:
103: public String getStoredValue(IScopeContext[] lookupOrder,
104: boolean ignoreTopScope, IWorkingCopyManager manager) {
105: for (int i = ignoreTopScope ? 1 : 0; i < lookupOrder.length; i++) {
106: String value = getStoredValue(lookupOrder[i], manager);
107: if (value != null) {
108: return value;
109: }
110: }
111: return null;
112: }
113:
114: public void setStoredValue(IScopeContext context, String value,
115: IWorkingCopyManager manager) {
116: if (value != null) {
117: getNode(context, manager).put(fKey, value);
118: } else {
119: getNode(context, manager).remove(fKey);
120: }
121: }
122:
123: /* (non-Javadoc)
124: * @see java.lang.Object#toString()
125: */
126: public String toString() {
127: return fQualifier + '/' + fKey;
128: }
129:
130: public String getQualifier() {
131: return fQualifier;
132: }
133:
134: }
135:
136: protected static class ControlData {
137: private Key fKey;
138: private String[] fValues;
139:
140: public ControlData(Key key, String[] values) {
141: fKey = key;
142: fValues = values;
143: }
144:
145: public Key getKey() {
146: return fKey;
147: }
148:
149: public String getValue(boolean selection) {
150: int index = selection ? 0 : 1;
151: return fValues[index];
152: }
153:
154: public String getValue(int index) {
155: return fValues[index];
156: }
157:
158: public int getSelection(String value) {
159: if (value != null) {
160: for (int i = 0; i < fValues.length; i++) {
161: if (value.equals(fValues[i])) {
162: return i;
163: }
164: }
165: }
166: return fValues.length - 1; // assume the last option is the least severe
167: }
168: }
169:
170: private static final String REBUILD_COUNT_KEY = "preferences_build_requested"; //$NON-NLS-1$
171:
172: private static final String SETTINGS_EXPANDED = "expanded"; //$NON-NLS-1$
173:
174: protected final ArrayList fCheckBoxes;
175: protected final ArrayList fComboBoxes;
176: protected final ArrayList fTextBoxes;
177: protected final HashMap fLabels;
178: protected final ArrayList fExpandedComposites;
179:
180: private SelectionListener fSelectionListener;
181: private ModifyListener fTextModifyListener;
182:
183: protected IStatusChangeListener fContext;
184: protected final IProject fProject; // project or null
185: protected final Key[] fAllKeys;
186:
187: private IScopeContext[] fLookupOrder;
188:
189: private Shell fShell;
190:
191: private final IWorkingCopyManager fManager;
192: private IWorkbenchPreferenceContainer fContainer;
193:
194: private Map fDisabledProjectSettings; // null when project specific settings are turned off
195:
196: private int fRebuildCount; /// used to prevent multiple dialogs that ask for a rebuild
197:
198: public OptionsConfigurationBlock(IStatusChangeListener context,
199: IProject project, Key[] allKeys,
200: IWorkbenchPreferenceContainer container) {
201: fContext = context;
202: fProject = project;
203: fAllKeys = allKeys;
204: fContainer = container;
205: if (container == null) {
206: fManager = new WorkingCopyManager();
207: } else {
208: fManager = container.getWorkingCopyManager();
209: }
210:
211: if (fProject != null) {
212: fLookupOrder = new IScopeContext[] {
213: new ProjectScope(fProject), new InstanceScope(),
214: new DefaultScope() };
215: } else {
216: fLookupOrder = new IScopeContext[] { new InstanceScope(),
217: new DefaultScope() };
218: }
219:
220: testIfOptionsComplete(allKeys);
221: if (fProject == null || hasProjectSpecificOptions(fProject)) {
222: fDisabledProjectSettings = null;
223: } else {
224: fDisabledProjectSettings = new IdentityHashMap();
225: for (int i = 0; i < allKeys.length; i++) {
226: Key curr = allKeys[i];
227: fDisabledProjectSettings.put(curr, curr.getStoredValue(
228: fLookupOrder, false, fManager));
229: }
230: }
231:
232: settingsUpdated();
233:
234: fCheckBoxes = new ArrayList();
235: fComboBoxes = new ArrayList();
236: fTextBoxes = new ArrayList(2);
237: fLabels = new HashMap();
238: fExpandedComposites = new ArrayList();
239:
240: fRebuildCount = getRebuildCount();
241: }
242:
243: protected final IWorkbenchPreferenceContainer getPreferenceContainer() {
244: return fContainer;
245: }
246:
247: protected static Key getKey(String plugin, String key) {
248: return new Key(plugin, key);
249: }
250:
251: protected final static Key getJDTCoreKey(String key) {
252: return getKey(JavaCore.PLUGIN_ID, key);
253: }
254:
255: protected final static Key getJDTUIKey(String key) {
256: return getKey(JavaUI.ID_PLUGIN, key);
257: }
258:
259: private void testIfOptionsComplete(Key[] allKeys) {
260: for (int i = 0; i < allKeys.length; i++) {
261: if (allKeys[i]
262: .getStoredValue(fLookupOrder, false, fManager) == null) {
263: JavaPlugin
264: .logErrorMessage("preference option missing: " + allKeys[i] + " (" + this .getClass().getName() + ')'); //$NON-NLS-1$//$NON-NLS-2$
265: }
266: }
267: }
268:
269: private int getRebuildCount() {
270: return fManager.getWorkingCopy(
271: new DefaultScope().getNode(JavaUI.ID_PLUGIN)).getInt(
272: REBUILD_COUNT_KEY, 0);
273: }
274:
275: private void incrementRebuildCount() {
276: fRebuildCount++;
277: fManager.getWorkingCopy(
278: new DefaultScope().getNode(JavaUI.ID_PLUGIN)).putInt(
279: REBUILD_COUNT_KEY, fRebuildCount);
280: }
281:
282: protected void settingsUpdated() {
283: }
284:
285: public void selectOption(String key, String qualifier) {
286: for (int i = 0; i < fAllKeys.length; i++) {
287: Key curr = fAllKeys[i];
288: if (curr.getName().equals(key)
289: && curr.getQualifier().equals(qualifier)) {
290: selectOption(curr);
291: }
292: }
293: }
294:
295: public void selectOption(Key key) {
296: Control control = findControl(key);
297: if (control != null) {
298: if (!fExpandedComposites.isEmpty()) {
299: ExpandableComposite expandable = getParentExpandableComposite(control);
300: if (expandable != null) {
301: for (int i = 0; i < fExpandedComposites.size(); i++) {
302: ExpandableComposite curr = (ExpandableComposite) fExpandedComposites
303: .get(i);
304: curr.setExpanded(curr == expandable);
305: }
306: expandedStateChanged(expandable);
307: }
308: }
309: control.setFocus();
310: }
311: }
312:
313: public boolean hasProjectSpecificOptions(IProject project) {
314: if (project != null) {
315: IScopeContext projectContext = new ProjectScope(project);
316: Key[] allKeys = fAllKeys;
317: for (int i = 0; i < allKeys.length; i++) {
318: if (allKeys[i].getStoredValue(projectContext, fManager) != null) {
319: return true;
320: }
321: }
322: }
323: return false;
324: }
325:
326: protected Shell getShell() {
327: return fShell;
328: }
329:
330: protected void setShell(Shell shell) {
331: fShell = shell;
332: }
333:
334: protected abstract Control createContents(Composite parent);
335:
336: protected Button addCheckBox(Composite parent, String label,
337: Key key, String[] values, int indent) {
338: ControlData data = new ControlData(key, values);
339:
340: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
341: gd.horizontalSpan = 3;
342: gd.horizontalIndent = indent;
343:
344: Button checkBox = new Button(parent, SWT.CHECK);
345: checkBox.setFont(JFaceResources.getDialogFont());
346: checkBox.setText(label);
347: checkBox.setData(data);
348: checkBox.setLayoutData(gd);
349: checkBox.addSelectionListener(getSelectionListener());
350:
351: makeScrollableCompositeAware(checkBox);
352:
353: String currValue = getValue(key);
354: checkBox.setSelection(data.getSelection(currValue) == 0);
355:
356: fCheckBoxes.add(checkBox);
357:
358: return checkBox;
359: }
360:
361: protected Button addCheckBoxWithLink(Composite parent,
362: String label, Key key, String[] values, int indent,
363: int widthHint, SelectionListener listener) {
364: ControlData data = new ControlData(key, values);
365:
366: GridData gd = new GridData(GridData.FILL, GridData.FILL, true,
367: false);
368: gd.horizontalSpan = 3;
369: gd.horizontalIndent = indent;
370:
371: Composite composite = new Composite(parent, SWT.NONE);
372: GridLayout layout = new GridLayout();
373: layout.marginHeight = 0;
374: layout.marginWidth = 0;
375: layout.numColumns = 2;
376: composite.setLayout(layout);
377: composite.setLayoutData(gd);
378:
379: Button checkBox = new Button(composite, SWT.CHECK);
380: checkBox.setFont(JFaceResources.getDialogFont());
381: checkBox.setData(data);
382: checkBox.setLayoutData(new GridData(GridData.FILL,
383: GridData.BEGINNING, false, false));
384: checkBox.addSelectionListener(getSelectionListener());
385:
386: gd = new GridData(GridData.FILL, GridData.CENTER, true, false);
387: gd.widthHint = widthHint;
388:
389: Link link = new Link(composite, SWT.NONE);
390: link.setText(label);
391: link.setLayoutData(gd);
392: if (listener != null) {
393: link.addSelectionListener(listener);
394: }
395:
396: makeScrollableCompositeAware(link);
397: makeScrollableCompositeAware(checkBox);
398:
399: String currValue = getValue(key);
400: checkBox.setSelection(data.getSelection(currValue) == 0);
401:
402: fCheckBoxes.add(checkBox);
403:
404: return checkBox;
405: }
406:
407: protected Combo addComboBox(Composite parent, String label,
408: Key key, String[] values, String[] valueLabels, int indent) {
409: GridData gd = new GridData(GridData.FILL, GridData.CENTER,
410: true, false, 2, 1);
411: gd.horizontalIndent = indent;
412:
413: Label labelControl = new Label(parent, SWT.LEFT);
414: labelControl.setFont(JFaceResources.getDialogFont());
415: labelControl.setText(label);
416: labelControl.setLayoutData(gd);
417:
418: Combo comboBox = newComboControl(parent, key, values,
419: valueLabels);
420: comboBox.setLayoutData(new GridData(
421: GridData.HORIZONTAL_ALIGN_FILL));
422:
423: fLabels.put(comboBox, labelControl);
424:
425: return comboBox;
426: }
427:
428: protected Combo addInversedComboBox(Composite parent, String label,
429: Key key, String[] values, String[] valueLabels, int indent) {
430: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
431: gd.horizontalIndent = indent;
432: gd.horizontalSpan = 3;
433:
434: Composite composite = new Composite(parent, SWT.NONE);
435: GridLayout layout = new GridLayout();
436: layout.marginHeight = 0;
437: layout.marginWidth = 0;
438: layout.numColumns = 2;
439: composite.setLayout(layout);
440: composite.setLayoutData(gd);
441:
442: Combo comboBox = newComboControl(composite, key, values,
443: valueLabels);
444: comboBox.setFont(JFaceResources.getDialogFont());
445: comboBox.setLayoutData(new GridData(
446: GridData.HORIZONTAL_ALIGN_FILL));
447:
448: Label labelControl = new Label(composite, SWT.LEFT | SWT.WRAP);
449: labelControl.setText(label);
450: labelControl.setLayoutData(new GridData());
451:
452: fLabels.put(comboBox, labelControl);
453: return comboBox;
454: }
455:
456: protected Combo newComboControl(Composite composite, Key key,
457: String[] values, String[] valueLabels) {
458: ControlData data = new ControlData(key, values);
459:
460: Combo comboBox = new Combo(composite, SWT.READ_ONLY);
461: comboBox.setItems(valueLabels);
462: comboBox.setData(data);
463: comboBox.addSelectionListener(getSelectionListener());
464: comboBox.setFont(JFaceResources.getDialogFont());
465:
466: makeScrollableCompositeAware(comboBox);
467:
468: String currValue = getValue(key);
469: comboBox.select(data.getSelection(currValue));
470:
471: fComboBoxes.add(comboBox);
472: return comboBox;
473: }
474:
475: protected Text addTextField(Composite parent, String label,
476: Key key, int indent, int widthHint) {
477: Label labelControl = new Label(parent, SWT.WRAP);
478: labelControl.setText(label);
479: labelControl.setFont(JFaceResources.getDialogFont());
480: labelControl.setLayoutData(new GridData());
481:
482: Text textBox = new Text(parent, SWT.BORDER | SWT.SINGLE);
483: textBox.setData(key);
484: textBox.setLayoutData(new GridData());
485:
486: makeScrollableCompositeAware(textBox);
487:
488: fLabels.put(textBox, labelControl);
489:
490: String currValue = getValue(key);
491: if (currValue != null) {
492: textBox.setText(currValue);
493: }
494: textBox.addModifyListener(getTextModifyListener());
495:
496: GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
497: if (widthHint != 0) {
498: data.widthHint = widthHint;
499: }
500: data.horizontalIndent = indent;
501: data.horizontalSpan = 2;
502: textBox.setLayoutData(data);
503:
504: fTextBoxes.add(textBox);
505: return textBox;
506: }
507:
508: protected ScrolledPageContent getParentScrolledComposite(
509: Control control) {
510: Control parent = control.getParent();
511: while (!(parent instanceof ScrolledPageContent)
512: && parent != null) {
513: parent = parent.getParent();
514: }
515: if (parent instanceof ScrolledPageContent) {
516: return (ScrolledPageContent) parent;
517: }
518: return null;
519: }
520:
521: protected ExpandableComposite getParentExpandableComposite(
522: Control control) {
523: Control parent = control.getParent();
524: while (!(parent instanceof ExpandableComposite)
525: && parent != null) {
526: parent = parent.getParent();
527: }
528: if (parent instanceof ExpandableComposite) {
529: return (ExpandableComposite) parent;
530: }
531: return null;
532: }
533:
534: private void makeScrollableCompositeAware(Control control) {
535: ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(control);
536: if (parentScrolledComposite != null) {
537: parentScrolledComposite.adaptChild(control);
538: }
539: }
540:
541: protected ExpandableComposite createStyleSection(Composite parent,
542: String label, int nColumns) {
543: ExpandableComposite excomposite = new ExpandableComposite(
544: parent, SWT.NONE, ExpandableComposite.TWISTIE
545: | ExpandableComposite.CLIENT_INDENT);
546: excomposite.setText(label);
547: excomposite.setExpanded(false);
548: excomposite.setFont(JFaceResources.getFontRegistry().getBold(
549: JFaceResources.DIALOG_FONT));
550: excomposite.setLayoutData(new GridData(GridData.FILL,
551: GridData.FILL, true, false, nColumns, 1));
552: excomposite.addExpansionListener(new ExpansionAdapter() {
553: public void expansionStateChanged(ExpansionEvent e) {
554: expandedStateChanged((ExpandableComposite) e
555: .getSource());
556: }
557: });
558: fExpandedComposites.add(excomposite);
559: makeScrollableCompositeAware(excomposite);
560: return excomposite;
561: }
562:
563: protected final void expandedStateChanged(
564: ExpandableComposite expandable) {
565: ScrolledPageContent parentScrolledComposite = getParentScrolledComposite(expandable);
566: if (parentScrolledComposite != null) {
567: parentScrolledComposite.reflow(true);
568: }
569: }
570:
571: protected void restoreSectionExpansionStates(
572: IDialogSettings settings) {
573: for (int i = 0; i < fExpandedComposites.size(); i++) {
574: ExpandableComposite excomposite = (ExpandableComposite) fExpandedComposites
575: .get(i);
576: if (settings == null) {
577: excomposite.setExpanded(i == 0); // only expand the first node by default
578: } else {
579: excomposite.setExpanded(settings
580: .getBoolean(SETTINGS_EXPANDED
581: + String.valueOf(i)));
582: }
583: }
584: }
585:
586: protected void storeSectionExpansionStates(IDialogSettings settings) {
587: for (int i = 0; i < fExpandedComposites.size(); i++) {
588: ExpandableComposite curr = (ExpandableComposite) fExpandedComposites
589: .get(i);
590: settings.put(SETTINGS_EXPANDED + String.valueOf(i), curr
591: .isExpanded());
592: }
593: }
594:
595: protected SelectionListener getSelectionListener() {
596: if (fSelectionListener == null) {
597: fSelectionListener = new SelectionListener() {
598: public void widgetDefaultSelected(SelectionEvent e) {
599: }
600:
601: public void widgetSelected(SelectionEvent e) {
602: controlChanged(e.widget);
603: }
604: };
605: }
606: return fSelectionListener;
607: }
608:
609: protected ModifyListener getTextModifyListener() {
610: if (fTextModifyListener == null) {
611: fTextModifyListener = new ModifyListener() {
612: public void modifyText(ModifyEvent e) {
613: textChanged((Text) e.widget);
614: }
615: };
616: }
617: return fTextModifyListener;
618: }
619:
620: protected void controlChanged(Widget widget) {
621: ControlData data = (ControlData) widget.getData();
622: String newValue = null;
623: if (widget instanceof Button) {
624: newValue = data.getValue(((Button) widget).getSelection());
625: } else if (widget instanceof Combo) {
626: newValue = data.getValue(((Combo) widget)
627: .getSelectionIndex());
628: } else {
629: return;
630: }
631: String oldValue = setValue(data.getKey(), newValue);
632: validateSettings(data.getKey(), oldValue, newValue);
633: }
634:
635: protected void textChanged(Text textControl) {
636: Key key = (Key) textControl.getData();
637: String number = textControl.getText();
638: String oldValue = setValue(key, number);
639: validateSettings(key, oldValue, number);
640: }
641:
642: protected boolean checkValue(Key key, String value) {
643: return value.equals(getValue(key));
644: }
645:
646: protected String getValue(Key key) {
647: if (fDisabledProjectSettings != null) {
648: return (String) fDisabledProjectSettings.get(key);
649: }
650: return key.getStoredValue(fLookupOrder, false, fManager);
651: }
652:
653: protected boolean getBooleanValue(Key key) {
654: return Boolean.valueOf(getValue(key)).booleanValue();
655: }
656:
657: protected String setValue(Key key, String value) {
658: if (fDisabledProjectSettings != null) {
659: return (String) fDisabledProjectSettings.put(key, value);
660: }
661: String oldValue = getValue(key);
662: key.setStoredValue(fLookupOrder[0], value, fManager);
663: return oldValue;
664: }
665:
666: protected String setValue(Key key, boolean value) {
667: return setValue(key, String.valueOf(value));
668: }
669:
670: /**
671: * Returns the value as actually stored in the preference store.
672: * @param key
673: * @return the value as actually stored in the preference store.
674: */
675: protected String getStoredValue(Key key) {
676: return key.getStoredValue(fLookupOrder, false, fManager);
677: }
678:
679: /* (non-javadoc)
680: * Update fields and validate.
681: * @param changedKey Key that changed, or null, if all changed.
682: */
683: protected abstract void validateSettings(Key changedKey,
684: String oldValue, String newValue);
685:
686: protected String[] getTokens(String text, String separator) {
687: StringTokenizer tok = new StringTokenizer(text, separator);
688: int nTokens = tok.countTokens();
689: String[] res = new String[nTokens];
690: for (int i = 0; i < res.length; i++) {
691: res[i] = tok.nextToken().trim();
692: }
693: return res;
694: }
695:
696: private boolean getChanges(IScopeContext currContext,
697: List changedSettings) {
698: boolean completeSettings = fProject != null
699: && fDisabledProjectSettings == null; // complete when project settings are enabled
700: boolean needsBuild = false;
701: for (int i = 0; i < fAllKeys.length; i++) {
702: Key key = fAllKeys[i];
703: String oldVal = key.getStoredValue(currContext, null);
704: String val = key.getStoredValue(currContext, fManager);
705: if (val == null) {
706: if (oldVal != null) {
707: changedSettings.add(key);
708: needsBuild |= !oldVal.equals(key.getStoredValue(
709: fLookupOrder, true, fManager));
710: } else if (completeSettings) {
711: key.setStoredValue(currContext, key.getStoredValue(
712: fLookupOrder, true, fManager), fManager);
713: changedSettings.add(key);
714: // no build needed
715: }
716: } else if (!val.equals(oldVal)) {
717: changedSettings.add(key);
718: needsBuild |= oldVal != null
719: || !val.equals(key.getStoredValue(fLookupOrder,
720: true, fManager));
721: }
722: }
723: return needsBuild;
724: }
725:
726: public void useProjectSpecificSettings(boolean enable) {
727: boolean hasProjectSpecificOption = fDisabledProjectSettings == null;
728: if (enable != hasProjectSpecificOption && fProject != null) {
729: if (enable) {
730: for (int i = 0; i < fAllKeys.length; i++) {
731: Key curr = fAllKeys[i];
732: String val = (String) fDisabledProjectSettings
733: .get(curr);
734: curr.setStoredValue(fLookupOrder[0], val, fManager);
735: }
736: fDisabledProjectSettings = null;
737: updateControls();
738: validateSettings(null, null, null);
739: } else {
740: fDisabledProjectSettings = new IdentityHashMap();
741: for (int i = 0; i < fAllKeys.length; i++) {
742: Key curr = fAllKeys[i];
743: String oldSetting = curr.getStoredValue(
744: fLookupOrder, false, fManager);
745: fDisabledProjectSettings.put(curr, oldSetting);
746: curr
747: .setStoredValue(fLookupOrder[0], null,
748: fManager); // clear project settings
749: }
750: }
751: }
752: }
753:
754: public boolean areSettingsEnabled() {
755: return fDisabledProjectSettings == null || fProject == null;
756: }
757:
758: public boolean performOk() {
759: return processChanges(fContainer);
760: }
761:
762: public boolean performApply() {
763: return processChanges(null); // apply directly
764: }
765:
766: protected boolean processChanges(
767: IWorkbenchPreferenceContainer container) {
768: IScopeContext currContext = fLookupOrder[0];
769:
770: List /* <Key>*/changedOptions = new ArrayList();
771: boolean needsBuild = getChanges(currContext, changedOptions);
772: if (changedOptions.isEmpty()) {
773: return true;
774: }
775: if (needsBuild) {
776: int count = getRebuildCount();
777: if (count > fRebuildCount) {
778: needsBuild = false; // build already requested
779: fRebuildCount = count;
780: }
781: }
782:
783: boolean doBuild = false;
784: if (needsBuild) {
785: String[] strings = getFullBuildDialogStrings(fProject == null);
786: if (strings != null) {
787: MessageDialog dialog = new MessageDialog(getShell(),
788: strings[0], null, strings[1],
789: MessageDialog.QUESTION, new String[] {
790: IDialogConstants.YES_LABEL,
791: IDialogConstants.NO_LABEL,
792: IDialogConstants.CANCEL_LABEL }, 2);
793: int res = dialog.open();
794: if (res == 0) {
795: doBuild = true;
796: } else if (res != 1) {
797: return false; // cancel pressed
798: }
799: }
800: }
801: if (container != null) {
802: // no need to apply the changes to the original store: will be done by the page container
803: if (doBuild) { // post build
804: incrementRebuildCount();
805: container.registerUpdateJob(CoreUtility
806: .getBuildJob(fProject));
807: }
808: } else {
809: // apply changes right away
810: try {
811: fManager.applyChanges();
812: } catch (BackingStoreException e) {
813: JavaPlugin.log(e);
814: return false;
815: }
816: if (doBuild) {
817: CoreUtility.getBuildJob(fProject).schedule();
818: }
819:
820: }
821: return true;
822: }
823:
824: protected abstract String[] getFullBuildDialogStrings(
825: boolean workspaceSettings);
826:
827: public void performDefaults() {
828: for (int i = 0; i < fAllKeys.length; i++) {
829: Key curr = fAllKeys[i];
830: String defValue = curr.getStoredValue(fLookupOrder, true,
831: fManager);
832: setValue(curr, defValue);
833: }
834:
835: settingsUpdated();
836: updateControls();
837: validateSettings(null, null, null);
838: }
839:
840: /**
841: * @since 3.1
842: */
843: public void performRevert() {
844: for (int i = 0; i < fAllKeys.length; i++) {
845: Key curr = fAllKeys[i];
846: String origValue = curr.getStoredValue(fLookupOrder, false,
847: null);
848: setValue(curr, origValue);
849: }
850:
851: settingsUpdated();
852: updateControls();
853: validateSettings(null, null, null);
854: }
855:
856: public void dispose() {
857: }
858:
859: protected void updateControls() {
860: // update the UI
861: for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
862: updateCheckBox((Button) fCheckBoxes.get(i));
863: }
864: for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
865: updateCombo((Combo) fComboBoxes.get(i));
866: }
867: for (int i = fTextBoxes.size() - 1; i >= 0; i--) {
868: updateText((Text) fTextBoxes.get(i));
869: }
870: }
871:
872: protected void updateCombo(Combo curr) {
873: ControlData data = (ControlData) curr.getData();
874:
875: String currValue = getValue(data.getKey());
876: curr.select(data.getSelection(currValue));
877: }
878:
879: protected void updateCheckBox(Button curr) {
880: ControlData data = (ControlData) curr.getData();
881:
882: String currValue = getValue(data.getKey());
883: curr.setSelection(data.getSelection(currValue) == 0);
884: }
885:
886: protected void updateText(Text curr) {
887: Key key = (Key) curr.getData();
888:
889: String currValue = getValue(key);
890: if (currValue != null) {
891: curr.setText(currValue);
892: }
893: }
894:
895: protected Button getCheckBox(Key key) {
896: for (int i = fCheckBoxes.size() - 1; i >= 0; i--) {
897: Button curr = (Button) fCheckBoxes.get(i);
898: ControlData data = (ControlData) curr.getData();
899: if (key.equals(data.getKey())) {
900: return curr;
901: }
902: }
903: return null;
904: }
905:
906: protected Combo getComboBox(Key key) {
907: for (int i = fComboBoxes.size() - 1; i >= 0; i--) {
908: Combo curr = (Combo) fComboBoxes.get(i);
909: ControlData data = (ControlData) curr.getData();
910: if (key.equals(data.getKey())) {
911: return curr;
912: }
913: }
914: return null;
915: }
916:
917: protected Text getTextControl(Key key) {
918: for (int i = fTextBoxes.size() - 1; i >= 0; i--) {
919: Text curr = (Text) fTextBoxes.get(i);
920: ControlData data = (ControlData) curr.getData();
921: if (key.equals(data.getKey())) {
922: return curr;
923: }
924: }
925: return null;
926: }
927:
928: protected Control findControl(Key key) {
929: Combo comboBox = getComboBox(key);
930: if (comboBox != null) {
931: return comboBox;
932: }
933: Button checkBox = getCheckBox(key);
934: if (checkBox != null) {
935: return checkBox;
936: }
937: Text text = getTextControl(key);
938: if (text != null) {
939: return text;
940: }
941: return null;
942: }
943:
944: protected void setComboEnabled(Key key, boolean enabled) {
945: Combo combo = getComboBox(key);
946: Label label = (Label) fLabels.get(combo);
947: combo.setEnabled(enabled);
948: label.setEnabled(enabled);
949: }
950: }
|