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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.internal.ui.preferences;
14 import java.util.HashMap;
15 import java.util.StringTokenizer;
17 import net.sourceforge.phpdt.internal.ui.dialogs.StatusInfo;
18 import net.sourceforge.phpdt.internal.ui.dialogs.StatusUtil;
19 import net.sourceforge.phpdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor;
20 import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
21 import net.sourceforge.phpdt.ui.PreferenceConstants;
22 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.jface.action.Action;
26 import org.eclipse.jface.dialogs.Dialog;
27 import org.eclipse.jface.preference.IPreferenceStore;
28 import org.eclipse.jface.text.Assert;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.KeyEvent;
31 import org.eclipse.swt.events.KeyListener;
32 import org.eclipse.swt.events.ModifyEvent;
33 import org.eclipse.swt.events.ModifyListener;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.events.SelectionListener;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.layout.GridData;
38 import org.eclipse.swt.layout.GridLayout;
39 import org.eclipse.swt.widgets.Button;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.Control;
42 import org.eclipse.swt.widgets.Label;
43 import org.eclipse.swt.widgets.List;
44 import org.eclipse.swt.widgets.Text;
47 * Configures Java Editor hover preferences.
51 class JavaEditorHoverConfigurationBlock {
53 private static final String DELIMITER= PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
55 // Data structure to hold the values which are edited by the user
56 private static class HoverConfig {
58 private String fModifierString;
59 private boolean fIsEnabled;
60 private int fStateMask;
62 private HoverConfig(String modifier, int stateMask, boolean enabled) {
63 fModifierString= modifier;
65 fStateMask= stateMask;
69 private IPreferenceStore fStore;
70 private HoverConfig[] fHoverConfigs;
71 private Text fModifierEditor;
72 private Button fEnableField;
73 private List fHoverList;
74 private Text fDescription;
75 // private Button fShowHoverAffordanceCheckbox;
77 private JavaEditorPreferencePage fMainPreferencePage;
79 private StatusInfo fStatus;
81 public JavaEditorHoverConfigurationBlock(JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
82 Assert.isNotNull(mainPreferencePage);
83 Assert.isNotNull(store);
84 fMainPreferencePage= mainPreferencePage;
89 * Creates page for hover preferences.
91 public Control createControl(Composite parent) {
93 PixelConverter pixelConverter= new PixelConverter(parent);
95 Composite hoverComposite= new Composite(parent, SWT.NULL);
96 GridLayout layout= new GridLayout();
98 hoverComposite.setLayout(layout);
99 GridData gd= new GridData(GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
100 hoverComposite.setLayoutData(gd);
102 Label label= new Label(hoverComposite, SWT.NONE);
103 label.setText(PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.hoverPreferences")); //$NON-NLS-1$
104 gd= new GridData(GridData.FILL_HORIZONTAL);
105 gd.horizontalAlignment= GridData.BEGINNING;
106 gd.horizontalSpan= 2;
107 label.setLayoutData(gd);
108 gd= new GridData(GridData.GRAB_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
111 fHoverList= new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
112 gd= new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
113 int listHeight= 10 * fHoverList.getItemHeight();
114 gd.heightHint= listHeight;
115 fHoverList.setLayoutData(gd);
116 fHoverList.addSelectionListener(new SelectionListener() {
117 public void widgetSelected(SelectionEvent e) {
118 handleHoverListSelection();
120 public void widgetDefaultSelected(SelectionEvent e) {
125 Composite stylesComposite= new Composite(hoverComposite, SWT.NONE);
126 layout= new GridLayout();
127 layout.marginHeight= 0;
128 layout.marginWidth= 0;
129 layout.numColumns= 2;
130 stylesComposite.setLayout(layout);
131 gd= new GridData(GridData.FILL_HORIZONTAL);
132 gd.heightHint= listHeight + (2 * fHoverList.getBorderWidth());
133 stylesComposite.setLayoutData(gd);
136 fEnableField= new Button(stylesComposite, SWT.CHECK);
137 fEnableField.setText(PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.enabled")); //$NON-NLS-1$
138 gd= new GridData(GridData.FILL_HORIZONTAL);
139 gd.horizontalAlignment= GridData.BEGINNING;
140 gd.horizontalSpan= 2;
141 fEnableField.setLayoutData(gd);
142 fEnableField.addSelectionListener(new SelectionListener() {
143 public void widgetSelected(SelectionEvent e) {
144 int i= fHoverList.getSelectionIndex();
145 boolean state= fEnableField.getSelection();
146 fModifierEditor.setEnabled(state);
147 fHoverConfigs[i].fIsEnabled= state;
148 handleModifierModified();
150 public void widgetDefaultSelected(SelectionEvent e) {
154 // Text field for modifier string
155 label= new Label(stylesComposite, SWT.LEFT);
156 label.setText(PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.keyModifier")); //$NON-NLS-1$
157 fModifierEditor= new Text(stylesComposite, SWT.BORDER);
158 gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
159 fModifierEditor.setLayoutData(gd);
161 fModifierEditor.addKeyListener(new KeyListener() {
162 private boolean isModifierCandidate;
163 public void keyPressed(KeyEvent e) {
164 isModifierCandidate= e.keyCode > 0 && e.character == 0 && e.stateMask == 0;
167 public void keyReleased(KeyEvent e) {
168 if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask && e.character == 0) {// && e.time -time < 1000) {
169 String text= fModifierEditor.getText();
170 Point selection= fModifierEditor.getSelection();
171 int i= selection.x - 1;
172 while (i > -1 && Character.isWhitespace(text.charAt(i))) {
175 boolean needsPrefixDelimiter= i > -1 && !String.valueOf(text.charAt(i)).equals(DELIMITER);
178 while (i < text.length() && Character.isWhitespace(text.charAt(i))) {
181 boolean needsPostfixDelimiter= i < text.length() && !String.valueOf(text.charAt(i)).equals(DELIMITER);
185 if (needsPrefixDelimiter && needsPostfixDelimiter)
186 insertString= PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$
187 else if (needsPrefixDelimiter)
188 insertString= PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$
189 else if (needsPostfixDelimiter)
190 insertString= PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] {Action.findModifierString(e.stateMask)}); //$NON-NLS-1$
192 insertString= Action.findModifierString(e.stateMask);
194 if (insertString != null)
195 fModifierEditor.insert(insertString);
200 fModifierEditor.addModifyListener(new ModifyListener() {
201 public void modifyText(ModifyEvent e) {
202 handleModifierModified();
207 Label descriptionLabel= new Label(stylesComposite, SWT.LEFT);
208 descriptionLabel.setText(PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.description")); //$NON-NLS-1$
209 gd= new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
210 gd.horizontalSpan= 2;
211 descriptionLabel.setLayoutData(gd);
212 fDescription= new Text(stylesComposite, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
213 gd= new GridData(GridData.FILL_BOTH);
214 gd.horizontalSpan= 2;
215 fDescription.setLayoutData(gd);
218 Label filler= new Label(hoverComposite, SWT.LEFT);
219 gd= new GridData(GridData.BEGINNING | GridData.VERTICAL_ALIGN_FILL);
220 gd.heightHint= pixelConverter.convertHeightInCharsToPixels(1) / 3;
221 filler.setLayoutData(gd);
223 // Affordance checkbox
224 // fShowHoverAffordanceCheckbox= new Button(hoverComposite, SWT.CHECK);
225 // fShowHoverAffordanceCheckbox.setText(PreferencesMessages.getString("JavaEditorHoverConfigurationBlock.showAffordance")); //$NON-NLS-1$
226 // gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
227 // gd.horizontalIndent= 0;
228 // gd.horizontalSpan= 2;
229 // fShowHoverAffordanceCheckbox.setLayoutData(gd);
233 Dialog.applyDialogFont(hoverComposite);
234 return hoverComposite;
237 private JavaEditorTextHoverDescriptor[] getContributedHovers() {
238 return PHPeclipsePlugin.getDefault().getJavaEditorTextHoverDescriptors();
242 JavaEditorTextHoverDescriptor[] hoverDescs= getContributedHovers();
243 fHoverConfigs= new HoverConfig[hoverDescs.length];
244 for (int i= 0; i < hoverDescs.length; i++) {
245 fHoverConfigs[i]= new HoverConfig(hoverDescs[i].getModifierString(), hoverDescs[i].getStateMask(), hoverDescs[i].isEnabled());
246 fHoverList.add(hoverDescs[i].getLabel());
251 void initializeFields() {
252 fHoverList.getDisplay().asyncExec(new Runnable() {
254 if (fHoverList != null && !fHoverList.isDisposed()) {
255 fHoverList.select(0);
256 handleHoverListSelection();
260 // fShowHoverAffordanceCheckbox.setSelection(fStore.getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
264 StringBuffer buf= new StringBuffer();
265 StringBuffer maskBuf= new StringBuffer();
266 for (int i= 0; i < fHoverConfigs.length; i++) {
267 buf.append(getContributedHovers()[i].getId());
268 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
269 if (!fHoverConfigs[i].fIsEnabled)
270 buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG);
271 String modifier= fHoverConfigs[i].fModifierString;
272 if (modifier == null || modifier.length() == 0)
273 modifier= JavaEditorTextHoverDescriptor.NO_MODIFIER;
274 buf.append(modifier);
275 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
277 maskBuf.append(getContributedHovers()[i].getId());
278 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
279 maskBuf.append(fHoverConfigs[i].fStateMask);
280 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
282 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf.toString());
283 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, maskBuf.toString());
285 // fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, fShowHoverAffordanceCheckbox.getSelection());
287 PHPeclipsePlugin.getDefault().resetJavaEditorTextHoverDescriptors();
290 void performDefaults() {
291 restoreFromPreferences();
295 private void restoreFromPreferences() {
297 // fShowHoverAffordanceCheckbox.setSelection(fStore.getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
299 String compiledTextHoverModifiers= fStore.getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
301 StringTokenizer tokenizer= new StringTokenizer(compiledTextHoverModifiers, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
302 HashMap idToModifier= new HashMap(tokenizer.countTokens() / 2);
304 while (tokenizer.hasMoreTokens()) {
305 String id= tokenizer.nextToken();
306 if (tokenizer.hasMoreTokens())
307 idToModifier.put(id, tokenizer.nextToken());
310 String compiledTextHoverModifierMasks= PHPeclipsePlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
312 tokenizer= new StringTokenizer(compiledTextHoverModifierMasks, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
313 HashMap idToModifierMask= new HashMap(tokenizer.countTokens() / 2);
315 while (tokenizer.hasMoreTokens()) {
316 String id= tokenizer.nextToken();
317 if (tokenizer.hasMoreTokens())
318 idToModifierMask.put(id, tokenizer.nextToken());
321 for (int i= 0; i < fHoverConfigs.length; i++) {
322 String modifierString= (String)idToModifier.get(getContributedHovers()[i].getId());
323 boolean enabled= true;
324 if (modifierString == null)
325 modifierString= JavaEditorTextHoverDescriptor.DISABLED_TAG;
327 if (modifierString.startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
329 modifierString= modifierString.substring(1);
332 if (modifierString.equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
333 modifierString= ""; //$NON-NLS-1$
335 fHoverConfigs[i].fModifierString= modifierString;
336 fHoverConfigs[i].fIsEnabled= enabled;
337 fHoverConfigs[i].fStateMask= JavaEditorTextHoverDescriptor.computeStateMask(modifierString);
339 if (fHoverConfigs[i].fStateMask == -1) {
341 fHoverConfigs[i].fStateMask= Integer.parseInt((String)idToModifierMask.get(getContributedHovers()[i].getId()));
342 } catch (NumberFormatException ex) {
343 fHoverConfigs[i].fStateMask= -1;
349 private void handleModifierModified() {
350 int i= fHoverList.getSelectionIndex();
351 String modifiers= fModifierEditor.getText();
352 fHoverConfigs[i].fModifierString= modifiers;
353 fHoverConfigs[i].fStateMask= JavaEditorTextHoverDescriptor.computeStateMask(modifiers);
354 if (fHoverConfigs[i].fIsEnabled && fHoverConfigs[i].fStateMask == -1)
355 fStatus= new StatusInfo(IStatus.ERROR, PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
357 fStatus= new StatusInfo();
361 private void handleHoverListSelection() {
362 int i= fHoverList.getSelectionIndex();
363 boolean enabled= fHoverConfigs[i].fIsEnabled;
364 fEnableField.setSelection(enabled);
365 fModifierEditor.setEnabled(enabled);
366 fModifierEditor.setText(fHoverConfigs[i].fModifierString);
367 String description= getContributedHovers()[i].getDescription();
368 if (description == null)
369 description= ""; //$NON-NLS-1$
370 fDescription.setText(description);
373 IStatus getStatus() {
375 fStatus= new StatusInfo();
379 private void updateStatus() {
381 HashMap stateMasks= new HashMap(fHoverConfigs.length);
382 while (fStatus.isOK() && i < fHoverConfigs.length) {
383 if (fHoverConfigs[i].fIsEnabled) {
384 String label= getContributedHovers()[i].getLabel();
385 Integer stateMask= new Integer(fHoverConfigs[i].fStateMask);
386 if (fHoverConfigs[i].fStateMask == -1)
387 fStatus= new StatusInfo(IStatus.ERROR, PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] {fHoverConfigs[i].fModifierString, label})); //$NON-NLS-1$
388 else if (stateMasks.containsKey(stateMask))
389 fStatus= new StatusInfo(IStatus.ERROR, PreferencesMessages.getFormattedString("JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] {label, (String)stateMasks.get(stateMask)})); //$NON-NLS-1$
391 stateMasks.put(stateMask, label);
397 fMainPreferencePage.updateStatus(fStatus);
399 fMainPreferencePage.setValid(false);
400 StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);