A massive organize imports and formatting of the sources using default Eclipse code...
[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 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;
45
46 /**
47  * Configures Java Editor hover preferences.
48  * 
49  * @since 2.1
50  */
51 class JavaEditorHoverConfigurationBlock {
52
53         private static final String DELIMITER = PreferencesMessages
54                         .getString("JavaEditorHoverConfigurationBlock.delimiter"); //$NON-NLS-1$
55
56         // Data structure to hold the values which are edited by the user
57         private static class HoverConfig {
58
59                 private String fModifierString;
60
61                 private boolean fIsEnabled;
62
63                 private int fStateMask;
64
65                 private HoverConfig(String modifier, int stateMask, boolean enabled) {
66                         fModifierString = modifier;
67                         fIsEnabled = enabled;
68                         fStateMask = stateMask;
69                 }
70         }
71
72         private IPreferenceStore fStore;
73
74         private HoverConfig[] fHoverConfigs;
75
76         private Text fModifierEditor;
77
78         private Button fEnableField;
79
80         private List fHoverList;
81
82         private Text fDescription;
83
84         private Button fShowHoverAffordanceCheckbox;
85
86         private JavaEditorPreferencePage fMainPreferencePage;
87
88         private StatusInfo fStatus;
89
90         public JavaEditorHoverConfigurationBlock(
91                         JavaEditorPreferencePage mainPreferencePage, IPreferenceStore store) {
92                 Assert.isNotNull(mainPreferencePage);
93                 Assert.isNotNull(store);
94                 fMainPreferencePage = mainPreferencePage;
95                 fStore = store;
96         }
97
98         /**
99          * Creates page for hover preferences.
100          */
101         public Control createControl(Composite parent) {
102
103                 PixelConverter pixelConverter = new PixelConverter(parent);
104
105                 Composite hoverComposite = new Composite(parent, SWT.NULL);
106                 GridLayout layout = new GridLayout();
107                 layout.numColumns = 2;
108                 hoverComposite.setLayout(layout);
109                 GridData gd = new GridData(GridData.GRAB_HORIZONTAL
110                                 | GridData.VERTICAL_ALIGN_FILL);
111                 hoverComposite.setLayoutData(gd);
112
113                 Label label = new Label(hoverComposite, SWT.NONE);
114                 label
115                                 .setText(PreferencesMessages
116                                                 .getString("JavaEditorHoverConfigurationBlock.hoverPreferences")); //$NON-NLS-1$
117                 gd = new GridData(GridData.FILL_HORIZONTAL);
118                 gd.horizontalAlignment = GridData.BEGINNING;
119                 gd.horizontalSpan = 2;
120                 label.setLayoutData(gd);
121                 gd = new GridData(GridData.GRAB_HORIZONTAL
122                                 | GridData.VERTICAL_ALIGN_FILL);
123
124                 // Hover list
125                 fHoverList = new List(hoverComposite, SWT.SINGLE | SWT.V_SCROLL
126                                 | SWT.BORDER);
127                 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING
128                                 | GridData.FILL_HORIZONTAL);
129                 int listHeight = 10 * fHoverList.getItemHeight();
130                 gd.heightHint = listHeight;
131                 fHoverList.setLayoutData(gd);
132                 fHoverList.addSelectionListener(new SelectionListener() {
133                         public void widgetSelected(SelectionEvent e) {
134                                 handleHoverListSelection();
135                         }
136
137                         public void widgetDefaultSelected(SelectionEvent e) {
138                         }
139                 });
140
141                 Composite stylesComposite = new Composite(hoverComposite, SWT.NONE);
142                 layout = new GridLayout();
143                 layout.marginHeight = 0;
144                 layout.marginWidth = 0;
145                 layout.numColumns = 2;
146                 stylesComposite.setLayout(layout);
147                 gd = new GridData(GridData.FILL_HORIZONTAL);
148                 gd.heightHint = listHeight + (2 * fHoverList.getBorderWidth());
149                 stylesComposite.setLayoutData(gd);
150
151                 // Enabled checkbox
152                 fEnableField = new Button(stylesComposite, SWT.CHECK);
153                 fEnableField.setText(PreferencesMessages
154                                 .getString("JavaEditorHoverConfigurationBlock.enabled")); //$NON-NLS-1$
155                 gd = new GridData(GridData.FILL_HORIZONTAL);
156                 gd.horizontalAlignment = GridData.BEGINNING;
157                 gd.horizontalSpan = 2;
158                 fEnableField.setLayoutData(gd);
159                 fEnableField.addSelectionListener(new SelectionListener() {
160                         public void widgetSelected(SelectionEvent e) {
161                                 int i = fHoverList.getSelectionIndex();
162                                 boolean state = fEnableField.getSelection();
163                                 fModifierEditor.setEnabled(state);
164                                 fHoverConfigs[i].fIsEnabled = state;
165                                 handleModifierModified();
166                         }
167
168                         public void widgetDefaultSelected(SelectionEvent e) {
169                         }
170                 });
171
172                 // Text field for modifier string
173                 label = new Label(stylesComposite, SWT.LEFT);
174                 label.setText(PreferencesMessages
175                                 .getString("JavaEditorHoverConfigurationBlock.keyModifier")); //$NON-NLS-1$
176                 fModifierEditor = new Text(stylesComposite, SWT.BORDER);
177                 gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
178                 fModifierEditor.setLayoutData(gd);
179
180                 fModifierEditor.addKeyListener(new KeyListener() {
181                         private boolean isModifierCandidate;
182
183                         public void keyPressed(KeyEvent e) {
184                                 isModifierCandidate = e.keyCode > 0 && e.character == 0
185                                                 && e.stateMask == 0;
186                         }
187
188                         public void keyReleased(KeyEvent e) {
189                                 if (isModifierCandidate && e.stateMask > 0
190                                                 && e.stateMask == e.stateMask && e.character == 0) {// &&
191                                                                                                                                                         // e.time
192                                                                                                                                                         // -time
193                                                                                                                                                         // <
194                                                                                                                                                         // 1000)
195                                                                                                                                                         // {
196                                         String text = fModifierEditor.getText();
197                                         Point selection = fModifierEditor.getSelection();
198                                         int i = selection.x - 1;
199                                         while (i > -1 && Character.isWhitespace(text.charAt(i))) {
200                                                 i--;
201                                         }
202                                         boolean needsPrefixDelimiter = i > -1
203                                                         && !String.valueOf(text.charAt(i))
204                                                                         .equals(DELIMITER);
205
206                                         i = selection.y;
207                                         while (i < text.length()
208                                                         && Character.isWhitespace(text.charAt(i))) {
209                                                 i++;
210                                         }
211                                         boolean needsPostfixDelimiter = i < text.length()
212                                                         && !String.valueOf(text.charAt(i))
213                                                                         .equals(DELIMITER);
214
215                                         String insertString;
216
217                                         if (needsPrefixDelimiter && needsPostfixDelimiter)
218                                                 insertString = PreferencesMessages
219                                                                 .getFormattedString(
220                                                                                 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
221                                         else if (needsPrefixDelimiter)
222                                                 insertString = PreferencesMessages
223                                                                 .getFormattedString(
224                                                                                 "JavaEditorHoverConfigurationBlock.insertDelimiterAndModifier", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
225                                         else if (needsPostfixDelimiter)
226                                                 insertString = PreferencesMessages
227                                                                 .getFormattedString(
228                                                                                 "JavaEditorHoverConfigurationBlock.insertModifierAndDelimiter", new String[] { Action.findModifierString(e.stateMask) }); //$NON-NLS-1$
229                                         else
230                                                 insertString = Action.findModifierString(e.stateMask);
231
232                                         if (insertString != null)
233                                                 fModifierEditor.insert(insertString);
234                                 }
235                         }
236                 });
237
238                 fModifierEditor.addModifyListener(new ModifyListener() {
239                         public void modifyText(ModifyEvent e) {
240                                 handleModifierModified();
241                         }
242                 });
243
244                 // Description
245                 Label descriptionLabel = new Label(stylesComposite, SWT.LEFT);
246                 descriptionLabel.setText(PreferencesMessages
247                                 .getString("JavaEditorHoverConfigurationBlock.description")); //$NON-NLS-1$
248                 gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
249                 gd.horizontalSpan = 2;
250                 descriptionLabel.setLayoutData(gd);
251                 fDescription = new Text(stylesComposite, SWT.LEFT | SWT.WRAP
252                                 | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER);
253                 gd = new GridData(GridData.FILL_BOTH);
254                 gd.horizontalSpan = 2;
255                 fDescription.setLayoutData(gd);
256
257                 // Vertical filler
258                 Label filler = new Label(hoverComposite, SWT.LEFT);
259                 gd = new GridData(GridData.BEGINNING | GridData.VERTICAL_ALIGN_FILL);
260                 gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 3;
261                 filler.setLayoutData(gd);
262
263                 // Affordance checkbox
264                 fShowHoverAffordanceCheckbox = new Button(hoverComposite, SWT.CHECK);
265                 fShowHoverAffordanceCheckbox.setText(PreferencesMessages
266                                 .getString("JavaEditorHoverConfigurationBlock.showAffordance")); //$NON-NLS-1$
267                 gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
268                 gd.horizontalIndent = 0;
269                 gd.horizontalSpan = 2;
270                 fShowHoverAffordanceCheckbox.setLayoutData(gd);
271
272                 initialize();
273
274                 Dialog.applyDialogFont(hoverComposite);
275                 return hoverComposite;
276         }
277
278         private JavaEditorTextHoverDescriptor[] getContributedHovers() {
279                 return PHPeclipsePlugin.getDefault()
280                                 .getJavaEditorTextHoverDescriptors();
281         }
282
283         void initialize() {
284                 JavaEditorTextHoverDescriptor[] hoverDescs = getContributedHovers();
285                 fHoverConfigs = new HoverConfig[hoverDescs.length];
286                 for (int i = 0; i < hoverDescs.length; i++) {
287                         fHoverConfigs[i] = new HoverConfig(hoverDescs[i]
288                                         .getModifierString(), hoverDescs[i].getStateMask(),
289                                         hoverDescs[i].isEnabled());
290                         fHoverList.add(hoverDescs[i].getLabel());
291                 }
292                 initializeFields();
293         }
294
295         void initializeFields() {
296                 fHoverList.getDisplay().asyncExec(new Runnable() {
297                         public void run() {
298                                 if (fHoverList != null && !fHoverList.isDisposed()) {
299                                         fHoverList.select(0);
300                                         handleHoverListSelection();
301                                 }
302                         }
303                 });
304                 fShowHoverAffordanceCheckbox
305                                 .setSelection(fStore
306                                                 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
307         }
308
309         void performOk() {
310                 StringBuffer buf = new StringBuffer();
311                 StringBuffer maskBuf = new StringBuffer();
312                 for (int i = 0; i < fHoverConfigs.length; i++) {
313                         buf.append(getContributedHovers()[i].getId());
314                         buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
315                         if (!fHoverConfigs[i].fIsEnabled)
316                                 buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG);
317                         String modifier = fHoverConfigs[i].fModifierString;
318                         if (modifier == null || modifier.length() == 0)
319                                 modifier = JavaEditorTextHoverDescriptor.NO_MODIFIER;
320                         buf.append(modifier);
321                         buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
322
323                         maskBuf.append(getContributedHovers()[i].getId());
324                         maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
325                         maskBuf.append(fHoverConfigs[i].fStateMask);
326                         maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
327                 }
328                 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf
329                                 .toString());
330                 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS,
331                                 maskBuf.toString());
332
333                 fStore.setValue(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE,
334                                 fShowHoverAffordanceCheckbox.getSelection());
335
336                 PHPeclipsePlugin.getDefault().resetJavaEditorTextHoverDescriptors();
337         }
338
339         void performDefaults() {
340                 restoreFromPreferences();
341                 initializeFields();
342         }
343
344         private void restoreFromPreferences() {
345
346                 fShowHoverAffordanceCheckbox
347                                 .setSelection(fStore
348                                                 .getBoolean(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE));
349
350                 String compiledTextHoverModifiers = fStore
351                                 .getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS);
352
353                 StringTokenizer tokenizer = new StringTokenizer(
354                                 compiledTextHoverModifiers,
355                                 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
356                 HashMap idToModifier = new HashMap(tokenizer.countTokens() / 2);
357
358                 while (tokenizer.hasMoreTokens()) {
359                         String id = tokenizer.nextToken();
360                         if (tokenizer.hasMoreTokens())
361                                 idToModifier.put(id, tokenizer.nextToken());
362                 }
363
364                 String compiledTextHoverModifierMasks = PHPeclipsePlugin.getDefault()
365                                 .getPreferenceStore().getString(
366                                                 PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS);
367
368                 tokenizer = new StringTokenizer(compiledTextHoverModifierMasks,
369                                 JavaEditorTextHoverDescriptor.VALUE_SEPARATOR);
370                 HashMap idToModifierMask = new HashMap(tokenizer.countTokens() / 2);
371
372                 while (tokenizer.hasMoreTokens()) {
373                         String id = tokenizer.nextToken();
374                         if (tokenizer.hasMoreTokens())
375                                 idToModifierMask.put(id, tokenizer.nextToken());
376                 }
377
378                 for (int i = 0; i < fHoverConfigs.length; i++) {
379                         String modifierString = (String) idToModifier
380                                         .get(getContributedHovers()[i].getId());
381                         boolean enabled = true;
382                         if (modifierString == null)
383                                 modifierString = JavaEditorTextHoverDescriptor.DISABLED_TAG;
384
385                         if (modifierString
386                                         .startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) {
387                                 enabled = false;
388                                 modifierString = modifierString.substring(1);
389                         }
390
391                         if (modifierString
392                                         .equals(JavaEditorTextHoverDescriptor.NO_MODIFIER))
393                                 modifierString = ""; //$NON-NLS-1$
394
395                         fHoverConfigs[i].fModifierString = modifierString;
396                         fHoverConfigs[i].fIsEnabled = enabled;
397                         fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
398                                         .computeStateMask(modifierString);
399
400                         if (fHoverConfigs[i].fStateMask == -1) {
401                                 try {
402                                         fHoverConfigs[i].fStateMask = Integer
403                                                         .parseInt((String) idToModifierMask
404                                                                         .get(getContributedHovers()[i].getId()));
405                                 } catch (NumberFormatException ex) {
406                                         fHoverConfigs[i].fStateMask = -1;
407                                 }
408                         }
409                 }
410         }
411
412         private void handleModifierModified() {
413                 int i = fHoverList.getSelectionIndex();
414                 String modifiers = fModifierEditor.getText();
415                 fHoverConfigs[i].fModifierString = modifiers;
416                 fHoverConfigs[i].fStateMask = JavaEditorTextHoverDescriptor
417                                 .computeStateMask(modifiers);
418                 if (fHoverConfigs[i].fIsEnabled && fHoverConfigs[i].fStateMask == -1)
419                         fStatus = new StatusInfo(
420                                         IStatus.ERROR,
421                                         PreferencesMessages
422                                                         .getFormattedString(
423                                                                         "JavaEditorHoverConfigurationBlock.modifierIsNotValid", fHoverConfigs[i].fModifierString)); //$NON-NLS-1$
424                 else
425                         fStatus = new StatusInfo();
426                 updateStatus();
427         }
428
429         private void handleHoverListSelection() {
430                 int i = fHoverList.getSelectionIndex();
431                 boolean enabled = fHoverConfigs[i].fIsEnabled;
432                 fEnableField.setSelection(enabled);
433                 fModifierEditor.setEnabled(enabled);
434                 fModifierEditor.setText(fHoverConfigs[i].fModifierString);
435                 String description = getContributedHovers()[i].getDescription();
436                 if (description == null)
437                         description = ""; //$NON-NLS-1$
438                 fDescription.setText(description);
439         }
440
441         IStatus getStatus() {
442                 if (fStatus == null)
443                         fStatus = new StatusInfo();
444                 return fStatus;
445         }
446
447         private void updateStatus() {
448                 int i = 0;
449                 HashMap stateMasks = new HashMap(fHoverConfigs.length);
450                 while (fStatus.isOK() && i < fHoverConfigs.length) {
451                         if (fHoverConfigs[i].fIsEnabled) {
452                                 String label = getContributedHovers()[i].getLabel();
453                                 Integer stateMask = new Integer(fHoverConfigs[i].fStateMask);
454                                 if (fHoverConfigs[i].fStateMask == -1)
455                                         fStatus = new StatusInfo(
456                                                         IStatus.ERROR,
457                                                         PreferencesMessages
458                                                                         .getFormattedString(
459                                                                                         "JavaEditorHoverConfigurationBlock.modifierIsNotValidForHover", new String[] { fHoverConfigs[i].fModifierString, label })); //$NON-NLS-1$
460                                 else if (stateMasks.containsKey(stateMask))
461                                         fStatus = new StatusInfo(
462                                                         IStatus.ERROR,
463                                                         PreferencesMessages
464                                                                         .getFormattedString(
465                                                                                         "JavaEditorHoverConfigurationBlock.duplicateModifier", new String[] { label, (String) stateMasks.get(stateMask) })); //$NON-NLS-1$
466                                 else
467                                         stateMasks.put(stateMask, label);
468                         }
469                         i++;
470                 }
471
472                 if (fStatus.isOK())
473                         fMainPreferencePage.updateStatus(fStatus);
474                 else {
475                         fMainPreferencePage.setValid(false);
476                         StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus);
477                 }
478         }
479 }