KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > preferences > AbstractConfigurationBlock


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.internal.ui.preferences;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.core.runtime.IStatus;
23
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.events.ModifyEvent;
26 import org.eclipse.swt.events.ModifyListener;
27 import org.eclipse.swt.events.SelectionEvent;
28 import org.eclipse.swt.events.SelectionListener;
29 import org.eclipse.swt.layout.GridData;
30 import org.eclipse.swt.layout.GridLayout;
31 import org.eclipse.swt.widgets.Button;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.swt.widgets.Control;
34 import org.eclipse.swt.widgets.Group;
35 import org.eclipse.swt.widgets.Label;
36 import org.eclipse.swt.widgets.Text;
37
38 import org.eclipse.jface.preference.IPreferenceStore;
39 import org.eclipse.jface.preference.PreferencePage;
40 import org.eclipse.jface.resource.JFaceResources;
41
42
43 import org.eclipse.ui.forms.events.ExpansionAdapter;
44 import org.eclipse.ui.forms.events.ExpansionEvent;
45 import org.eclipse.ui.forms.widgets.ExpandableComposite;
46
47 import org.eclipse.jdt.internal.corext.util.Messages;
48
49 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
50 import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
51 import org.eclipse.jdt.internal.ui.util.PixelConverter;
52
53 /**
54  * Configures Java Editor typing preferences.
55  *
56  * @since 3.1
57  */

