~ubuntu-branches/debian/sid/eclipse-cdt/sid

« back to all changes in this revision

Viewing changes to core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/AbstractConfigurationBlock.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2011-10-06 21:15:04 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111006211504-8dutmljjih0zikfv
Tags: 8.0.1-1
* New upstream release.
* Split the JNI packages into a separate architecture dependent
  package and made eclipse-cdt architecture independent.
* Install JNI libraries into multiarch aware location
* Bumped Standards-Version to 3.9.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2000, 2010 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
 *     Sergey Prigogin, Google
 
11
 *     Anton Leherbauer (Wind River Systems)
 
12
 *******************************************************************************/
 
13
 
 
14
package org.eclipse.cdt.internal.ui.preferences;
 
15
 
 
16
import java.util.ArrayList;
 
17
import java.util.HashMap;
 
18
import java.util.HashSet;
 
19
import java.util.Iterator;
 
20
import java.util.Map;
 
21
import java.util.Set;
 
22
 
 
23
import org.eclipse.core.runtime.Assert;
 
24
import org.eclipse.core.runtime.IStatus;
 
25
import org.eclipse.jface.layout.PixelConverter;
 
26
import org.eclipse.jface.preference.IPreferenceStore;
 
27
import org.eclipse.jface.preference.PreferencePage;
 
28
import org.eclipse.jface.resource.JFaceResources;
 
29
import org.eclipse.osgi.util.NLS;
 
30
import org.eclipse.swt.SWT;
 
31
import org.eclipse.swt.events.ModifyEvent;
 
32
import org.eclipse.swt.events.ModifyListener;
 
33
import org.eclipse.swt.events.SelectionEvent;
 
34
import org.eclipse.swt.events.SelectionListener;
 
35
import org.eclipse.swt.layout.GridData;
 
36
import org.eclipse.swt.layout.GridLayout;
 
37
import org.eclipse.swt.widgets.Button;
 
38
import org.eclipse.swt.widgets.Composite;
 
39
import org.eclipse.swt.widgets.Control;
 
40
import org.eclipse.swt.widgets.Group;
 
41
import org.eclipse.swt.widgets.Label;
 
42
import org.eclipse.swt.widgets.Text;
 
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.cdt.internal.ui.dialogs.StatusInfo;
 
48
import org.eclipse.cdt.internal.ui.dialogs.StatusUtil;
 
49
 
 
50
/**
 
51
 * Abstract implementation of a generic {@link IPreferenceConfigurationBlock}.
 
52
 * 
 
53
 * @since 4.0
 
54
 */
 
