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;
29 //import org.eclipse.jface.text.Assert;
30 import org.eclipse.core.runtime.Assert;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.events.KeyEvent;
33 import org.eclipse.swt.events.KeyListener;
34 import org.eclipse.swt.events.ModifyEvent;
35 import org.eclipse.swt.events.ModifyListener;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.events.SelectionListener;
38 import org.eclipse.swt.graphics.Point;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Button;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.swt.widgets.Control;
44 import org.eclipse.swt.widgets.Label;
45 import org.eclipse.swt.widgets.List;
46 import org.eclipse.swt.widgets.Text;
49 * Configures Java Editor hover preferences.
53 class JavaEditorHoverConfigurationBlock {
55 private static final String DELIMITER = PreferencesMessages
56 .getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
58 // Data structure to hold the values which are edited by the user
59 private static class HoverConfig {
61 private String fModifierString;
63 private boolean fIsEnabled;
65 private int fStateMask;
67 private HoverConfig(String modifier, int stateMask, boolean enabled) {
68 fModifierString = modifier;
70 fStateMask = stateMask;
74 private IPreferenceStore fStore;
76 private HoverConfig[] fHoverConfigs;
78 private Text fModifierEditor;
80 private Button fEnableField;
82 private List fHoverList;
84 private Text fDescription;
86 private Button fShowHoverAffordanceCheckbox;
88 private JavaEditorPreferencePage fMainPreferencePage;
90 private StatusInfo fStatus;
92 public JavaEditorHoverConfigurationBlock(
93 JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
94 Assert.isNotNull(mainPreferencePage);
95 Assert.isNotNull(store);
96 fMainPreferencePage = mainPreferencePage;
101 * Creates page for hover preferences.
103 public Control createControl(Composite parent) {
105 PixelConverter pixelConverter = new PixelConverter(parent);
107 Composite hoverComposite = new Composite(parent, SWT.NULL);
108 GridLayout layout = new GridLayout();
109 layout.numColumns = 2;
110 hoverComposite.setLayout(layout);
111 GridData gd = new GridData(GridData.GRAB_HORIZONTAL
112 | GridData.VERTICAL_ALIGN_FILL);
113 hoverComposite.setLayoutData(gd);
115 Label label = new Label(hoverComposite, SWT.NONE);
117 .setText(PreferencesMessages
118 .getString("JavaEditorHoverConfigurationBlock.hoverPreferences")); //$NON-NLS-1$
119 gd = new GridData(GridData.FILL_HORIZONTAL);
120 gd.horizontalAlignment = GridData.BEGINNING;
121 gd.horizontalSpan = 2;
122 label.setLayoutData(gd);
123 gd = new GridData(GridData.GRAB_HORIZONTAL
124 | GridData.VERTICAL_ALIGN_FILL);
127 fHoverList = new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL
129 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
130 | GridData.FILL_HORIZONTAL);
131 int listHeight = 10 * fHoverList.getItemHeight();
132 gd.heightHint = listHeight;
133 fHoverList.setLayoutData(gd);
134 fHoverList.addSelectionListener(new SelectionListener() {
135 public void widgetSelected(SelectionEvent e) {
136 handleHoverListSelection();
139 public void widgetDefaultSelected(SelectionEvent e) {
143 Composite stylesComposite = new Composite(hoverComposite, SWT.NONE);
144 layout = new GridLayout();
145 layout.marginHeight = 0;
146 layout.marginWidth = 0;
147 layout.numColumns = 2;
148 stylesComposite.setLayout(layout);
149 gd = new GridData(GridData.FILL_HORIZONTAL);
150 gd.heightHint = listHeight + (2 * fHoverList.getBorderWidth());
151 stylesComposite.setLayoutData(gd);
154 fEnableField = new Button(stylesComposite, SWT.CHECK);
155 fEnableField.setText(PreferencesMessages
156 .getString("JavaEditorHoverConfigurationBlock.enabled")); //$NON-NLS-1$
157 gd = new GridData(GridData.FILL_HORIZONTAL);
158 gd.horizontalAlignment = GridData.BEGINNING;
159 gd.horizontalSpan = 2;
160 fEnableField.setLayoutData(gd);
161 fEnableField.addSelectionListener(new SelectionListener() {
162 public void widgetSelected(SelectionEvent e) {
163 int i = fHoverList.getSelectionIndex();
164 boolean state = fEnableField.getSelection();
165 fModifierEditor.setEnabled(state);
166 fHoverConfigs[i].fIsEnabled = state;
167 handleModifierModified();
170 public void widgetDefaultSelected(SelectionEvent e) {
174 // Text field for modifier string
175 label = new Label(stylesComposite, SWT.LEFT);
176 label.setText(PreferencesMessages
177 .getString("JavaEditorHoverConfigurationBlock.keyModifier")); //$NON-NLS-1$
178 fModifierEditor = new Text(stylesComposite, SWT.BORDER);
179 gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
180 fModifierEditor.setLayoutData(gd);
182 fModifierEditor.addKeyListener(new KeyListener() {
183 private boolean isModifierCandidate;
185 public void keyPressed(KeyEvent e) {
186 isModifierCandidate = e.keyCode > 0 && e.character == 0
190 public void keyReleased(KeyEvent e) {
191 if (isModifierCandidate && e.stateMask > 0
192 && e.stateMask == e.stateMask && e.character == 0) {// &&
198 String text = fModifierEditor.getText();
199 Point selection = fModifierEditor.getSelection();
200 int i = selection.x - 1;
201 while (i > -1 && Character.isWhitespace(text.charAt(i))) {
204 boolean needsPrefixDelimiter = i > -1
205 && !String.valueOf(text.charAt(i))
209 while (i < text.length()
210 && Character.isWhitespace(text.charAt(i))) {
213 boolean needsPostfixDelimiter = i < text.length()
214 && !String.valueOf(text.charAt(i))
219 if (needsPrefixDelimiter && needsPostfixDelimiter)
220 insertString = PreferencesMessages
222 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
223 else if (needsPrefixDelimiter)
224 insertString = PreferencesMessages
226 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
227 else if (needsPostfixDelimiter)
228 insertString = PreferencesMessages
230 "JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
232 insertString = Action.findModifierString(e.stateMask);
234 if (insertString != null)
235 fModifierEditor.insert(insertString);
240 fModifierEditor.addModifyListener(new ModifyListener() {
241 public void modifyText(ModifyEvent e) {
242 handleModifierModified();
247 Label descriptionLabel = new Label(stylesComposite, SWT.LEFT);
248 descriptionLabel.setText(PreferencesMessages
249 .getString("JavaEditorHoverConfigurationBlock.description")); //$NON-NLS-1$
250 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
251 gd.horizontalSpan = 2;
252 descriptionLabel.setLayoutData(gd);
253 fDescription = new Text(stylesComposite, SWT.LEFT | SWT.WRAP
254 | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
255 gd = new GridData(GridData.FILL_BOTH);
256 gd.horizontalSpan = 2;
257 fDescription.setLayoutData(gd);
260 Label filler = new Label(hoverComposite, SWT.LEFT);
261 gd = new GridData(GridData.BEGINNING | GridData.VERTICAL_ALIGN_FILL);
262 gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 3;
263 filler.setLayoutData(gd);
265 // Affordance checkbox
266 fShowHoverAffordanceCheckbox = new Button(hoverComposite, SWT.CHECK);
267 fShowHoverAffordanceCheckbox.setText(PreferencesMessages
268 .getString("JavaEditorHoverConfigurationBlock.showAffordance")); //$NON-NLS-1$
269 gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
270 gd.horizontalIndent = 0;
271 gd.horizontalSpan = 2;
272 fShowHoverAffordanceCheckbox.setLayoutData(gd);
276 Dialog.applyDialogFont(hoverComposite);
277 return hoverComposite;
280 private JavaEditorTextHoverDescriptor[] getContributedHovers() {
281 return PHPeclipsePlugin.getDefault()
282 .getJavaEditorTextHoverDescriptors();
286 JavaEditorTextHoverDescriptor[] hoverDescs = getContributedHovers();
287 fHoverConfigs = new HoverConfig[hoverDescs.length];
288 for (int i = 0; i < hoverDescs.length; i++) {
289 fHoverConfigs[i] = new HoverConfig(hoverDescs[i]
290 .getModifierString(), hoverDescs[i].getStateMask(),
291 hoverDescs[i].isEnabled());
292 fHoverList.add(hoverDescs[i].getLabel());
297 void initializeFields() {
298 fHoverList.getDisplay().asyncExec(new Runnable() {
300 if (fHoverList != null && !fHoverList.isDisposed()) {
301 fHoverList.select(0);
302 handleHoverListSelection();
306 fShowHoverAffordanceCheckbox
308 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
312 StringBuffer buf = new StringBuffer();
313 StringBuffer maskBuf = new StringBuffer();
314 for (int i = 0; i < fHoverConfigs.length; i++) {
315 buf.append(getContributedHovers()[i].getId());
316 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
317 if (!fHoverConfigs[i].fIsEnabled)
318 buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG);
319 String modifier = fHoverConfigs[i].fModifierString;
320 if (modifier == null || modifier.length() == 0)
321 modifier = JavaEditorTextHoverDescriptor.NO_MODIFIER;
322 buf.append(modifier);
323 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
325 maskBuf.append(getContributedHovers()[i].getId());
326 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
327 maskBuf.append(fHoverConfigs[i].fStateMask);
328 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
330 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf
332 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
335 fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
336 fShowHoverAffordanceCheckbox.getSelection());
338 PHPeclipsePlugin.getDefault().resetJavaEditorTextHoverDescriptors();
341 void performDefaults() {
342 restoreFromPreferences();
346 private void restoreFromPreferences() {
348 fShowHoverAffordanceCheckbox
350 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
352 String compiledTextHoverModifiers = fStore
353 .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
355 StringTokenizer tokenizer = new StringTokenizer(
356 compiledTextHoverModifiers,
357 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
358 HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
360 while (tokenizer.hasMoreTokens()) {
361 String id = tokenizer.nextToken();
362 if (tokenizer.hasMoreTokens())
363 idToModifier.put(id, tokenizer.nextToken());
366 String compiledTextHoverModifierMasks = PHPeclipsePlugin.getDefault()
367 .getPreferenceStore().getString(
368 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
370 tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
371 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
372 HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
374 while (tokenizer.hasMoreTokens()) {
375 String id = tokenizer.nextToken();
376 if (tokenizer.hasMoreTokens())
377 idToModifierMask.put(id, tokenizer.nextToken());
380 for (int i = 0; i < fHoverConfigs.length; i++) {
381 String modifierString = (String) idToModifier
382 .get(getContributedHovers()[i].getId());
383 boolean enabled = true;
384 if (modifierString == null)
385 modifierString = JavaEditorTextHoverDescriptor.DISABLED_TAG;
388 .startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
390 modifierString = modifierString.substring(1);
394 .equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
395 modifierString = ""; //$NON-NLS-1$
397 fHoverConfigs[i].fModifierString = modifierString;
398 fHoverConfigs[i].fIsEnabled = enabled;
399 fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
400 .computeStateMask(modifierString);
402 if (fHoverConfigs[i].fStateMask == -1) {
404 fHoverConfigs[i].fStateMask = Integer
405 .parseInt((String) idToModifierMask
406 .get(getContributedHovers()[i].getId()));
407 } catch (NumberFormatException ex) {
408 fHoverConfigs[i].fStateMask = -1;
414 private void handleModifierModified() {
415 int i = fHoverList.getSelectionIndex();
416 String modifiers = fModifierEditor.getText();
417 fHoverConfigs[i].fModifierString = modifiers;
418 fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
419 .computeStateMask(modifiers);
420 if (fHoverConfigs[i].fIsEnabled && fHoverConfigs[i].fStateMask == -1)
421 fStatus = new StatusInfo(
425 "JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
427 fStatus = new StatusInfo();
431 private void handleHoverListSelection() {
432 int i = fHoverList.getSelectionIndex();
433 boolean enabled = fHoverConfigs[i].fIsEnabled;
434 fEnableField.setSelection(enabled);
435 fModifierEditor.setEnabled(enabled);
436 fModifierEditor.setText(fHoverConfigs[i].fModifierString);
437 String description = getContributedHovers()[i].getDescription();
438 if (description == null)
439 description = ""; //$NON-NLS-1$
440 fDescription.setText(description);
443 IStatus getStatus() {
445 fStatus = new StatusInfo();
449 private void updateStatus() {
451 HashMap stateMasks = new HashMap(fHoverConfigs.length);
452 while (fStatus.isOK() && i < fHoverConfigs.length) {
453 if (fHoverConfigs[i].fIsEnabled) {
454 String label = getContributedHovers()[i].getLabel();
455 Integer stateMask = new Integer(fHoverConfigs[i].fStateMask);
456 if (fHoverConfigs[i].fStateMask == -1)
457 fStatus = new StatusInfo(
461 "JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] { fHoverConfigs[i].fModifierString, label })); //$NON-NLS-1$
462 else if (stateMasks.containsKey(stateMask))
463 fStatus = new StatusInfo(
467 "JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] { label, (String) stateMasks.get(stateMask) })); //$NON-NLS-1$
469 stateMasks.put(stateMask, label);
475 fMainPreferencePage.updateStatus(fStatus);
477 fMainPreferencePage.setValid(false);
478 StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);