1) Moved net.sourceforge.phpeclipse.ui\src\net\sourceforge\phpdt back to net.sourcefo...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / preferences / JavaEditorHoverConfigurationBlock.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.internal.ui.preferences;
13
14 import java.util.HashMap;
15 import java.util.StringTokenizer;
16
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;
23
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 //incastrix
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;
47
48 /**
49  * Configures Java Editor hover preferences.
50  * 
51  * @since 2.1
52  */
53 class JavaEditorHoverConfigurationBlock {
54
55         private static final String DELIMITER = PreferencesMessages
56                         .getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
57
58         // Data structure to hold the values which are edited by the user
59         private static class HoverConfig {
60
61                 private String fModifierString;
62
63                 private boolean fIsEnabled;
64
65                 private int fStateMask;
66
67                 private HoverConfig(String modifier, int stateMask, boolean enabled) {
68                         fModifierString = modifier;
69                         fIsEnabled = enabled;
70                         fStateMask = stateMask;
71                 }
72         }
73
74         private IPreferenceStore fStore;
75
76         private HoverConfig[] fHoverConfigs;
77
78         private Text fModifierEditor;
79
80         private Button fEnableField;
81
82         private List fHoverList;
83
84         private Text fDescription;
85
86         private Button fShowHoverAffordanceCheckbox;
87
88         private JavaEditorPreferencePage fMainPreferencePage;
89
90         private StatusInfo fStatus;
91
92         public JavaEditorHoverConfigurationBlock(
93                         JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
94                 Assert.isNotNull(mainPreferencePage);
95                 Assert.isNotNull(store);
96                 fMainPreferencePage = mainPreferencePage;
97                 fStore = store;
98         }
99
100         /**
101          * Creates page for hover preferences.
102          */
103         public Control createControl(Composite parent) {
104
105                 PixelConverter pixelConverter = new PixelConverter(parent);
106
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);
114
115                 Label label = new Label(hoverComposite, SWT.NONE);
116                 label
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);
125
126                 // Hover list
127                 fHoverList = new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL
128                                 | SWT.BORDER);
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();
137                         }
138
139                         public void widgetDefaultSelected(SelectionEvent e) {
140                         }
141                 });
142
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);
152
153                 // Enabled checkbox
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();
168                         }
169
170                         public void widgetDefaultSelected(SelectionEvent e) {
171                         }
172                 });
173
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);
181
182                 fModifierEditor.addKeyListener(new KeyListener() {
183                         private boolean isModifierCandidate;
184
185                         public void keyPressed(KeyEvent e) {
186                                 isModifierCandidate = e.keyCode > 0 && e.character == 0
187                                                 && e.stateMask == 0;
188                         }
189
190                         public void keyReleased(KeyEvent e) {
191                                 if (isModifierCandidate && e.stateMask > 0
192                                                 && e.stateMask == e.stateMask && e.character == 0) {// &&
193                                                                                                                                                         // e.time
194                                                                                                                                                         // -time
195                                                                                                                                                         // <
196                                                                                                                                                         // 1000)
197                                                                                                                                                         // {
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))) {
202                                                 i--;
203                                         }
204                                         boolean needsPrefixDelimiter = i > -1
205                                                         && !String.valueOf(text.charAt(i))
206                                                                         .equals(DELIMITER);
207
208                                         i = selection.y;
209                                         while (i < text.length()
210                                                         && Character.isWhitespace(text.charAt(i))) {
211                                                 i++;
212                                         }
213                                         boolean needsPostfixDelimiter = i < text.length()
214                                                         && !String.valueOf(text.charAt(i))
215                                                                         .equals(DELIMITER);
216
217                                         String insertString;
218
219                                         if (needsPrefixDelimiter && needsPostfixDelimiter)
220                                                 insertString = PreferencesMessages
221                                                                 .getFormattedString(
222                                                                                 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
223                                         else if (needsPrefixDelimiter)
224                                                 insertString = PreferencesMessages
225                                                                 .getFormattedString(
226                                                                                 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
227                                         else if (needsPostfixDelimiter)
228                                                 insertString = PreferencesMessages
229                                                                 .getFormattedString(
230                                                                                 "JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
231                                         else
232                                                 insertString = Action.findModifierString(e.stateMask);
233
234                                         if (insertString != null)
235                                                 fModifierEditor.insert(insertString);
236                                 }
237                         }
238                 });
239
240                 fModifierEditor.addModifyListener(new ModifyListener() {
241                         public void modifyText(ModifyEvent e) {
242                                 handleModifierModified();
243                         }
244                 });
245
246                 // Description
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);
258
259                 // Vertical filler
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);
264
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);
273
274                 initialize();
275
276                 Dialog.applyDialogFont(hoverComposite);
277                 return hoverComposite;
278         }
279
280         private JavaEditorTextHoverDescriptor[] getContributedHovers() {
281                 return PHPeclipsePlugin.getDefault()
282                                 .getJavaEditorTextHoverDescriptors();
283         }
284
285         void initialize() {
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());
293                 }
294                 initializeFields();
295         }
296
297         void initializeFields() {
298                 fHoverList.getDisplay().asyncExec(new Runnable() {
299                         public void run() {
300                                 if (fHoverList != null && !fHoverList.isDisposed()) {
301                                         fHoverList.select(0);
302                                         handleHoverListSelection();
303                                 }
304                         }
305                 });
306                 fShowHoverAffordanceCheckbox
307                                 .setSelection(fStore
308                                                 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
309         }
310
311         void performOk() {
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);
324
325                         maskBuf.append(getContributedHovers()[i].getId());
326                         maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
327                         maskBuf.append(fHoverConfigs[i].fStateMask);
328                         maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
329                 }
330                 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf
331                                 .toString());
332                 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
333                                 maskBuf.toString());
334
335                 fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
336                                 fShowHoverAffordanceCheckbox.getSelection());
337
338                 PHPeclipsePlugin.getDefault().resetJavaEditorTextHoverDescriptors();
339         }
340
341         void performDefaults() {
342                 restoreFromPreferences();
343                 initializeFields();
344         }
345
346         private void restoreFromPreferences() {
347
348                 fShowHoverAffordanceCheckbox
349                                 .setSelection(fStore
350                                                 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
351
352                 String compiledTextHoverModifiers = fStore
353                                 .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
354
355                 StringTokenizer tokenizer = new StringTokenizer(
356                                 compiledTextHoverModifiers,
357                                 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
358                 HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
359
360                 while (tokenizer.hasMoreTokens()) {
361                         String id = tokenizer.nextToken();
362                         if (tokenizer.hasMoreTokens())
363                                 idToModifier.put(id, tokenizer.nextToken());
364                 }
365
366                 String compiledTextHoverModifierMasks = PHPeclipsePlugin.getDefault()
367                                 .getPreferenceStore().getString(
368                                                 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
369
370                 tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
371                                 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
372                 HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
373
374                 while (tokenizer.hasMoreTokens()) {
375                         String id = tokenizer.nextToken();
376                         if (tokenizer.hasMoreTokens())
377                                 idToModifierMask.put(id, tokenizer.nextToken());
378                 }
379
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;
386
387                         if (modifierString
388                                         .startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
389                                 enabled = false;
390                                 modifierString = modifierString.substring(1);
391                         }
392
393                         if (modifierString
394                                         .equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
395                                 modifierString = ""; //$NON-NLS-1$
396
397                         fHoverConfigs[i].fModifierString = modifierString;
398                         fHoverConfigs[i].fIsEnabled = enabled;
399                         fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
400                                         .computeStateMask(modifierString);
401
402                         if (fHoverConfigs[i].fStateMask == -1) {
403                                 try {
404                                         fHoverConfigs[i].fStateMask = Integer
405                                                         .parseInt((String) idToModifierMask
406                                                                         .get(getContributedHovers()[i].getId()));
407                                 } catch (NumberFormatException ex) {
408                                         fHoverConfigs[i].fStateMask = -1;
409                                 }
410                         }
411                 }
412         }
413
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(
422                                         IStatus.ERROR,
423                                         PreferencesMessages
424                                                         .getFormattedString(
425                                                                         "JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
426                 else
427                         fStatus = new StatusInfo();
428                 updateStatus();
429         }
430
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);
441         }
442
443         IStatus getStatus() {
444                 if (fStatus == null)
445                         fStatus = new StatusInfo();
446                 return fStatus;
447         }
448
449         private void updateStatus() {
450                 int i = 0;
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(
458                                                         IStatus.ERROR,
459                                                         PreferencesMessages
460                                                                         .getFormattedString(
461                                                                                         "JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] { fHoverConfigs[i].fModifierString, label })); //$NON-NLS-1$
462                                 else if (stateMasks.containsKey(stateMask))
463                                         fStatus = new StatusInfo(
464                                                         IStatus.ERROR,
465                                                         PreferencesMessages
466                                                                         .getFormattedString(
467                                                                                         "JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] { label, (String) stateMasks.get(stateMask) })); //$NON-NLS-1$
468                                 else
469                                         stateMasks.put(stateMask, label);
470                         }
471                         i++;
472                 }
473
474                 if (fStatus.isOK())
475                         fMainPreferencePage.updateStatus(fStatus);
476                 else {
477                         fMainPreferencePage.setValid(false);
478                         StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);
479                 }
480         }
481 }