58 abstract class AbstractConfigurationBlock implements IPreferenceConfigurationBlock {
59
60     /**
61      * Use as follows:
62      *
63      * <pre>
64      * SectionManager manager= new SectionManager();
65      * Composite composite= manager.createSectionComposite(parent);
66      *
67      * Composite xSection= manager.createSection("section X"));
68      * xSection.setLayout(new FillLayout());
69      * new Button(xSection, SWT.PUSH); // add controls to section..
70      *
71      * [...]
72      *
73      * return composite; // return main composite
74      * </pre>
75      */

76     protected final class SectionManager {
77         /** The preference setting for keeping no section open. */
78         private static final String JavaDoc __NONE= "__none"; //$NON-NLS-1$
79
private Set JavaDoc fSections= new HashSet JavaDoc();
80         private boolean fIsBeingManaged= false;
81         private ExpansionAdapter fListener= new ExpansionAdapter() {
82             public void expansionStateChanged(ExpansionEvent e) {
83                 ExpandableComposite source= (ExpandableComposite) e.getSource();
84                 updateSectionStyle(source);
85                 if (fIsBeingManaged)
86                     return;
87                 if (e.getState()) {
88                     try {
89                         fIsBeingManaged= true;
90                         for (Iterator JavaDoc iter= fSections.iterator(); iter.hasNext();) {
91                             ExpandableComposite composite= (ExpandableComposite) iter.next();
92                             if (composite != source)
93                                 composite.setExpanded(false);
94                         }
95                     } finally {
96                         fIsBeingManaged= false;
97                     }
98                     if (fLastOpenKey != null && fDialogSettingsStore != null)
99                         fDialogSettingsStore.setValue(fLastOpenKey, source.getText());
100                 } else {
101                     if (!fIsBeingManaged && fLastOpenKey != null && fDialogSettingsStore != null)
102                         fDialogSettingsStore.setValue(fLastOpenKey, __NONE);
103                 }
104                 ExpandableComposite exComp= getParentExpandableComposite(source);
105                 if (exComp != null)
106                     exComp.layout(true, true);
107                 ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(source);
108                 if (parentScrolledComposite != null) {
109                     parentScrolledComposite.reflow(true);
110                 }
111             }
112         };
113         private Composite fBody;
114         private final String JavaDoc fLastOpenKey;
115         private final IPreferenceStore fDialogSettingsStore;
116         private ExpandableComposite fFirstChild= null;
117         /**
118          * Creates a new section manager.
119          */

120         public SectionManager() {
121             this(null, null);
122         }
123         /**
124          * Creates a new section manager.
125          */

126         public SectionManager(IPreferenceStore dialogSettingsStore, String JavaDoc lastOpenKey) {
127             fDialogSettingsStore= dialogSettingsStore;
128             fLastOpenKey= lastOpenKey;
129         }
130         private void manage(ExpandableComposite section) {
131             if (section == null)
132                 throw new NullPointerException JavaDoc();
133             if (fSections.add(section))
134                 section.addExpansionListener(fListener);
135             makeScrollableCompositeAware(section);
136         }
137         
138         /**
139          * Creates a new composite that can contain a set of expandable
140          * sections. A <code>ScrolledPageComposite</code> is created and a new
141          * composite within that, to ensure that expanding the sections will
142          * always have enough space, unless there already is a
143          * <code>ScrolledComposite</code> along the parent chain of
144          * <code>parent</code>, in which case a normal <code>Composite</code>
145          * is created.
146          * <p>
147          * The receiver keeps a reference to the inner body composite, so that
148          * new sections can be added via <code>createSection</code>.
149          * </p>
150          *
151          * @param parent the parent composite
152          * @return the newly created composite
153          */

154         public Composite createSectionComposite(Composite parent) {
155             Assert.isTrue(fBody == null);
156             boolean isNested= isNestedInScrolledComposite(parent);
157             Composite composite;
158             if (isNested) {
159                 composite= new Composite(parent, SWT.NONE);
160                 fBody= composite;
161             } else {
162                 composite= new ScrolledPageContent(parent);
163                 fBody= ((ScrolledPageContent) composite).getBody();
164             }
165             
166             fBody.setLayout(new GridLayout());
167             
168             return composite;
169         }
170         
171         /**
172          * Creates an expandable section within the parent created previously by
173          * calling <code>createSectionComposite</code>. Controls can be added
174          * directly to the returned composite, which has no layout initially.
175          *
176          * @param label the display name of the section
177          * @return a composite within the expandable section
178          */

179         public Composite createSection(String JavaDoc label) {
180             Assert.isNotNull(fBody);
181             final ExpandableComposite excomposite= new ExpandableComposite(fBody, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT | ExpandableComposite.COMPACT);
182             if (fFirstChild == null)
183                 fFirstChild= excomposite;
184             excomposite.setText(label);
185             String JavaDoc last= null;
186             if (fLastOpenKey != null && fDialogSettingsStore != null)
187                 last= fDialogSettingsStore.getString(fLastOpenKey);
188             
189             if (fFirstChild == excomposite && !__NONE.equals(last) || label.equals(last)) {
190                 excomposite.setExpanded(true);
191                 if (fFirstChild != excomposite)
192                     fFirstChild.setExpanded(false);
193             } else {
194                 excomposite.setExpanded(false);
195             }
196             excomposite.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
197             
198             updateSectionStyle(excomposite);
199             manage(excomposite);
200             
201             Composite contents= new Composite(excomposite, SWT.NONE);
202             excomposite.setClient(contents);
203             
204             return contents;
205         }
206     }
207
208     protected static final int INDENT= 20;
209     private OverlayPreferenceStore fStore;
210     
211     private Map JavaDoc fCheckBoxes= new HashMap JavaDoc();
212     private SelectionListener fCheckBoxListener= new SelectionListener() {
213         public void widgetDefaultSelected(SelectionEvent e) {
214         }
215         public void widgetSelected(SelectionEvent e) {
216             Button button= (Button) e.widget;
217             fStore.setValue((String JavaDoc) fCheckBoxes.get(button), button.getSelection());
218         }
219     };
220     
221     
222     private Map JavaDoc fTextFields= new HashMap JavaDoc();
223     private ModifyListener fTextFieldListener= new ModifyListener() {
224         public void modifyText(ModifyEvent e) {
225             Text text= (Text) e.widget;
226             fStore.setValue((String JavaDoc) fTextFields.get(text), text.getText());
227         }
228     };
229
230     private ArrayList JavaDoc fNumberFields= new ArrayList JavaDoc();
231     private ModifyListener fNumberFieldListener= new ModifyListener() {
232         public void modifyText(ModifyEvent e) {
233             numberFieldChanged((Text) e.widget);
234         }
235     };
236     
237     /**
238      * List of master/slave listeners when there's a dependency.
239      *
240      * @see #createDependency(Button, Control)
241      * @since 3.0
242      */

243     private ArrayList JavaDoc fMasterSlaveListeners= new ArrayList JavaDoc();
244     
245     private StatusInfo fStatus;
246     private final PreferencePage fMainPage;
247
248     public AbstractConfigurationBlock(OverlayPreferenceStore store) {
249         Assert.isNotNull(store);
250         fStore= store;
251         fMainPage= null;
252     }
253     
254     public AbstractConfigurationBlock(OverlayPreferenceStore store, PreferencePage mainPreferencePage) {
255         Assert.isNotNull(store);
256         Assert.isNotNull(mainPreferencePage);
257         fStore= store;
258         fMainPage= mainPreferencePage;
259     }
260
261     protected final ScrolledPageContent getParentScrolledComposite(Control control) {
262         Control parent= control.getParent();
263         while (!(parent instanceof ScrolledPageContent) && parent != null) {
264             parent= parent.getParent();
265         }
266         if (parent instanceof ScrolledPageContent) {
267             return (ScrolledPageContent) parent;
268         }
269         return null;
270     }
271
272     private final ExpandableComposite getParentExpandableComposite(Control control) {
273         Control parent= control.getParent();
274         while (!(parent instanceof ExpandableComposite) && parent != null) {
275             parent= parent.getParent();
276         }
277         if (parent instanceof ExpandableComposite) {
278             return (ExpandableComposite) parent;
279         }
280         return null;
281     }
282
283     protected void updateSectionStyle(ExpandableComposite excomposite) {
284         excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
285     }
286     
287     private void makeScrollableCompositeAware(Control control) {
288         ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(control);
289         if (parentScrolledComposite != null) {
290             parentScrolledComposite.adaptChild(control);
291         }
292     }
293     
294     private boolean isNestedInScrolledComposite(Composite parent) {
295         return getParentScrolledComposite(parent) != null;
296     }
297     
298     protected Button addCheckBox(Composite parent, String JavaDoc label, String JavaDoc key, int indentation) {
299         Button checkBox= new Button(parent, SWT.CHECK);
300         checkBox.setText(label);
301         
302         GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
303         gd.horizontalIndent= indentation;
304         gd.horizontalSpan= 2;
305         checkBox.setLayoutData(gd);
306         checkBox.addSelectionListener(fCheckBoxListener);
307         makeScrollableCompositeAware(checkBox);
308
309         fCheckBoxes.put(checkBox, key);
310         
311         return checkBox;
312     }
313
314     /**
315      * Returns an array of size 2:
316      * - first element is of type <code>Label</code>
317      * - second element is of type <code>Text</code>
318      * Use <code>getLabelControl</code> and <code>getTextControl</code> to get the 2 controls.
319      *
320      * @param composite the parent composite
321      * @param label the text field's label
322      * @param key the preference key
323      * @param textLimit the text limit
324      * @param indentation the field's indentation
325      * @param isNumber <code>true</code> iff this text field is used to e4dit a number
326      * @return the controls added
327      */

328     protected Control[] addLabelledTextField(Composite composite, String JavaDoc label, String JavaDoc key, int textLimit, int indentation, boolean isNumber) {
329         
330         PixelConverter pixelConverter= new PixelConverter(composite);
331         
332         Label labelControl= new Label(composite, SWT.NONE);
333         labelControl.setText(label);
334         GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
335         gd.horizontalIndent= indentation;
336         labelControl.setLayoutData(gd);
337         
338         Text textControl= new Text(composite, SWT.BORDER | SWT.SINGLE);
339         gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
340         gd.widthHint= pixelConverter.convertWidthInCharsToPixels(textLimit + 1);
341         textControl.setLayoutData(gd);
342         textControl.setTextLimit(textLimit);
343         fTextFields.put(textControl, key);
344         if (isNumber) {
345             fNumberFields.add(textControl);
346             textControl.addModifyListener(fNumberFieldListener);
347         } else {
348             textControl.addModifyListener(fTextFieldListener);
349         }
350             
351         return new Control[]{labelControl, textControl};
352     }
353
354     protected void createDependency(final Button master, final Control slave) {
355         createDependency(master, new Control[] {slave});
356     }
357     
358     protected void createDependency(final Button master, final Control[] slaves) {
359         Assert.isTrue(slaves.length > 0);
360         indent(slaves[0]);
361         SelectionListener listener= new SelectionListener() {
362             public void widgetSelected(SelectionEvent e) {
363                 boolean state= master.getSelection();
364                 for (int i= 0; i < slaves.length; i++) {
365                     slaves[i].setEnabled(state);
366                 }
367             }
368
369             public void widgetDefaultSelected(SelectionEvent e) {}
370         };
371         master.addSelectionListener(listener);
372         fMasterSlaveListeners.add(listener);
373     }
374
375     protected static void indent(Control control) {
376         ((GridData) control.getLayoutData()).horizontalIndent+= INDENT;
377     }
378
379     public void initialize() {
380         initializeFields();
381     }
382
383     private void initializeFields() {
384         
385         Iterator JavaDoc iter= fCheckBoxes.keySet().iterator();
386         while (iter.hasNext()) {
387             Button b= (Button) iter.next();
388             String JavaDoc key= (String JavaDoc) fCheckBoxes.get(b);
389             b.setSelection(fStore.getBoolean(key));
390         }
391         
392         iter= fTextFields.keySet().iterator();
393         while (iter.hasNext()) {
394             Text t= (Text) iter.next();
395             String JavaDoc key= (String JavaDoc) fTextFields.get(t);
396             t.setText(fStore.getString(key));
397         }
398         
399         // Update slaves
400
iter= fMasterSlaveListeners.iterator();
401         while (iter.hasNext()) {
402             SelectionListener listener= (SelectionListener)iter.next();
403             listener.widgetSelected(null);
404         }
405      
406         updateStatus(new StatusInfo());
407     }
408
409     public void performOk() {
410     }
411
412     public void performDefaults() {
413         initializeFields();
414     }
415
416     IStatus getStatus() {
417         if (fStatus == null)
418             fStatus= new StatusInfo();
419         return fStatus;
420     }
421
422     /*
423      * @see org.eclipse.jdt.internal.ui.preferences.IPreferenceConfigurationBlock#dispose()
424      * @since 3.0
425      */

426     public void dispose() {
427     }
428     
429     private void numberFieldChanged(Text textControl) {
430         String JavaDoc number= textControl.getText();
431         IStatus status= validatePositiveNumber(number);
432         if (!status.matches(IStatus.ERROR))
433             fStore.setValue((String JavaDoc) fTextFields.get(textControl), number);
434         updateStatus(status);
435     }
436     
437     private IStatus validatePositiveNumber(String JavaDoc number) {
438         StatusInfo status= new StatusInfo();
439         if (number.length() == 0) {
440             status.setError(PreferencesMessages.JavaEditorPreferencePage_empty_input);
441         } else {
442             try {
443                 int value= Integer.parseInt(number);
444                 if (value < 0)
445                     status.setError(Messages.format(PreferencesMessages.JavaEditorPreferencePage_invalid_input, number));
446             } catch (NumberFormatException JavaDoc e) {
447                 status.setError(Messages.format(PreferencesMessages.JavaEditorPreferencePage_invalid_input, number));
448             }
449         }
450         return status;
451     }
452
453     protected void updateStatus(IStatus status) {
454         if (fMainPage == null)
455             return;
456         fMainPage.setValid(status.isOK());
457         StatusUtil.applyToStatusLine(fMainPage, status);
458     }
459     
460     protected final OverlayPreferenceStore getPreferenceStore() {
461         return fStore;
462     }
463
464     protected Composite createSubsection(Composite parent, SectionManager manager, String JavaDoc label) {
465         if (manager != null) {
466             return manager.createSection(label);
467         } else {
468             Group group= new Group(parent, SWT.SHADOW_NONE);
469             group.setText(label);
470             GridData data= new GridData(SWT.FILL, SWT.CENTER, true, false);
471             group.setLayoutData(data);
472             return group;
473         }
474     }
475 }
476
Popular Tags