55
abstract class AbstractConfigurationBlock implements IPreferenceConfigurationBlock {
 
56
 
 
57
        /**
 
58
         * Use as follows:
 
59
         * 
 
60
         * <pre>
 
61
         * SectionManager manager= new SectionManager();
 
62
         * Composite composite= manager.createSectionComposite(parent);
 
63
         * 
 
64
         * Composite xSection= manager.createSection("section X"));
 
65
         * xSection.setLayout(new FillLayout());
 
66
         * new Button(xSection, SWT.PUSH); // add controls to section..
 
67
         * 
 
68
         * [...]
 
69
         * 
 
70
         * return composite; // return main composite
 
71
         * </pre>
 
72
         */
 
73
        protected final class SectionManager {
 
74
                /** The preference setting for keeping no section open. */
 
75
                private static final String __NONE= "__none"; //$NON-NLS-1$
 
76
                private Set<ExpandableComposite> fSections= new HashSet<ExpandableComposite>();
 
77
                private boolean fIsBeingManaged= false;
 
78
                private ExpansionAdapter fListener= new ExpansionAdapter() {
 
79
                        @Override
 
80
                        public void expansionStateChanged(ExpansionEvent e) {
 
81
                                ExpandableComposite source= (ExpandableComposite) e.getSource();
 
82
                                updateSectionStyle(source);
 
83
                                if (fIsBeingManaged)
 
84
                                        return;
 
85
                                if (e.getState()) {
 
86
                                        try {
 
87
                                                fIsBeingManaged= true;
 
88
                                                for (ExpandableComposite composite : fSections) {
 
89
                                                        if (composite != source)
 
90
                                                                composite.setExpanded(false);
 
91
                                                }
 
92
                                        } finally {
 
93
                                                fIsBeingManaged= false;
 
94
                                        }
 
95
                                        if (fLastOpenKey != null && fDialogSettingsStore != null)
 
96
                                                fDialogSettingsStore.setValue(fLastOpenKey, source.getText());
 
97
                                } else {
 
98
                                        if (!fIsBeingManaged && fLastOpenKey != null && fDialogSettingsStore != null)
 
99
                                                fDialogSettingsStore.setValue(fLastOpenKey, __NONE);
 
100
                                }
 
101
                                ExpandableComposite exComp= getParentExpandableComposite(source);
 
102
                                if (exComp != null)
 
103
                                        exComp.layout(true, true);
 
104
                                ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(source);
 
105
                                if (parentScrolledComposite != null) {
 
106
                                        parentScrolledComposite.reflow(true);
 
107
                                }
 
108
                        }
 
109
                };
 
110
                private Composite fBody;
 
111
                private final String fLastOpenKey;
 
112
                private final IPreferenceStore fDialogSettingsStore;
 
113
                private ExpandableComposite fFirstChild= null;
 
114
                /**
 
115
                 * Creates a new section manager.
 
116
                 */
 
117
                public SectionManager() {
 
118
                        this(null, null);
 
119
                }
 
120
                /**
 
121
                 * Creates a new section manager.
 
122
                 */
 
123
                public SectionManager(IPreferenceStore dialogSettingsStore, String lastOpenKey) {
 
124
                        fDialogSettingsStore= dialogSettingsStore;
 
125
                        fLastOpenKey= lastOpenKey;
 
126
                }
 
127
                private void manage(ExpandableComposite section) {
 
128
                        if (section == null)
 
129
                                throw new NullPointerException();
 
130
                        if (fSections.add(section))
 
131
                                section.addExpansionListener(fListener);
 
132
                        makeScrollableCompositeAware(section);
 
133
                }
 
134
                
 
135
                /**
 
136
                 * Creates a new composite that can contain a set of expandable
 
137
                 * sections. A <code>ScrolledPageComposite</code> is created and a new
 
138
                 * composite within that, to ensure that expanding the sections will
 
139
                 * always have enough space, unless there already is a
 
140
                 * <code>ScrolledComposite</code> along the parent chain of
 
141
                 * <code>parent</code>, in which case a normal <code>Composite</code>
 
142
                 * is created.
 
143
                 * <p>
 
144
                 * The receiver keeps a reference to the inner body composite, so that
 
145
                 * new sections can be added via <code>createSection</code>.
 
146
                 * </p>
 
147
                 * 
 
148
                 * @param parent the parent composite
 
149
                 * @return the newly created composite
 
150
                 */
 
151
                public Composite createSectionComposite(Composite parent) {
 
152
                        Assert.isTrue(fBody == null);
 
153
                        boolean isNested= isNestedInScrolledComposite(parent);
 
154
                        Composite composite;
 
155
                        if (isNested) {
 
156
                                composite= new Composite(parent, SWT.NONE);
 
157
                                fBody= composite;
 
158
                        } else {
 
159
                                composite= new ScrolledPageContent(parent);
 
160
                                fBody= ((ScrolledPageContent) composite).getBody();
 
161
                        }
 
162
                        
 
163
                        fBody.setLayout(new GridLayout());
 
164
                        
 
165
                        return composite;
 
166
                }
 
167
                
 
168
                /**
 
169
                 * Creates an expandable section within the parent created previously by
 
170
                 * calling <code>createSectionComposite</code>. Controls can be added 
 
171
                 * directly to the returned composite, which has no layout initially.
 
172
                 * 
 
173
                 * @param label the display name of the section
 
174
                 * @return a composite within the expandable section
 
175
                 */
 
176
                public Composite createSection(String label) {
 
177
                        Assert.isNotNull(fBody);
 
178
                        final ExpandableComposite excomposite= new ExpandableComposite(fBody, SWT.NONE, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT | ExpandableComposite.COMPACT);
 
179
                        if (fFirstChild == null)
 
180
                                fFirstChild= excomposite;
 
181
                        excomposite.setText(label);
 
182
                        String last= null;
 
183
                        if (fLastOpenKey != null && fDialogSettingsStore != null)
 
184
                                last= fDialogSettingsStore.getString(fLastOpenKey);
 
185
                        
 
186
                        if (fFirstChild == excomposite && !__NONE.equals(last) || label.equals(last)) {
 
187
                                excomposite.setExpanded(true);
 
188
                                if (fFirstChild != excomposite)
 
189
                                        fFirstChild.setExpanded(false);
 
190
                        } else {
 
191
                                excomposite.setExpanded(false);
 
192
                        }
 
193
                        excomposite.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
 
194
                        
 
195
                        updateSectionStyle(excomposite);
 
196
                        manage(excomposite);
 
197
                        
 
198
                        Composite contents= new Composite(excomposite, SWT.NONE);
 
199
                        excomposite.setClient(contents);
 
200
                        
 
201
                        return contents;
 
202
                }
 
203
        }
 
204
 
 
205
        protected static final int INDENT= 20;
 
206
        private OverlayPreferenceStore fStore;
 
207
        
 
208
        private Map<Object, String> fCheckBoxes= new HashMap<Object, String>();
 
209
        private SelectionListener fCheckBoxListener= new SelectionListener() {
 
210
                public void widgetDefaultSelected(SelectionEvent e) {
 
211
                }
 
212
                public void widgetSelected(SelectionEvent e) {
 
213
                        Button button= (Button) e.widget;
 
214
                        fStore.setValue(fCheckBoxes.get(button), button.getSelection());
 
215
                }
 
216
        };
 
217
        
 
218
        
 
219
        private Map<Object, String> fTextFields= new HashMap<Object, String>();
 
220
        private ModifyListener fTextFieldListener= new ModifyListener() {
 
221
                public void modifyText(ModifyEvent e) {
 
222
                        Text text= (Text) e.widget;
 
223
                        fStore.setValue(fTextFields.get(text), text.getText());
 
224
                }
 
225
        };
 
226
 
 
227
        private ArrayList<Text> fNumberFields= new ArrayList<Text>();
 
228
        private ModifyListener fNumberFieldListener= new ModifyListener() {
 
229
                public void modifyText(ModifyEvent e) {
 
230
                        numberFieldChanged((Text) e.widget);
 
231
                }
 
232
        };
 
233
        
 
234
        /**
 
235
         * List of master/slave listeners when there's a dependency.
 
236
         * 
 
237
         * @see #createDependency(Button, Control)
 
238
         * @since 3.0
 
239
         */
 
240
        private ArrayList<Object> fMasterSlaveListeners= new ArrayList<Object>();
 
241
        
 
242
        private StatusInfo fStatus;
 
243
        private final PreferencePage fMainPage;
 
244
 
 
245
        public AbstractConfigurationBlock(OverlayPreferenceStore store) {
 
246
                Assert.isNotNull(store);
 
247
                fStore= store;
 
248
                fMainPage= null;
 
249
        }
 
250
        
 
251
        public AbstractConfigurationBlock(OverlayPreferenceStore store, PreferencePage mainPreferencePage) {
 
252
                Assert.isNotNull(store);
 
253
                Assert.isNotNull(mainPreferencePage);
 
254
                fStore= store;
 
255
                fMainPage= mainPreferencePage;
 
256
        }
 
257
 
 
258
        protected final ScrolledPageContent getParentScrolledComposite(Control control) {
 
259
                Control parent= control.getParent();
 
260
                while (!(parent instanceof ScrolledPageContent) && parent != null) {
 
261
                        parent= parent.getParent();
 
262
                }
 
263
                if (parent instanceof ScrolledPageContent) {
 
264
                        return (ScrolledPageContent) parent;
 
265
                }
 
266
                return null;
 
267
        }
 
268
 
 
269
        private final ExpandableComposite getParentExpandableComposite(Control control) {
 
270
                Control parent= control.getParent();
 
271
                while (!(parent instanceof ExpandableComposite) && parent != null) {
 
272
                        parent= parent.getParent();
 
273
                }
 
274
                if (parent instanceof ExpandableComposite) {
 
275
                        return (ExpandableComposite) parent;
 
276
                }
 
277
                return null;
 
278
        }
 
279
 
 
280
        protected void updateSectionStyle(ExpandableComposite excomposite) {
 
281
                excomposite.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT));
 
