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