Fixed: 1777185 - Remote Debug option 'Open with ...' should work
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / ui / overlaypages / FieldEditorOverlayPage.java
1 /*******************************************************************************
2  * Copyright (c) 2003 Berthold Daum.
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  *     Berthold Daum
10  *******************************************************************************/
11 package net.sourceforge.phpeclipse.ui.overlaypages;
12
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IAdaptable;
20 import org.eclipse.core.runtime.QualifiedName;
21 import org.eclipse.jface.preference.FieldEditor;
22 import org.eclipse.jface.preference.FieldEditorPreferencePage;
23 import org.eclipse.jface.preference.IPreferenceNode;
24 import org.eclipse.jface.preference.IPreferencePage;
25 import org.eclipse.jface.preference.IPreferenceStore;
26 import org.eclipse.jface.preference.PreferenceDialog;
27 import org.eclipse.jface.preference.PreferenceManager;
28 import org.eclipse.jface.preference.PreferenceNode;
29 import org.eclipse.jface.resource.ImageDescriptor;
30 import org.eclipse.swt.SWT;
31 import org.eclipse.swt.custom.BusyIndicator;
32 import org.eclipse.swt.events.SelectionAdapter;
33 import org.eclipse.swt.events.SelectionEvent;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Button;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.ui.IWorkbenchPropertyPage;
40
41 /**
42  * @author Berthold Daum
43  */
44 public abstract class FieldEditorOverlayPage extends FieldEditorPreferencePage
45                 implements IWorkbenchPropertyPage {
46         /**
47          * * Name of resource property for the selection of workbench or project
48          * settings **
49          */
50         public static final String USEPROJECTSETTINGS = "useProjectSettings"; //$NON-NLS-1$
51
52         private static final String FALSE = "false"; //$NON-NLS-1$
53
54         private static final String TRUE = "true"; //$NON-NLS-1$
55
56         private boolean fUseFileSettings = false;
57
58         // Stores all created field editors
59         private List editors = new ArrayList();
60
61         // Stores owning element of properties
62         private IAdaptable element;
63
64         // Additional buttons for property pages
65         private Button useWorkspaceSettingsButton, useProjectSettingsButton,
66                         configureButton;
67
68         // Overlay preference store for property pages
69         private IPreferenceStore overlayStore;
70
71         // The image descriptor of this pages title image
72         private ImageDescriptor image;
73
74         // Cache for page id
75         private String pageId;
76
77         /**
78          * Constructor
79          * 
80          * @param style -
81          *            layout style
82          */
83         public FieldEditorOverlayPage(int style) {
84                 super(style);
85         }
86
87         /**
88          * Constructor
89          * 
90          * @param style -
91          *            layout style
92          */
93         public FieldEditorOverlayPage(int style, boolean isFileSettings) {
94                 super(style);
95                 fUseFileSettings = isFileSettings;
96         }
97
98         /**
99          * Constructor
100          * 
101          * @param title -
102          *            title string
103          * @param style -
104          *            layout style
105          */
106         public FieldEditorOverlayPage(String title, int style) {
107                 super(title, style);
108         }
109
110         public FieldEditorOverlayPage(String title, int style,
111                         boolean isFileSettings) {
112                 super(title, style);
113                 fUseFileSettings = isFileSettings;
114         }
115
116         /**
117          * Constructor
118          * 
119          * @param title -
120          *            title string
121          * @param image -
122          *            title image
123          * @param style -
124          *            layout style
125          */
126         public FieldEditorOverlayPage(String title, ImageDescriptor image, int style) {
127                 super(title, image, style);
128                 this.image = image;
129         }
130
131         /**
132          * Returns the id of the current preference page as defined in plugin.xml
133          * Subclasses must implement.
134          * 
135          * @return - the qualifier
136          */
137         protected abstract String getPageId();
138
139         /**
140          * Receives the object that owns the properties shown in this property page.
141          * 
142          * @see org.eclipse.ui.IWorkbenchPropertyPage#setElement(org.eclipse.core.runtime.IAdaptable)
143          */
144         public void setElement(IAdaptable element) {
145                 this.element = element;
146         }
147
148         /**
149          * Delivers the object that owns the properties shown in this property page.
150          * 
151          * @see org.eclipse.ui.IWorkbenchPropertyPage#getElement()
152          */
153         public IAdaptable getElement() {
154                 return element;
155         }
156
157         /**
158          * Returns true if this instance represents a property page
159          * 
160          * @return - true for property pages, false for preference pages
161          */
162         public boolean isPropertyPage() {
163                 return getElement() != null;
164         }
165
166         /**
167          * We override the addField method. This allows us to store each field
168          * editor added by subclasses in a list for later processing.
169          * 
170          * @see org.eclipse.jface.preference.FieldEditorPreferencePage#addField(org.eclipse.jface.preference.FieldEditor)
171          */
172         protected void addField(FieldEditor editor) {
173                 editors.add(editor);
174                 super.addField(editor);
175         }
176
177         /**
178          * We override the createControl method. In case of property pages we create
179          * a new PropertyStore as local preference store. After all control have
180          * been create, we enable/disable these controls.
181          * 
182          * @see org.eclipse.jface.preference.PreferencePage#createControl()
183          */
184         public void createControl(Composite parent) {
185                 // Special treatment for property pages
186                 if (isPropertyPage()) {
187                         // Cache the page id
188                         pageId = getPageId();
189                         // Create an overlay preference store and fill it with properties
190                         overlayStore = new PropertyStore((IResource) getElement(), super
191                                         .getPreferenceStore(), pageId);
192                         // Set overlay store as current preference store
193                 }
194                 super.createControl(parent);
195                 // Update state of all subclass controls
196                 if (isPropertyPage())
197                         updateFieldEditors();
198         }
199
200         /**
201          * We override the createContents method. In case of property pages we
202          * insert two radio buttons at the top of the page.
203          * 
204          * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
205          */
206         protected Control createContents(Composite parent) {
207                 if (isPropertyPage())
208                         createSelectionGroup(parent);
209                 return super.createContents(parent);
210         }
211
212         /**
213          * Creates and initializes a selection group with two choice buttons and one
214          * push button.
215          * 
216          * @param parent -
217          *            the parent composite
218          */
219         private void createSelectionGroup(Composite parent) {
220                 Composite comp = new Composite(parent, SWT.NONE);
221                 GridLayout layout = new GridLayout(2, false);
222                 layout.marginHeight = 0;
223                 layout.marginWidth = 0;
224                 comp.setLayout(layout);
225                 comp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
226                 Composite radioGroup = new Composite(comp, SWT.NONE);
227                 radioGroup.setLayout(new GridLayout());
228                 radioGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
229                 useWorkspaceSettingsButton = createRadioButton(radioGroup, Messages
230                                 .getString("OverlayPage.Use_Workspace_Settings")); //$NON-NLS-1$
231                 if (fUseFileSettings) {
232                         useProjectSettingsButton = createRadioButton(radioGroup, Messages
233                                         .getString("OverlayPage.Use_File_Settings")); //$NON-NLS-1$
234                 } else {
235                         useProjectSettingsButton = createRadioButton(radioGroup, Messages
236                                         .getString("OverlayPage.Use_Project_Settings")); //$NON-NLS-1$
237                 }
238                 configureButton = new Button(comp, SWT.PUSH);
239                 configureButton.setText(Messages
240                                 .getString("OverlayPage.Configure_Workspace_Settings")); //$NON-NLS-1$
241                 configureButton.addSelectionListener(new SelectionAdapter() {
242                         public void widgetSelected(SelectionEvent e) {
243                                 configureWorkspaceSettings();
244                         }
245                 });
246                 // Set workspace/project radio buttons
247                 try {
248                         String use = ((IResource) getElement())
249                                         .getPersistentProperty(new QualifiedName(pageId,
250                                                         USEPROJECTSETTINGS));
251                         if (TRUE.equals(use)) {
252                                 useProjectSettingsButton.setSelection(true);
253                                 configureButton.setEnabled(false);
254                         } else
255                                 useWorkspaceSettingsButton.setSelection(true);
256                 } catch (CoreException e) {
257                         useWorkspaceSettingsButton.setSelection(true);
258                 }
259         }
260
261         /**
262          * Convenience method creating a radio button
263          * 
264          * @param parent -
265          *            the parent composite
266          * @param label -
267          *            the button label
268          * @return - the new button
269          */
270         private Button createRadioButton(Composite parent, String label) {
271                 final Button button = new Button(parent, SWT.RADIO);
272                 button.setText(label);
273                 button.addSelectionListener(new SelectionAdapter() {
274                         public void widgetSelected(SelectionEvent e) {
275                                 configureButton
276                                                 .setEnabled(button == useWorkspaceSettingsButton);
277                                 updateFieldEditors();
278                         }
279                 });
280                 return button;
281         }
282
283         /**
284          * Returns in case of property pages the overlay store, in case of
285          * preference pages the standard preference store
286          * 
287          * @see org.eclipse.jface.preference.PreferencePage#getPreferenceStore()
288          */
289         public IPreferenceStore getPreferenceStore() {
290                 if (isPropertyPage())
291                         return overlayStore;
292                 return super.getPreferenceStore();
293         }
294
295         /*
296          * Enables or disables the field editors and buttons of this page
297          */
298         private void updateFieldEditors() {
299                 // We iterate through all field editors
300                 boolean enabled = useProjectSettingsButton.getSelection();
301                 updateFieldEditors(enabled);
302         }
303
304         /**
305          * Enables or disables the field editors and buttons of this page Subclasses
306          * may override.
307          * 
308          * @param enabled -
309          *            true if enabled
310          */
311         protected void updateFieldEditors(boolean enabled) {
312                 Composite parent = getFieldEditorParent();
313                 Iterator it = editors.iterator();
314                 while (it.hasNext()) {
315                         FieldEditor editor = (FieldEditor) it.next();
316                         editor.setEnabled(enabled, parent);
317                 }
318         }
319
320         /**
321          * We override the performOk method. In case of property pages we copy the
322          * values in the overlay store into the property values of the selected
323          * project. We also save the state of the radio buttons.
324          * 
325          * @see org.eclipse.jface.preference.IPreferencePage#performOk()
326          */
327         public boolean performOk() {
328                 boolean result = super.performOk();
329                 if (result && isPropertyPage()) {
330                         // Save state of radiobuttons in project properties
331                         IResource resource = (IResource) getElement();
332                         try {
333                                 String value = (useProjectSettingsButton.getSelection()) ? TRUE
334                                                 : FALSE;
335                                 resource.setPersistentProperty(new QualifiedName(pageId,
336                                                 USEPROJECTSETTINGS), value);
337                         } catch (CoreException e) {
338                         }
339                 }
340                 return result;
341         }
342
343         /**
344          * We override the performDefaults method. In case of property pages we
345          * switch back to the workspace settings and disable the field editors.
346          * 
347          * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
348          */
349         protected void performDefaults() {
350                 if (isPropertyPage()) {
351                         useWorkspaceSettingsButton.setSelection(true);
352                         useProjectSettingsButton.setSelection(false);
353                         configureButton.setEnabled(true);
354                         updateFieldEditors();
355                 }
356                 super.performDefaults();
357         }
358
359         /**
360          * Creates a new preferences page and opens it
361          * 
362          * @see com.bdaum.SpellChecker.preferences.SpellCheckerPreferencePage#configureWorkspaceSettings()
363          */
364         protected void configureWorkspaceSettings() {
365                 try {
366                         // create a new instance of the current class
367                         IPreferencePage page = (IPreferencePage) this.getClass()
368                                         .newInstance();
369                         page.setTitle(getTitle());
370                         page.setImageDescriptor(image);
371                         // and show it
372                         showPreferencePage(pageId, page);
373                 } catch (InstantiationException e) {
374                         e.printStackTrace();
375                 } catch (IllegalAccessException e) {
376                         e.printStackTrace();
377                 }
378         }
379
380         /**
381          * Show a single preference pages
382          * 
383          * @param id -
384          *            the preference page identification
385          * @param page -
386          *            the preference page
387          */
388         protected void showPreferencePage(String id, IPreferencePage page) {
389                 final IPreferenceNode targetNode = new PreferenceNode(id, page);
390                 PreferenceManager manager = new PreferenceManager();
391                 manager.addToRoot(targetNode);
392                 final PreferenceDialog dialog = new PreferenceDialog(getControl()
393                                 .getShell(), manager);
394                 BusyIndicator.showWhile(getControl().getDisplay(), new Runnable() {
395                         public void run() {
396                                 dialog.create();
397                                 dialog.setMessage(targetNode.getLabelText());
398                                 dialog.open();
399                         }
400                 });
401         }
402 }