282
        }
 
283
        
 
284
        private void makeScrollableCompositeAware(Control control) {
 
285
                ScrolledPageContent parentScrolledComposite= getParentScrolledComposite(control);
 
286
                if (parentScrolledComposite != null) {
 
287
                        parentScrolledComposite.adaptChild(control);
 
288
                }
 
289
        }
 
290
        
 
291
        private boolean isNestedInScrolledComposite(Composite parent) {
 
292
                return getParentScrolledComposite(parent) != null;
 
293
        }
 
294
        
 
295
        protected Button addCheckBox(Composite parent, String label, String key, int indentation) {             
 
296
                Button checkBox= new Button(parent, SWT.CHECK);
 
297
                checkBox.setText(label);
 
298
                
 
299
                GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
 
300
                gd.horizontalIndent= indentation;
 
301
                gd.horizontalSpan= 2;
 
302
                checkBox.setLayoutData(gd);
 
303
                checkBox.addSelectionListener(fCheckBoxListener);
 
304
                makeScrollableCompositeAware(checkBox);
 
305
 
 
306
                fCheckBoxes.put(checkBox, key);
 
307
                
 
308
                return checkBox;
 
309
        }
 
310
 
 
311
        /**
 
312
         * Returns an array of size 2:
 
313
         *  - first element is of type <code>Label</code>
 
314
         *  - second element is of type <code>Text</code>
 
315
         * Use <code>getLabelControl</code> and <code>getTextControl</code> to get the 2 controls.
 
316
         * 
 
317
         * @param composite     the parent composite
 
318
         * @param label                 the text field's label
 
319
         * @param key                   the preference key
 
320
         * @param textLimit             the text limit
 
321
         * @param indentation   the field's indentation
 
322
         * @param isNumber              <code>true</code> iff this text field is used to e4dit a number
 
323
         * @return the controls added
 
324
         */
 
