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.ui.WebUI;
23 //import net.sourceforge.phpeclipse.PHPeclipsePlugin;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.jface.action.Action;
27 import org.eclipse.jface.dialogs.Dialog;
28 import org.eclipse.jface.preference.IPreferenceStore;
30 //import org.eclipse.jface.text.Assert;
31 import org.eclipse.core.runtime.Assert;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.KeyEvent;
34 import org.eclipse.swt.events.KeyListener;
35 import org.eclipse.swt.events.ModifyEvent;
36 import org.eclipse.swt.events.ModifyListener;
37 import org.eclipse.swt.events.SelectionEvent;
38 import org.eclipse.swt.events.SelectionListener;
39 import org.eclipse.swt.graphics.Point;
40 import org.eclipse.swt.layout.GridData;
41 import org.eclipse.swt.layout.GridLayout;
42 import org.eclipse.swt.widgets.Button;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Control;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.List;
47 import org.eclipse.swt.widgets.Text;
50 * Configures Java Editor hover preferences.
54 class JavaEditorHoverConfigurationBlock {
56 private static final String DELIMITER = PreferencesMessages
57 .getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
59 // Data structure to hold the values which are edited by the user
60 private static class HoverConfig {
62 private String fModifierString;
64 private boolean fIsEnabled;
66 private int fStateMask;
68 private HoverConfig(String modifier, int stateMask, boolean enabled) {
69 fModifierString = modifier;
71 fStateMask = stateMask;
75 private IPreferenceStore fStore;
77 private HoverConfig[] fHoverConfigs;
79 private Text fModifierEditor;
81 private Button fEnableField;
83 private List fHoverList;
85 private Text fDescription;
87 private Button fShowHoverAffordanceCheckbox;
89 private JavaEditorPreferencePage fMainPreferencePage;
91 private StatusInfo fStatus;
93 public JavaEditorHoverConfigurationBlock(
94 JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
95 Assert.isNotNull(mainPreferencePage);
96 Assert.isNotNull(store);
97 fMainPreferencePage = mainPreferencePage;
102 * Creates page for hover preferences.
104 public Control createControl(Composite parent) {
106 PixelConverter pixelConverter = new PixelConverter(parent);
108 Composite hoverComposite = new Composite(parent, SWT.NULL);
109 GridLayout layout = new GridLayout();
110 layout.numColumns = 2;
111 hoverComposite.setLayout(layout);
112 GridData gd = new GridData(GridData.GRAB_HORIZONTAL
113 | GridData.VERTICAL_ALIGN_FILL);
114 hoverComposite.setLayoutData(gd);
116 Label label = new Label(hoverComposite, SWT.NONE);
118 .setText(PreferencesMessages
119 .getString("JavaEditorHoverConfigurationBlock.hoverPreferences")); //$NON-NLS-1$
120 gd = new GridData(GridData.FILL_HORIZONTAL);
121 gd.horizontalAlignment = GridData.BEGINNING;
122 gd.horizontalSpan = 2;
123 label.setLayoutData(gd);
124 gd = new GridData(GridData.GRAB_HORIZONTAL
125 | GridData.VERTICAL_ALIGN_FILL);
128 fHoverList = new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL
130 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
131 | GridData.FILL_HORIZONTAL);
132 int listHeight = 10 * fHoverList.getItemHeight();
133 gd.heightHint = listHeight;
134 fHoverList.setLayoutData(gd);
135 fHoverList.addSelectionListener(new SelectionListener() {
136 public void widgetSelected(SelectionEvent e) {
137 handleHoverListSelection();
140 public void widgetDefaultSelected(SelectionEvent e) {
144 Composite stylesComposite = new Composite(hoverComposite, SWT.NONE);
145 layout = new GridLayout();
146 layout.marginHeight = 0;
147 layout.marginWidth = 0;
148 layout.numColumns = 2;
149 stylesComposite.setLayout(layout);
150 gd = new GridData(GridData.FILL_HORIZONTAL);
151 gd.heightHint = listHeight + (2 * fHoverList.getBorderWidth());
152 stylesComposite.setLayoutData(gd);
155 fEnableField = new Button(stylesComposite, SWT.CHECK);
156 fEnableField.setText(PreferencesMessages
157 .getString("JavaEditorHoverConfigurationBlock.enabled")); //$NON-NLS-1$
158 gd = new GridData(GridData.FILL_HORIZONTAL);
159 gd.horizontalAlignment = GridData.BEGINNING;
160 gd.horizontalSpan = 2;
161 fEnableField.setLayoutData(gd);
162 fEnableField.addSelectionListener(new SelectionListener() {
163 public void widgetSelected(SelectionEvent e) {
164 int i = fHoverList.getSelectionIndex();
165 boolean state = fEnableField.getSelection();
166 fModifierEditor.setEnabled(state);
167 fHoverConfigs[i].fIsEnabled = state;
168 handleModifierModified();
171 public void widgetDefaultSelected(SelectionEvent e) {
175 // Text field for modifier string
176 label = new Label(stylesComposite, SWT.LEFT);
177 label.setText(PreferencesMessages
178 .getString("JavaEditorHoverConfigurationBlock.keyModifier")); //$NON-NLS-1$
179 fModifierEditor = new Text(stylesComposite, SWT.BORDER);
180 gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
181 fModifierEditor.setLayoutData(gd);
183 fModifierEditor.addKeyListener(new KeyListener() {
184 private boolean isModifierCandidate;
186 public void keyPressed(KeyEvent e) {
187 isModifierCandidate = e.keyCode > 0 && e.character == 0
191 public void keyReleased(KeyEvent e) {
192 if (isModifierCandidate && e.stateMask > 0
193 && e.stateMask == e.stateMask && e.character == 0) {// &&
199 String text = fModifierEditor.getText();
200 Point selection = fModifierEditor.getSelection();
201 int i = selection.x - 1;
202 while (i > -1 && Character.isWhitespace(text.charAt(i))) {
205 boolean needsPrefixDelimiter = i > -1
206 && !String.valueOf(text.charAt(i))
210 while (i < text.length()
211 && Character.isWhitespace(text.charAt(i))) {
214 boolean needsPostfixDelimiter = i < text.length()
215 && !String.valueOf(text.charAt(i))
220 if (needsPrefixDelimiter && needsPostfixDelimiter)
221 insertString = PreferencesMessages
223 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
224 else if (needsPrefixDelimiter)
225 insertString = PreferencesMessages
227 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
228 else if (needsPostfixDelimiter)
229 insertString = PreferencesMessages
231 "JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
233 insertString = Action.findModifierString(e.stateMask);
235 if (insertString != null)
236 fModifierEditor.insert(insertString);
241 fModifierEditor.addModifyListener(new ModifyListener() {
242 public void modifyText(ModifyEvent e) {
243 handleModifierModified();
248 Label descriptionLabel = new Label(stylesComposite, SWT.LEFT);
249 descriptionLabel.setText(PreferencesMessages
250 .getString("JavaEditorHoverConfigurationBlock.description")); //$NON-NLS-1$
251 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
252 gd.horizontalSpan = 2;
253 descriptionLabel.setLayoutData(gd);
254 fDescription = new Text(stylesComposite, SWT.LEFT | SWT.WRAP
255 | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
256 gd = new GridData(GridData.FILL_BOTH);
257 gd.horizontalSpan = 2;
258 fDescription.setLayoutData(gd);
261 Label filler = new Label(hoverComposite, SWT.LEFT);
262 gd = new GridData(GridData.BEGINNING | GridData.VERTICAL_ALIGN_FILL);
263 gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 3;
264 filler.setLayoutData(gd);
266 // Affordance checkbox
267 fShowHoverAffordanceCheckbox = new Button(hoverComposite, SWT.CHECK);
268 fShowHoverAffordanceCheckbox.setText(PreferencesMessages
269 .getString("JavaEditorHoverConfigurationBlock.showAffordance")); //$NON-NLS-1$
270 gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
271 gd.horizontalIndent = 0;
272 gd.horizontalSpan = 2;
273 fShowHoverAffordanceCheckbox.setLayoutData(gd);
277 Dialog.applyDialogFont(hoverComposite);
278 return hoverComposite;
281 private JavaEditorTextHoverDescriptor[] getContributedHovers() {
282 return WebUI.getDefault()
283 .getJavaEditorTextHoverDescriptors();
287 JavaEditorTextHoverDescriptor[] hoverDescs = getContributedHovers();
288 fHoverConfigs = new HoverConfig[hoverDescs.length];
289 for (int i = 0; i < hoverDescs.length; i++) {
290 fHoverConfigs[i] = new HoverConfig(hoverDescs[i]
291 .getModifierString(), hoverDescs[i].getStateMask(),
292 hoverDescs[i].isEnabled());
293 fHoverList.add(hoverDescs[i].getLabel());
298 void initializeFields() {
299 fHoverList.getDisplay().asyncExec(new Runnable() {
301 if (fHoverList != null && !fHoverList.isDisposed()) {
302 fHoverList.select(0);
303 handleHoverListSelection();
307 fShowHoverAffordanceCheckbox
309 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
313 StringBuffer buf = new StringBuffer();
314 StringBuffer maskBuf = new StringBuffer();
315 for (int i = 0; i < fHoverConfigs.length; i++) {
316 buf.append(getContributedHovers()[i].getId());
317 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
318 if (!fHoverConfigs[i].fIsEnabled)
319 buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG);
320 String modifier = fHoverConfigs[i].fModifierString;
321 if (modifier == null || modifier.length() == 0)
322 modifier = JavaEditorTextHoverDescriptor.NO_MODIFIER;
323 buf.append(modifier);
324 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
326 maskBuf.append(getContributedHovers()[i].getId());
327 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
328 maskBuf.append(fHoverConfigs[i].fStateMask);
329 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
331 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf
333 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
336 fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
337 fShowHoverAffordanceCheckbox.getSelection());
339 WebUI.getDefault().resetJavaEditorTextHoverDescriptors();
342 void performDefaults() {
343 restoreFromPreferences();
347 private void restoreFromPreferences() {
349 fShowHoverAffordanceCheckbox
351 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
353 String compiledTextHoverModifiers = fStore
354 .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
356 StringTokenizer tokenizer = new StringTokenizer(
357 compiledTextHoverModifiers,
358 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
359 HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
361 while (tokenizer.hasMoreTokens()) {
362 String id = tokenizer.nextToken();
363 if (tokenizer.hasMoreTokens())
364 idToModifier.put(id, tokenizer.nextToken());
367 String compiledTextHoverModifierMasks = WebUI.getDefault()
368 .getPreferenceStore().getString(
369 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
371 tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
372 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
373 HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
375 while (tokenizer.hasMoreTokens()) {
376 String id = tokenizer.nextToken();
377 if (tokenizer.hasMoreTokens())
378 idToModifierMask.put(id, tokenizer.nextToken());
381 for (int i = 0; i < fHoverConfigs.length; i++) {
382 String modifierString = (String) idToModifier
383 .get(getContributedHovers()[i].getId());
384 boolean enabled = true;
385 if (modifierString == null)
386 modifierString = JavaEditorTextHoverDescriptor.DISABLED_TAG;
389 .startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
391 modifierString = modifierString.substring(1);
395 .equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
396 modifierString = ""; //$NON-NLS-1$
398 fHoverConfigs[i].fModifierString = modifierString;
399 fHoverConfigs[i].fIsEnabled = enabled;
400 fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
401 .computeStateMask(modifierString);
403 if (fHoverConfigs[i].fStateMask == -1) {
405 fHoverConfigs[i].fStateMask = Integer
406 .parseInt((String) idToModifierMask
407 .get(getContributedHovers()[i].getId()));
408 } catch (NumberFormatException ex) {
409 fHoverConfigs[i].fStateMask = -1;
415 private void handleModifierModified() {
416 int i = fHoverList.getSelectionIndex();
417 String modifiers = fModifierEditor.getText();
418 fHoverConfigs[i].fModifierString = modifiers;
419 fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
420 .computeStateMask(modifiers);
421 if (fHoverConfigs[i].fIsEnabled && fHoverConfigs[i].fStateMask == -1)
422 fStatus = new StatusInfo(
426 "JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
428 fStatus = new StatusInfo();
432 private void handleHoverListSelection() {
433 int i = fHoverList.getSelectionIndex();
434 boolean enabled = fHoverConfigs[i].fIsEnabled;
435 fEnableField.setSelection(enabled);
436 fModifierEditor.setEnabled(enabled);
437 fModifierEditor.setText(fHoverConfigs[i].fModifierString);
438 String description = getContributedHovers()[i].getDescription();
439 if (description == null)
440 description = ""; //$NON-NLS-1$
441 fDescription.setText(description);
444 IStatus getStatus() {
446 fStatus = new StatusInfo();
450 private void updateStatus() {
452 HashMap stateMasks = new HashMap(fHoverConfigs.length);
453 while (fStatus.isOK() && i < fHoverConfigs.length) {
454 if (fHoverConfigs[i].fIsEnabled) {
455 String label = getContributedHovers()[i].getLabel();
456 Integer stateMask = new Integer(fHoverConfigs[i].fStateMask);
457 if (fHoverConfigs[i].fStateMask == -1)
458 fStatus = new StatusInfo(
462 "JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] { fHoverConfigs[i].fModifierString, label })); //$NON-NLS-1$
463 else if (stateMasks.containsKey(stateMask))
464 fStatus = new StatusInfo(
468 "JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] { label, (String) stateMasks.get(stateMask) })); //$NON-NLS-1$
470 stateMasks.put(stateMask, label);
476 fMainPreferencePage.updateStatus(fStatus);
478 fMainPreferencePage.setValid(false);
479 StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);