improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / preferences / FoldingConfigurationBlock.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.internal.ui.preferences;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.Map;
18
19 import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderDescriptor;
20 import net.sourceforge.phpdt.internal.ui.text.folding.JavaFoldingStructureProviderRegistry;
21 import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
22 import net.sourceforge.phpdt.ui.PreferenceConstants;
23 import net.sourceforge.phpdt.ui.text.folding.IJavaFoldingPreferenceBlock;
24 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
25
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.jface.text.Assert;
30 import org.eclipse.jface.viewers.ComboViewer;
31 import org.eclipse.jface.viewers.ISelectionChangedListener;
32 import org.eclipse.jface.viewers.IStructuredContentProvider;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.jface.viewers.LabelProvider;
35 import org.eclipse.jface.viewers.SelectionChangedEvent;
36 import org.eclipse.jface.viewers.StructuredSelection;
37 import org.eclipse.jface.viewers.Viewer;
38 import org.eclipse.swt.SWT;
39 import org.eclipse.swt.custom.StackLayout;
40 import org.eclipse.swt.events.SelectionEvent;
41 import org.eclipse.swt.events.SelectionListener;
42 import org.eclipse.swt.graphics.Image;
43 import org.eclipse.swt.layout.FillLayout;
44 import org.eclipse.swt.layout.GridData;
45 import org.eclipse.swt.layout.GridLayout;
46 import org.eclipse.swt.widgets.Button;
47 import org.eclipse.swt.widgets.Combo;
48 import org.eclipse.swt.widgets.Composite;
49 import org.eclipse.swt.widgets.Control;
50 import org.eclipse.swt.widgets.Label;
51
52 /**
53  * Configures Java Editor folding preferences.
54  * 
55  * @since 3.0
56  */
57 class FoldingConfigurationBlock {
58         
59         private static class ErrorPreferences implements IJavaFoldingPreferenceBlock {
60                 private String fMessage;
61                 
62                 protected ErrorPreferences(String message) {
63                         fMessage= message;
64                 }
65                 
66                 /*
67                  * @see net.sourceforge.phpdt.internal.ui.text.folding.IJavaFoldingPreferences#createControl(org.eclipse.swt.widgets.Group)
68                  */
69                 public Control createControl(Composite composite) {
70                         Composite inner= new Composite(composite, SWT.NONE);
71                         inner.setLayout(new FillLayout(SWT.VERTICAL));
72
73                         Label label= new Label(inner, SWT.CENTER);
74                         label.setText(fMessage);
75                         
76                         return inner;
77                 }
78
79                 public void initialize() {
80                 }
81
82                 public void performOk() {
83                 }
84
85                 public void performDefaults() {
86                 }
87
88                 public void dispose() {
89                 }
90                 
91         }
92
93         /** The overlay preference store. */
94         private final OverlayPreferenceStore fStore;
95         
96         /* The controls */
97         private Combo fProviderCombo;
98         private Button fFoldingCheckbox;
99         private ComboViewer fProviderViewer;
100         private Map fProviderDescriptors;
101         private Composite fGroup;
102         private Map fProviderPreferences;
103         private Map fProviderControls;
104         private StackLayout fStackLayout;
105         
106
107         public FoldingConfigurationBlock(OverlayPreferenceStore store) {
108                 Assert.isNotNull(store);
109                 fStore= store;
110                 fStore.addKeys(createOverlayStoreKeys());
111                 fProviderDescriptors= createListModel();
112                 fProviderPreferences= new HashMap();
113                 fProviderControls= new HashMap();
114         }
115
116         private Map createListModel() {
117                 JavaFoldingStructureProviderRegistry reg= PHPeclipsePlugin.getDefault().getFoldingStructureProviderRegistry();
118                 reg.reloadExtensions();
119                 JavaFoldingStructureProviderDescriptor[] descs= reg.getFoldingProviderDescriptors();
120                 Map map= new HashMap();
121                 for (int i= 0; i < descs.length; i++) {
122                         map.put(descs[i].getId(), descs[i]);
123                 }
124                 return map;
125         }
126
127         private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
128                 
129                 ArrayList overlayKeys= new ArrayList();
130
131                 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_FOLDING_ENABLED));
132                 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_FOLDING_PROVIDER));
133                 
134                 OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
135                 overlayKeys.toArray(keys);
136                 return keys;
137         }
138
139         /**
140          * Creates page for folding preferences.
141          * 
142          * @param parent the parent composite
143          * @return the control for the preference page
144          */
145         Control createControl(Composite parent) {
146
147                 Composite composite= new Composite(parent, SWT.NULL);
148                 // assume parent page uses griddata
149                 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
150                 composite.setLayoutData(gd);
151                 GridLayout layout= new GridLayout();
152                 layout.numColumns= 2;
153                 PixelConverter pc= new PixelConverter(composite);
154                 layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2;
155                 composite.setLayout(layout);
156                 
157                 
158                 /* check box for new editors */
159                 fFoldingCheckbox= new Button(composite, SWT.CHECK);
160                 fFoldingCheckbox.setText(PreferencesMessages.getString("FoldingConfigurationBlock.enable")); //$NON-NLS-1$
161                 gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
162                 fFoldingCheckbox.setLayoutData(gd);
163                 fFoldingCheckbox.addSelectionListener(new SelectionListener() {
164                         public void widgetSelected(SelectionEvent e) {
165                                 boolean enabled= fFoldingCheckbox.getSelection(); 
166                                 fStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, enabled);
167                                 updateCheckboxDependencies();
168                         }
169
170                         public void widgetDefaultSelected(SelectionEvent e) {
171                         }
172                 });
173                 
174                 Label label= new Label(composite, SWT.CENTER);
175                 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
176                 label.setLayoutData(gd);
177
178                 /* list */
179                 Composite comboComp= new Composite(composite, SWT.NONE);
180                 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
181                 GridLayout gridLayout= new GridLayout(2, false);
182                 gridLayout.marginWidth= 0;
183                 comboComp.setLayout(gridLayout);
184                 
185                 Label comboLabel= new Label(comboComp, SWT.CENTER);
186                 gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER);
187                 comboLabel.setLayoutData(gd);
188                 comboLabel.setText(PreferencesMessages.getString("FoldingConfigurationBlock.combo_caption")); //$NON-NLS-1$
189                 
190                 label= new Label(composite, SWT.CENTER);
191                 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING);
192                 label.setLayoutData(gd);
193
194                 fProviderCombo= new Combo(comboComp, SWT.READ_ONLY | SWT.DROP_DOWN);
195                 gd= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER);
196                 fProviderCombo.setLayoutData(gd);
197
198                 /* list viewer */
199                 fProviderViewer= new ComboViewer(fProviderCombo);
200                 fProviderViewer.setContentProvider(new IStructuredContentProvider() {
201
202                         /*
203                          * @see org.eclipse.jface.viewers.IContentProvider#dispose()
204                          */
205                         public void dispose() {
206                         }
207
208                         /*
209                          * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
210                          */
211                         public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
212                         }
213
214                         /*
215                          * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
216                          */
217                         public Object[] getElements(Object inputElement) {
218                                 return fProviderDescriptors.values().toArray();
219                         }
220                 });
221                 fProviderViewer.setLabelProvider(new LabelProvider() {
222                         /*
223                          * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
224                          */
225                         public Image getImage(Object element) {
226                                 return null;
227                         }
228                         
229                         /*
230                          * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
231                          */
232                         public String getText(Object element) {
233                                 return ((JavaFoldingStructureProviderDescriptor) element).getName();
234                         }
235                 });
236                 fProviderViewer.addSelectionChangedListener(new ISelectionChangedListener() {
237
238                         public void selectionChanged(SelectionChangedEvent event) {
239                                 IStructuredSelection sel= (IStructuredSelection) event.getSelection();
240                                 if (!sel.isEmpty()) {
241                                         fStore.setValue(PreferenceConstants.EDITOR_FOLDING_PROVIDER, ((JavaFoldingStructureProviderDescriptor) sel.getFirstElement()).getId());
242                                         updateListDependencies();
243                                 }
244                         }
245                 });
246                 fProviderViewer.setInput(fProviderDescriptors);
247                 fProviderViewer.refresh();
248                 
249                 Composite groupComp= new Composite(composite, SWT.NONE);
250                 gd= new GridData(GridData.FILL_BOTH);
251                 gd.horizontalSpan= 2;
252                 groupComp.setLayoutData(gd);
253                 gridLayout= new GridLayout(1, false);
254                 gridLayout.marginWidth= 0;
255                 groupComp.setLayout(gridLayout);
256                 
257                 /* contributed provider preferences. */
258                 fGroup= new Composite(groupComp, SWT.NONE);
259                 gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
260                 fGroup.setLayoutData(gd);
261                 fStackLayout= new StackLayout();
262                 fGroup.setLayout(fStackLayout);
263                 
264                 return composite;
265         }
266
267         private void updateCheckboxDependencies() {
268         }
269
270         void updateListDependencies() {
271                 String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
272                 JavaFoldingStructureProviderDescriptor desc= (JavaFoldingStructureProviderDescriptor) fProviderDescriptors.get(id);
273                 IJavaFoldingPreferenceBlock prefs;
274                 
275                 if (desc == null) {
276                         // safety in case there is no such descriptor
277                         String message= PreferencesMessages.getString("FoldingConfigurationBlock.error.not_exist"); //$NON-NLS-1$
278                         PHPeclipsePlugin.log(new Status(IStatus.WARNING, PHPeclipsePlugin.getPluginId(), IStatus.OK, message, null));
279                         prefs= new ErrorPreferences(message);
280                 } else {
281                         prefs= (IJavaFoldingPreferenceBlock) fProviderPreferences.get(id);
282                         if (prefs == null) {
283                                 try {
284                                         prefs= desc.createPreferences();
285                                         fProviderPreferences.put(id, prefs);
286                                 } catch (CoreException e) {
287                                         PHPeclipsePlugin.log(e);
288                                         prefs= new ErrorPreferences(e.getLocalizedMessage());
289                                 }
290                         }
291                 }
292                 
293                 Control control= (Control) fProviderControls.get(id);
294                 if (control == null) {
295                         control= prefs.createControl(fGroup);
296                         if (control == null) {
297                                 String message= PreferencesMessages.getString("FoldingConfigurationBlock.info.no_preferences"); //$NON-NLS-1$
298                                 control= new ErrorPreferences(message).createControl(fGroup);
299                         } else {
300                                 fProviderControls.put(id, control);
301                         }
302                 }
303                 fStackLayout.topControl= control;
304                 control.pack();
305                 fGroup.layout();
306                 fGroup.getParent().layout();
307                 
308                 prefs.initialize();
309         }
310
311         void initialize() {
312                 restoreFromPreferences();
313         }
314
315         void performOk() {
316                 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) {
317                         IJavaFoldingPreferenceBlock prefs= (IJavaFoldingPreferenceBlock) it.next();
318                         prefs.performOk();
319                 }
320         }
321         
322         void performDefaults() {
323                 restoreFromPreferences();
324                 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) {
325                         IJavaFoldingPreferenceBlock prefs= (IJavaFoldingPreferenceBlock) it.next();
326                         prefs.performDefaults();
327                 }
328         }
329         
330         void dispose() {
331                 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) {
332                         IJavaFoldingPreferenceBlock prefs= (IJavaFoldingPreferenceBlock) it.next();
333                         prefs.dispose();
334                 }
335         }
336
337         private void restoreFromPreferences() {
338                 boolean enabled= fStore.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED);
339                 fFoldingCheckbox.setSelection(enabled);
340                 updateCheckboxDependencies();
341                 
342                 String id= fStore.getString(PreferenceConstants.EDITOR_FOLDING_PROVIDER);
343                 Object provider= fProviderDescriptors.get(id);
344                 if (provider != null) {
345                         fProviderViewer.setSelection(new StructuredSelection(provider), true);
346                         updateListDependencies();
347                 }
348         }
349 }