325
        protected Control[] addLabelledTextField(Composite composite, String label, String key, int textLimit, int indentation, boolean isNumber) {
 
326
                
 
327
                PixelConverter pixelConverter= new PixelConverter(composite);
 
328
                
 
329
                Label labelControl= new Label(composite, SWT.NONE);
 
330
                labelControl.setText(label);
 
331
                GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
 
332
                gd.horizontalIndent= indentation;
 
333
                labelControl.setLayoutData(gd);
 
334
                
 
335
                Text textControl= new Text(composite, SWT.BORDER | SWT.SINGLE);         
 
336
                gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
 
337
                gd.widthHint= pixelConverter.convertWidthInCharsToPixels(textLimit + 1);
 
338
                textControl.setLayoutData(gd);
 
339
                textControl.setTextLimit(textLimit);
 
340
                fTextFields.put(textControl, key);
 
341
                if (isNumber) {
 
342
                        fNumberFields.add(textControl);
 
343
                        textControl.addModifyListener(fNumberFieldListener);
 
344
                } else {
 
345
                        textControl.addModifyListener(fTextFieldListener);
 
346
                }
 
347
                        
 
348
                return new Control[]{labelControl, textControl};
 
349
        }
 
350
 
 
351
        protected void createDependency(final Button master, final Control slave) {
 
352
                createDependency(master, new Control[] {slave});
 
353
        }
 
354
        
 
355
        protected void createDependency(final Button master, final Control[] slaves) {
 
356
                Assert.isTrue(slaves.length > 0);
 
357
                indent(slaves[0]);
 
358
                SelectionListener listener= new SelectionListener() {
 
359
                        public void widgetSelected(SelectionEvent e) {
 
360
                                boolean state= master.getSelection();
 
361
                                for (Control slave : slaves) {
 
362
                                        slave.setEnabled(state);
 
363
                                }
 
364
                        }
 
365
 
 
366
                        public void widgetDefaultSelected(SelectionEvent e) {}
 
367
                };
 
368
                master.addSelectionListener(listener);
 
369
                fMasterSlaveListeners.add(listener);
 
370
        }
 
