1 11 12 package org.eclipse.jdt.internal.ui.preferences; 13 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 import java.util.StringTokenizer ; 19 20 import org.eclipse.core.runtime.Assert; 21 import org.eclipse.core.runtime.IStatus; 22 23 import org.eclipse.swt.SWT; 24 import org.eclipse.swt.events.KeyEvent; 25 import org.eclipse.swt.events.KeyListener; 26 import org.eclipse.swt.events.ModifyEvent; 27 import org.eclipse.swt.events.ModifyListener; 28 import org.eclipse.swt.events.SelectionEvent; 29 import org.eclipse.swt.events.SelectionListener; 30 import org.eclipse.swt.graphics.Image; 31 import org.eclipse.swt.graphics.Point; 32 import org.eclipse.swt.layout.GridData; 33 import org.eclipse.swt.layout.GridLayout; 34 import org.eclipse.swt.widgets.Button; 35 import org.eclipse.swt.widgets.Composite; 36 import org.eclipse.swt.widgets.Control; 37 import org.eclipse.swt.widgets.Label; 38 import org.eclipse.swt.widgets.Table; 39 import org.eclipse.swt.widgets.TableColumn; 40 import org.eclipse.swt.widgets.TableItem; 41 import org.eclipse.swt.widgets.Text; 42 43 import org.eclipse.jface.action.Action; 44 import org.eclipse.jface.dialogs.Dialog; 45 import org.eclipse.jface.preference.PreferencePage; 46 import org.eclipse.jface.viewers.CheckStateChangedEvent; 47 import org.eclipse.jface.viewers.CheckboxTableViewer; 48 import org.eclipse.jface.viewers.ColumnWeightData; 49 import org.eclipse.jface.viewers.ICheckStateListener; 50 import org.eclipse.jface.viewers.ILabelProviderListener; 51 import org.eclipse.jface.viewers.IStructuredContentProvider; 52 import org.eclipse.jface.viewers.ITableLabelProvider; 53 import org.eclipse.jface.viewers.StructuredSelection; 54 import org.eclipse.jface.viewers.TableLayout; 55 import org.eclipse.jface.viewers.TableViewer; 56 import org.eclipse.jface.viewers.Viewer; 57 58 59 import org.eclipse.jdt.internal.corext.util.Messages; 60 61 import org.eclipse.jdt.ui.PreferenceConstants; 62 63 import org.eclipse.jdt.internal.ui.JavaPlugin; 64 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; 65 import org.eclipse.jdt.internal.ui.dialogs.StatusUtil; 66 import org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverDescriptor; 67 import org.eclipse.jdt.internal.ui.util.PixelConverter; 68 import org.eclipse.jdt.internal.ui.util.SWTUtil; 69 import org.eclipse.jdt.internal.ui.util.TableLayoutComposite; 70 71 76 class JavaEditorHoverConfigurationBlock implements IPreferenceConfigurationBlock { 77 78 private static final String DELIMITER= PreferencesMessages.JavaEditorHoverConfigurationBlock_delimiter; 79 80 private static final int ENABLED_PROP= 0; 81 private static final int MODIFIER_PROP= 1; 82 83 private static class HoverConfig { 85 86 private String fModifierString; 87 private boolean fIsEnabled; 88 private int fStateMask; 89 90 private HoverConfig(String modifier, int stateMask, boolean enabled) { 91 fModifierString= modifier; 92 fIsEnabled= enabled; 93 fStateMask= stateMask; 94 } 95 } 96 97 98 private class JavaEditorTextHoverDescriptorLabelProvider implements ITableLabelProvider { 99 100 public Image getColumnImage(Object element, int columnIndex) { 101 return null; 102 } 103 104 public String getColumnText(Object element, int columnIndex) { 105 switch (columnIndex) { 106 case ENABLED_PROP: 107 return ((JavaEditorTextHoverDescriptor)element).getLabel(); 108 109 case MODIFIER_PROP: 110 TableItem item= (TableItem)fHoverTableViewer.testFindItem(element); 111 int index= fHoverTable.indexOf(item); 112 return fHoverConfigs[index].fModifierString; 113 114 default: 115 break; 116 } 117 118 return null; 119 } 120 121 public void addListener(ILabelProviderListener listener) { 122 } 123 124 public void dispose() { 125 } 126 127 public boolean isLabelProperty(Object element, String property) { 128 return false; 129 } 130 131 public void removeListener(ILabelProviderListener listener) { 132 } 133 } 134 135 136 private class JavaEditorTextHoverDescriptorContentProvider implements IStructuredContentProvider { 137 138 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 139 } 141 142 public void dispose() { 143 } 144 145 public boolean isDeleted(Object element) { 146 return false; 147 } 148 149 public Object [] getElements(Object element) { 150 return (Object [])element; 151 } 152 } 153 154 155 private OverlayPreferenceStore fStore; 156 private HoverConfig[] fHoverConfigs; 157 private Text fModifierEditor; 158 private Table fHoverTable; 159 private TableViewer fHoverTableViewer; 160 private TableColumn fNameColumn; 161 private TableColumn fModifierColumn; 162 private Text fDescription; 163 164 private PreferencePage fMainPreferencePage; 165 166 private StatusInfo fStatus; 167 168 private Map fCheckBoxes= new HashMap (); 169 private SelectionListener fCheckBoxListener= new SelectionListener() { 170 public void widgetDefaultSelected(SelectionEvent e) { 171 Button button= (Button) e.widget; 172 fStore.setValue((String ) fCheckBoxes.get(button), button.getSelection()); 173 } 174 public void widgetSelected(SelectionEvent e) { 175 Button button= (Button) e.widget; 176 fStore.setValue((String ) fCheckBoxes.get(button), button.getSelection()); 177 } 178 }; 179 180 181 public JavaEditorHoverConfigurationBlock(PreferencePage mainPreferencePage, OverlayPreferenceStore store) { 182 Assert.isNotNull(mainPreferencePage); 183 Assert.isNotNull(store); 184 fMainPreferencePage= mainPreferencePage; 185 fStore= store; 186 fStore.addKeys(createOverlayStoreKeys()); 187 } 188 189 190 private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { 191 192 ArrayList overlayKeys= new ArrayList (); 193 194 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER)); 195 196 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS)); 197 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS)); 198 199 OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; 200 overlayKeys.toArray(keys); 201 return keys; 202 } 203 204 210 public Control createControl(Composite parent) { 211 212 ScrolledPageContent scrolled= new ScrolledPageContent(parent, SWT.H_SCROLL | SWT.V_SCROLL); 213 scrolled.setExpandHorizontal(true); 214 scrolled.setExpandVertical(true); 215 216 217 Composite hoverComposite= new Composite(scrolled, SWT.NONE); 218 GridLayout layout= new GridLayout(); 219 layout.numColumns= 2; 220 layout.marginWidth= 0; 221 layout.marginHeight= 0; 222 hoverComposite.setLayout(layout); 223 224 String rollOverLabel= PreferencesMessages.JavaEditorHoverConfigurationBlock_annotationRollover; 225 addCheckBox(hoverComposite, rollOverLabel, PreferenceConstants.EDITOR_ANNOTATION_ROLL_OVER, 0); 226 227 addFiller(hoverComposite); 228 229 Label label= new Label(hoverComposite, SWT.NONE); 230 label.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_hoverPreferences); 231 GridData gd= new GridData(GridData.FILL_HORIZONTAL); 232 gd.horizontalAlignment= GridData.BEGINNING; 233 gd.horizontalSpan= 2; 234 label.setLayoutData(gd); 235 236 TableLayoutComposite layouter= new TableLayoutComposite(hoverComposite, SWT.NONE); 237 addColumnLayoutData(layouter); 238 239 fHoverTable= new Table(layouter, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK); 241 fHoverTable.setHeaderVisible(true); 242 fHoverTable.setLinesVisible(true); 243 244 gd= new GridData(GridData.FILL_HORIZONTAL); 245 gd.heightHint= SWTUtil.getTableHeightHint(fHoverTable, 10); 246 gd.horizontalSpan= 2; 247 gd.widthHint= new PixelConverter(parent).convertWidthInCharsToPixels(30); 248 layouter.setLayoutData(gd); 249 250 fHoverTable.addSelectionListener(new SelectionListener() { 251 public void widgetSelected(SelectionEvent e) { 252 handleHoverListSelection(); 253 } 254 public void widgetDefaultSelected(SelectionEvent e) { 255 } 256 }); 257 258 TableLayout tableLayout= new TableLayout(); 259 fHoverTable.setLayout(tableLayout); 260 261 fNameColumn= new TableColumn(fHoverTable, SWT.NONE); 262 fNameColumn.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_nameColumnTitle); 263 fNameColumn.setResizable(true); 264 265 fModifierColumn= new TableColumn(fHoverTable, SWT.NONE); 266 fModifierColumn.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierColumnTitle); 267 fModifierColumn.setResizable(true); 268 269 fHoverTableViewer= new CheckboxTableViewer(fHoverTable); 270 fHoverTableViewer.setUseHashlookup(true); 271 fHoverTableViewer.setContentProvider(new JavaEditorTextHoverDescriptorContentProvider()); 272 fHoverTableViewer.setLabelProvider(new JavaEditorTextHoverDescriptorLabelProvider()); 273 274 ((CheckboxTableViewer)fHoverTableViewer).addCheckStateListener(new ICheckStateListener() { 275 278 public void checkStateChanged(CheckStateChangedEvent event) { 279 String id= ((JavaEditorTextHoverDescriptor)event.getElement()).getId(); 280 if (id == null) 281 return; 282 JavaEditorTextHoverDescriptor[] descriptors= getContributedHovers(); 283 HoverConfig hoverConfig= null; 284 int i= 0, length= fHoverConfigs.length; 285 while (i < length) { 286 if (id.equals(descriptors[i].getId())) { 287 hoverConfig= fHoverConfigs[i]; 288 hoverConfig.fIsEnabled= event.getChecked(); 289 fModifierEditor.setEnabled(event.getChecked()); 290 fHoverTableViewer.setSelection(new StructuredSelection(descriptors[i])); 291 } 292 i++; 293 } 294 handleHoverListSelection(); 295 updateStatus(hoverConfig); 296 } 297 }); 298 299 label= new Label(hoverComposite, SWT.LEFT); 301 label.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_keyModifier); 302 fModifierEditor= new Text(hoverComposite, SWT.BORDER); 303 gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL); 304 fModifierEditor.setLayoutData(gd); 305 306 fModifierEditor.addKeyListener(new KeyListener() { 307 private boolean isModifierCandidate; 308 public void keyPressed(KeyEvent e) { 309 isModifierCandidate= e.keyCode > 0 && e.character == 0 && e.stateMask == 0; 310 } 311 312 public void keyReleased(KeyEvent e) { 313 if (isModifierCandidate && e.stateMask > 0 && e.stateMask == e.stateMask && e.character == 0) { String text= fModifierEditor.getText(); 315 Point selection= fModifierEditor.getSelection(); 316 int i= selection.x - 1; 317 while (i > -1 && Character.isWhitespace(text.charAt(i))) { 318 i--; 319 } 320 boolean needsPrefixDelimiter= i > -1 && !String.valueOf(text.charAt(i)).equals(DELIMITER); 321 322 i= selection.y; 323 while (i < text.length() && Character.isWhitespace(text.charAt(i))) { 324 i++; 325 } 326 boolean needsPostfixDelimiter= i < text.length() && !String.valueOf(text.charAt(i)).equals(DELIMITER); 327 328 String insertString; 329 330 if (needsPrefixDelimiter && needsPostfixDelimiter) 331 insertString= Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_insertDelimiterAndModifierAndDelimiter, new String [] {Action.findModifierString(e.stateMask)}); 332 else if (needsPrefixDelimiter) 333 insertString= Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_insertDelimiterAndModifier, new String [] {Action.findModifierString(e.stateMask)}); 334 else if (needsPostfixDelimiter) 335 insertString= Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_insertModifierAndDelimiter, new String [] {Action.findModifierString(e.stateMask)}); 336 else 337 insertString= Action.findModifierString(e.stateMask); 338 339 if (insertString != null) 340 fModifierEditor.insert(insertString); 341 } 342 } 343 }); 344 345 fModifierEditor.addModifyListener(new ModifyListener() { 346 public void modifyText(ModifyEvent e) { 347 handleModifierModified(); 348 } 349 }); 350 351 Label descriptionLabel= new Label(hoverComposite, SWT.LEFT); 353 descriptionLabel.setText(PreferencesMessages.JavaEditorHoverConfigurationBlock_description); 354 gd= new GridData(GridData.VERTICAL_ALIGN_BEGINNING); 355 gd.horizontalSpan= 2; 356 descriptionLabel.setLayoutData(gd); 357 fDescription= new Text(hoverComposite, SWT.LEFT | SWT.WRAP | SWT.MULTI | SWT.READ_ONLY | SWT.BORDER); 358 gd= new GridData(GridData.FILL_BOTH); 359 gd.horizontalSpan= 2; 360 fDescription.setLayoutData(gd); 361 362 initialize(); 363 364 scrolled.setContent(hoverComposite); 365 final Point size= hoverComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT); 366 scrolled.setMinSize(size.x, size.y); 367 368 Dialog.applyDialogFont(scrolled); 369 370 return scrolled; 371 372 } 373 374 private void addColumnLayoutData(TableLayoutComposite layouter) { 375 layouter.addColumnData(new ColumnWeightData(40, true)); 376 layouter.addColumnData(new ColumnWeightData(60, true)); 377 } 378 379 private JavaEditorTextHoverDescriptor[] getContributedHovers() { 380 return JavaPlugin.getDefault().getJavaEditorTextHoverDescriptors(); 381 } 382 383 public void initialize() { 384 JavaEditorTextHoverDescriptor[] hoverDescs= getContributedHovers(); 385 fHoverConfigs= new HoverConfig[hoverDescs.length]; 386 for (int i= 0; i < hoverDescs.length; i++) 387 fHoverConfigs[i]= new HoverConfig(hoverDescs[i].getModifierString(), hoverDescs[i].getStateMask(), hoverDescs[i].isEnabled()); 388 389 fHoverTableViewer.setInput(hoverDescs); 390 391 initializeFields(); 392 } 393 394 void initializeFields() { 395 fModifierEditor.setEnabled(false); 396 397 Iterator e= fCheckBoxes.keySet().iterator(); 398 while (e.hasNext()) { 399 Button b= (Button) e.next(); 400 String key= (String ) fCheckBoxes.get(b); 401 b.setSelection(fStore.getBoolean(key)); 402 } 403 404 for (int i= 0; i < fHoverConfigs.length; i++) 405 fHoverTable.getItem(i).setChecked(fHoverConfigs[i].fIsEnabled); 406 fHoverTableViewer.refresh(); 407 } 408 409 public void performOk() { 410 StringBuffer buf= new StringBuffer (); 411 StringBuffer maskBuf= new StringBuffer (); 412 for (int i= 0; i < fHoverConfigs.length; i++) { 413 buf.append(getContributedHovers()[i].getId()); 414 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 415 if (!fHoverConfigs[i].fIsEnabled) 416 buf.append(JavaEditorTextHoverDescriptor.DISABLED_TAG); 417 String modifier= fHoverConfigs[i].fModifierString; 418 if (modifier == null || modifier.length() == 0) 419 modifier= JavaEditorTextHoverDescriptor.NO_MODIFIER; 420 buf.append(modifier); 421 buf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 422 423 maskBuf.append(getContributedHovers()[i].getId()); 424 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 425 maskBuf.append(fHoverConfigs[i].fStateMask); 426 maskBuf.append(JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 427 } 428 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, buf.toString()); 429 fStore.setValue(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, maskBuf.toString()); 430 431 JavaPlugin.getDefault().resetJavaEditorTextHoverDescriptors(); 432 } 433 434 public void performDefaults() { 435 restoreFromPreferences(); 436 initializeFields(); 437 updateStatus(null); 438 } 439 440 private void restoreFromPreferences() { 441 String compiledTextHoverModifiers= fStore.getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS); 442 443 StringTokenizer tokenizer= new StringTokenizer (compiledTextHoverModifiers, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 444 HashMap idToModifier= new HashMap (tokenizer.countTokens() / 2); 445 446 while (tokenizer.hasMoreTokens()) { 447 String id= tokenizer.nextToken(); 448 if (tokenizer.hasMoreTokens()) 449 idToModifier.put(id, tokenizer.nextToken()); 450 } 451 452 String compiledTextHoverModifierMasks= JavaPlugin.getDefault().getPreferenceStore().getString(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS); 453 454 tokenizer= new StringTokenizer (compiledTextHoverModifierMasks, JavaEditorTextHoverDescriptor.VALUE_SEPARATOR); 455 HashMap idToModifierMask= new HashMap (tokenizer.countTokens() / 2); 456 457 while (tokenizer.hasMoreTokens()) { 458 String id= tokenizer.nextToken(); 459 if (tokenizer.hasMoreTokens()) 460 idToModifierMask.put(id, tokenizer.nextToken()); 461 } 462 463 for (int i= 0; i < fHoverConfigs.length; i++) { 464 String modifierString= (String )idToModifier.get(getContributedHovers()[i].getId()); 465 boolean enabled= true; 466 if (modifierString == null) 467 modifierString= JavaEditorTextHoverDescriptor.DISABLED_TAG; 468 469 if (modifierString.startsWith(JavaEditorTextHoverDescriptor.DISABLED_TAG)) { 470 enabled= false; 471 modifierString= modifierString.substring(1); 472 } 473 474 if (modifierString.equals(JavaEditorTextHoverDescriptor.NO_MODIFIER)) 475 modifierString= ""; 477 fHoverConfigs[i].fModifierString= modifierString; 478 fHoverConfigs[i].fIsEnabled= enabled; 479 fHoverConfigs[i].fStateMask= JavaEditorTextHoverDescriptor.computeStateMask(modifierString); 480 481 if (fHoverConfigs[i].fStateMask == -1) { 482 try { 483 fHoverConfigs[i].fStateMask= Integer.parseInt((String )idToModifierMask.get(getContributedHovers()[i].getId())); 484 } catch (NumberFormatException ex) { 485 fHoverConfigs[i].fStateMask= -1; 486 } 487 } 488 } 489 } 490 491 private void handleModifierModified() { 492 int i= fHoverTable.getSelectionIndex(); 493 if (i == -1) 494 return; 495 496 String modifiers= fModifierEditor.getText(); 497 fHoverConfigs[i].fModifierString= modifiers; 498 fHoverConfigs[i].fStateMask= JavaEditorTextHoverDescriptor.computeStateMask(modifiers); 499 500 fHoverTableViewer.refresh(getContributedHovers()[i]); 502 503 updateStatus(fHoverConfigs[i]); 504 } 505 506 private void handleHoverListSelection() { 507 int i= fHoverTable.getSelectionIndex(); 508 509 if (i == -1) { 510 if (fHoverTable.getSelectionCount() == 0) 511 fModifierEditor.setEnabled(false); 512 return; 513 } 514 515 boolean enabled= fHoverConfigs[i].fIsEnabled; 516 fModifierEditor.setEnabled(enabled); 517 fModifierEditor.setText(fHoverConfigs[i].fModifierString); 518 String description= getContributedHovers()[i].getDescription(); 519 if (description == null) 520 description= ""; fDescription.setText(description); 522 } 523 524 IStatus getStatus() { 525 if (fStatus == null) 526 fStatus= new StatusInfo(); 527 return fStatus; 528 } 529 530 private void updateStatus(HoverConfig hoverConfig) { 531 if (hoverConfig != null && hoverConfig.fIsEnabled && hoverConfig.fStateMask == -1) 532 fStatus= new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierIsNotValid, hoverConfig.fModifierString)); 533 else 534 fStatus= new StatusInfo(); 535 536 int i= 0; 537 HashMap stateMasks= new HashMap (fHoverConfigs.length); 538 while (fStatus.isOK() && i < fHoverConfigs.length) { 539 if (fHoverConfigs[i].fIsEnabled) { 540 String label= getContributedHovers()[i].getLabel(); 541 Integer stateMask= new Integer (fHoverConfigs[i].fStateMask); 542 if (fHoverConfigs[i].fStateMask == -1) 543 fStatus= new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_modifierIsNotValidForHover, new String [] {fHoverConfigs[i].fModifierString, label})); 544 else if (stateMasks.containsKey(stateMask)) 545 fStatus= new StatusInfo(IStatus.ERROR, Messages.format(PreferencesMessages.JavaEditorHoverConfigurationBlock_duplicateModifier, new String [] {label, (String )stateMasks.get(stateMask)})); 546 else 547 stateMasks.put(stateMask, label); 548 } 549 i++; 550 } 551 552 fMainPreferencePage.setValid(fStatus.isOK()); 553 StatusUtil.applyToStatusLine(fMainPreferencePage, fStatus); 554 } 555 556 private Button addCheckBox(Composite parent, String label, String key, int indentation) { 557 Button checkBox= new Button(parent, SWT.CHECK); 558 checkBox.setText(label); 559 560 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); 561 gd.horizontalIndent= indentation; 562 gd.horizontalSpan= 2; 563 checkBox.setLayoutData(gd); 564 checkBox.addSelectionListener(fCheckBoxListener); 565 566 fCheckBoxes.put(checkBox, key); 567 568 return checkBox; 569 } 570 571 private void addFiller(Composite composite) { 572 PixelConverter pixelConverter= new PixelConverter(composite); 573 Label filler= new Label(composite, SWT.LEFT ); 574 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL); 575 gd.horizontalSpan= 2; 576 gd.heightHint= pixelConverter.convertHeightInCharsToPixels(1) / 2; 577 filler.setLayoutData(gd); 578 } 579 580 583 public void dispose() { 584 } 586 } 587 | Popular Tags |