371
 
 
372
        protected static void indent(Control control) {
 
373
                ((GridData) control.getLayoutData()).horizontalIndent+= INDENT;
 
374
        }
 
375
 
 
376
        public void initialize() {
 
377
                initializeFields();
 
378
        }
 
379
 
 
380
        private void initializeFields() {
 
381
                
 
382
                Iterator<Object> iter= fCheckBoxes.keySet().iterator();
 
383
                while (iter.hasNext()) {
 
384
                        Button b= (Button) iter.next();
 
385
                        String key= fCheckBoxes.get(b);
 
386
                        b.setSelection(fStore.getBoolean(key));
 
387
                }
 
388
                
 
389
                iter= fTextFields.keySet().iterator();
 
390
                while (iter.hasNext()) {
 
391
                        Text t= (Text) iter.next();
 
392
                        String key= fTextFields.get(t);
 
393
                        t.setText(fStore.getString(key));
 
394
                }
 
395
                
 
396
        // Update slaves
 
397
        iter= fMasterSlaveListeners.iterator();
 
398
        while (iter.hasNext()) {
 
399
            SelectionListener listener= (SelectionListener)iter.next();
 
400
            listener.widgetSelected(null);
 
401
        }
 
402
     
 
403
        updateStatus(new StatusInfo());
 
404
        }
 
405
 
 
406
        public void performOk() {
 
407
        }
 
408
 
 
409
        public void performDefaults() {
 
410
                initializeFields();
 
411
        }
 
412
 
 
413
        IStatus getStatus() {
 
414
                if (fStatus == null)
 
415
                        fStatus= new StatusInfo();
 
416
                return fStatus;
 
417
        }
 
418
 
 
419
        /*
 
420
         * @see org.eclipse.cdt.internal.ui.preferences.IPreferenceConfigurationBlock#dispose()
 
421
         */
 
422
        public void dispose() {
 
423
        }
 
424
        
 
425
        private void numberFieldChanged(Text textControl) {
 
426
                String number= textControl.getText();
 
427
                IStatus status= validatePositiveNumber(number);
 
428
                if (!status.matches(IStatus.ERROR))
 
429
                        fStore.setValue(fTextFields.get(textControl), number);
 
430
                updateStatus(status);
 
431
        }
 
432
        
 
433
        private IStatus validatePositiveNumber(String number) {
 
434
                StatusInfo status= new StatusInfo();
 
435
                if (number.length() == 0) {
 
436
                        status.setError(PreferencesMessages.CEditorPreferencePage_empty_input); 
 
437
                } else {
 
438
                        try {
 
439
                                int value= Integer.parseInt(number);
 
440
                                if (value < 0)
 
441
                                        status.setError(NLS.bind(PreferencesMessages.CEditorPreferencePage_invalid_input, number)); 
 
442
                        } catch (NumberFormatException e) {
 
443
                                status.setError(NLS.bind(PreferencesMessages.CEditorPreferencePage_invalid_input, number)); 
 
444
                        }
 
445
                }
 
446
                return status;
 
447
        }
 
448
 
 
449
        protected void updateStatus(IStatus status) {
 
450
                if (fMainPage == null)
 
451
                        return;
 
452
                fMainPage.setValid(status.isOK());
 
453
                StatusUtil.applyToStatusLine(fMainPage, status);
 
454
        }
 
455
        
 
456
        protected final OverlayPreferenceStore getPreferenceStore() {
 
457
                return fStore;
 
458
        }
 
459
 
 
460
        protected Composite createSubsection(Composite parent, SectionManager manager, String label) {
 
461
                if (manager != null) {
 
462
                        return manager.createSection(label);
 
463
                }
 
464
                Group group= new Group(parent, SWT.SHADOW_NONE);
 
465
                group.setText(label);
 
466
                GridData data= new GridData(SWT.FILL, SWT.CENTER, true, false);
 
467
                group.setLayoutData(data);
 
468
                return group;
 
469
        }
 
470
}