1 11 12 package org.eclipse.ui.internal.editors.text; 13 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.Map ; 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.custom.StackLayout; 21 import org.eclipse.swt.events.SelectionEvent; 22 import org.eclipse.swt.events.SelectionListener; 23 import org.eclipse.swt.graphics.Image; 24 import org.eclipse.swt.layout.FillLayout; 25 import org.eclipse.swt.layout.GridData; 26 import org.eclipse.swt.layout.GridLayout; 27 import org.eclipse.swt.widgets.Button; 28 import org.eclipse.swt.widgets.Combo; 29 import org.eclipse.swt.widgets.Composite; 30 import org.eclipse.swt.widgets.Control; 31 import org.eclipse.swt.widgets.Label; 32 import org.eclipse.swt.widgets.Shell; 33 34 import org.eclipse.core.runtime.Assert; 35 import org.eclipse.core.runtime.CoreException; 36 import org.eclipse.core.runtime.ISafeRunnable; 37 import org.eclipse.core.runtime.IStatus; 38 import org.eclipse.core.runtime.SafeRunner; 39 import org.eclipse.core.runtime.Status; 40 41 import org.eclipse.jface.dialogs.Dialog; 42 import org.eclipse.jface.dialogs.IDialogConstants; 43 import org.eclipse.jface.dialogs.MessageDialog; 44 import org.eclipse.jface.viewers.ComboViewer; 45 import org.eclipse.jface.viewers.ISelectionChangedListener; 46 import org.eclipse.jface.viewers.IStructuredContentProvider; 47 import org.eclipse.jface.viewers.IStructuredSelection; 48 import org.eclipse.jface.viewers.LabelProvider; 49 import org.eclipse.jface.viewers.SelectionChangedEvent; 50 import org.eclipse.jface.viewers.StructuredSelection; 51 import org.eclipse.jface.viewers.Viewer; 52 53 54 import org.eclipse.ui.editors.text.EditorsUI; 55 56 import org.eclipse.ui.texteditor.spelling.IPreferenceStatusMonitor; 57 import org.eclipse.ui.texteditor.spelling.ISpellingPreferenceBlock; 58 import org.eclipse.ui.texteditor.spelling.SpellingEngineDescriptor; 59 import org.eclipse.ui.texteditor.spelling.SpellingService; 60 61 66 class SpellingConfigurationBlock implements IPreferenceConfigurationBlock { 67 68 71 private static class ErrorPreferences implements ISpellingPreferenceBlock { 72 73 74 private String fMessage; 75 76 77 private Label fLabel; 78 79 84 protected ErrorPreferences(String message) { 85 fMessage= message; 86 } 87 88 91 public Control createControl(Composite composite) { 92 Composite inner= new Composite(composite, SWT.NONE); 93 inner.setLayout(new FillLayout(SWT.VERTICAL)); 94 95 fLabel= new Label(inner, SWT.CENTER); 96 fLabel.setText(fMessage); 97 98 return inner; 99 } 100 101 104 public void initialize(IPreferenceStatusMonitor statusMonitor) { 105 } 106 107 110 public boolean canPerformOk() { 111 return true; 112 } 113 114 117 public void performOk() { 118 } 119 120 123 public void performDefaults() { 124 } 125 126 129 public void performRevert() { 130 } 131 132 135 public void dispose() { 136 } 137 138 141 public void setEnabled(boolean enabled) { 142 fLabel.setEnabled(enabled); 143 } 144 } 145 146 149 private static class ForwardingStatusMonitor implements IPreferenceStatusMonitor { 150 151 152 private IPreferenceStatusMonitor fForwardedMonitor; 153 154 155 private IStatus fStatus; 156 157 163 public ForwardingStatusMonitor(IPreferenceStatusMonitor forwardedMonitor) { 164 fForwardedMonitor= forwardedMonitor; 165 } 166 167 170 public void statusChanged(IStatus status) { 171 fStatus= status; 172 fForwardedMonitor.statusChanged(status); 173 } 174 175 180 public IStatus getStatus() { 181 return fStatus; 182 } 183 } 184 185 186 private final OverlayPreferenceStore fStore; 187 188 189 private Combo fProviderCombo; 190 private Button fEnablementCheckbox; 191 private ComboViewer fProviderViewer; 192 private Composite fComboGroup; 193 private Composite fGroup; 194 private StackLayout fStackLayout; 195 196 197 private final Map fProviderDescriptors; 198 private final Map fProviderPreferences; 199 private final Map fProviderControls; 200 201 private ForwardingStatusMonitor fStatusMonitor; 202 203 private ISpellingPreferenceBlock fCurrentBlock; 204 205 206 public SpellingConfigurationBlock(OverlayPreferenceStore store, IPreferenceStatusMonitor statusMonitor) { 207 Assert.isNotNull(store); 208 fStore= store; 209 fStore.addKeys(createOverlayStoreKeys()); 210 fStatusMonitor= new ForwardingStatusMonitor(statusMonitor); 211 fProviderDescriptors= createListModel(); 212 fProviderPreferences= new HashMap (); 213 fProviderControls= new HashMap (); 214 } 215 216 private Map createListModel() { 217 SpellingEngineDescriptor[] descs= EditorsUI.getSpellingService().getSpellingEngineDescriptors(); 218 Map map= new HashMap (); 219 for (int i= 0; i < descs.length; i++) { 220 map.put(descs[i].getId(), descs[i]); 221 } 222 return map; 223 } 224 225 private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() { 226 227 ArrayList overlayKeys= new ArrayList (); 228 229 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, SpellingService.PREFERENCE_SPELLING_ENABLED)); 230 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SpellingService.PREFERENCE_SPELLING_ENGINE)); 231 232 OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; 233 overlayKeys.toArray(keys); 234 return keys; 235 } 236 237 243 public Control createControl(Composite parent) { 244 245 Composite composite= new Composite(parent, SWT.NULL); 246 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL); 248 composite.setLayoutData(gd); 249 GridLayout layout= new GridLayout(); 250 layout.numColumns= 2; 251 layout.marginHeight= 0; 252 layout.marginWidth= 0; 253 254 PixelConverter pc= new PixelConverter(composite); 255 layout.verticalSpacing= pc.convertHeightInCharsToPixels(1) / 2; 256 composite.setLayout(layout); 257 258 if (EditorsUI.getSpellingService().getSpellingEngineDescriptors().length == 0) { 259 Label label= new Label(composite, SWT.NONE); 260 label.setText(TextEditorMessages.SpellingConfigurationBlock_error_not_installed); 261 return composite; 262 } 263 264 265 fEnablementCheckbox= new Button(composite, SWT.CHECK); 266 fEnablementCheckbox.setText(TextEditorMessages.SpellingConfigurationBlock_enable); 267 gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING); 268 fEnablementCheckbox.setLayoutData(gd); 269 fEnablementCheckbox.addSelectionListener(new SelectionListener() { 270 public void widgetSelected(SelectionEvent e) { 271 boolean enabled= fEnablementCheckbox.getSelection(); 272 fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENABLED, enabled); 273 updateCheckboxDependencies(); 274 } 275 276 public void widgetDefaultSelected(SelectionEvent e) { 277 } 278 }); 279 280 Label label= new Label(composite, SWT.CENTER); 281 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); 282 label.setLayoutData(gd); 283 284 if (fProviderDescriptors.size() > 1) { 285 fComboGroup= new Composite(composite, SWT.NONE); 286 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); 287 gd.horizontalIndent= 10; 288 fComboGroup.setLayoutData(gd); 289 GridLayout gridLayout= new GridLayout(2, false); 290 gridLayout.marginWidth= 0; 291 fComboGroup.setLayout(gridLayout); 292 293 Label comboLabel= new Label(fComboGroup, SWT.CENTER); 294 gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_CENTER); 295 comboLabel.setLayoutData(gd); 296 comboLabel.setText(TextEditorMessages.SpellingConfigurationBlock_combo_caption); 297 298 label= new Label(composite, SWT.CENTER); 299 gd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); 300 label.setLayoutData(gd); 301 302 fProviderCombo= new Combo(fComboGroup, SWT.READ_ONLY | SWT.DROP_DOWN); 303 gd= new GridData(GridData.HORIZONTAL_ALIGN_END | GridData.VERTICAL_ALIGN_CENTER); 304 fProviderCombo.setLayoutData(gd); 305 306 fProviderViewer= createProviderViewer(); 307 } 308 309 Composite groupComp= new Composite(composite, SWT.NONE); 310 gd= new GridData(GridData.FILL_BOTH); 311 gd.horizontalSpan= 2; 312 groupComp.setLayoutData(gd); 313 GridLayout gridLayout= new GridLayout(1, false); 314 gridLayout.marginWidth= 0; 315 groupComp.setLayout(gridLayout); 316 317 318 fGroup= new Composite(groupComp, SWT.NONE); 319 gd= new GridData(SWT.FILL, SWT.FILL, true, true); 320 gd.horizontalIndent= 10; 321 fGroup.setLayoutData(gd); 322 fStackLayout= new StackLayout(); 323 fGroup.setLayout(fStackLayout); 324 325 return composite; 326 } 327 328 private ComboViewer createProviderViewer() { 329 330 final ComboViewer viewer= new ComboViewer(fProviderCombo); 331 viewer.setContentProvider(new IStructuredContentProvider() { 332 333 336 public void dispose() { 337 } 338 339 342 public void inputChanged(Viewer v, Object oldInput, Object newInput) { 343 } 344 345 348 public Object [] getElements(Object inputElement) { 349 return fProviderDescriptors.values().toArray(); 350 } 351 }); 352 viewer.setLabelProvider(new LabelProvider() { 353 356 public Image getImage(Object element) { 357 return null; 358 } 359 360 363 public String getText(Object element) { 364 return ((SpellingEngineDescriptor) element).getLabel(); 365 } 366 }); 367 viewer.addSelectionChangedListener(new ISelectionChangedListener() { 368 369 public void selectionChanged(SelectionChangedEvent event) { 370 IStructuredSelection sel= (IStructuredSelection) event.getSelection(); 371 if (sel.isEmpty()) 372 return; 373 if (fCurrentBlock != null && fStatusMonitor.getStatus() != null && fStatusMonitor.getStatus().matches(IStatus.ERROR)) 374 if (isPerformRevert()) { 375 ISafeRunnable runnable= new ISafeRunnable() { 376 public void run() throws Exception { 377 fCurrentBlock.performRevert(); 378 } 379 public void handleException(Throwable x) { 380 } 381 }; 382 SafeRunner.run(runnable); 383 } else { 384 revertSelection(); 385 return; 386 } 387 fStore.setValue(SpellingService.PREFERENCE_SPELLING_ENGINE, ((SpellingEngineDescriptor) sel.getFirstElement()).getId()); 388 updateListDependencies(); 389 } 390 391 private boolean isPerformRevert() { 392 Shell shell= viewer.getControl().getShell(); 393 MessageDialog dialog= new MessageDialog(shell, TextEditorMessages.SpellingConfigurationBlock_error_title, null, TextEditorMessages.SpellingConfigurationBlock_error_message, MessageDialog.QUESTION, new String [] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL }, 1); 394 return dialog.open() == 0; 395 } 396 397 private void revertSelection() { 398 try { 399 viewer.removeSelectionChangedListener(this); 400 SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore); 401 if (desc != null) 402 viewer.setSelection(new StructuredSelection(desc), true); 403 } finally { 404 viewer.addSelectionChangedListener(this); 405 } 406 } 407 }); 408 viewer.setInput(fProviderDescriptors); 409 viewer.refresh(); 410 411 return viewer; 412 } 413 414 private void updateCheckboxDependencies() { 415 final boolean enabled= fEnablementCheckbox.getSelection(); 416 if (fComboGroup != null) 417 setEnabled(fComboGroup, enabled); 418 SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore); 419 String id= desc != null ? desc.getId() : ""; final ISpellingPreferenceBlock preferenceBlock= (ISpellingPreferenceBlock) fProviderPreferences.get(id); 421 if (preferenceBlock != null) { 422 ISafeRunnable runnable= new ISafeRunnable() { 423 public void run() throws Exception { 424 preferenceBlock.setEnabled(enabled); 425 } 426 public void handleException(Throwable x) { 427 } 428 }; 429 SafeRunner.run(runnable); 430 } 431 } 432 433 private void setEnabled(Control control, boolean enabled) { 434 if (control instanceof Composite) { 435 Control[] children= ((Composite) control).getChildren(); 436 for (int i= 0; i < children.length; i++) 437 setEnabled(children[i], enabled); 438 } 439 control.setEnabled(enabled); 440 } 441 442 void updateListDependencies() { 443 SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore); 444 String id; 445 if (desc == null) { 446 id= ""; String message= TextEditorMessages.SpellingConfigurationBlock_error_not_exist; 449 EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null)); 450 fCurrentBlock= new ErrorPreferences(message); 451 } else { 452 id= desc.getId(); 453 fCurrentBlock= (ISpellingPreferenceBlock) fProviderPreferences.get(id); 454 if (fCurrentBlock == null) { 455 try { 456 fCurrentBlock= desc.createPreferences(); 457 fProviderPreferences.put(id, fCurrentBlock); 458 } catch (CoreException e) { 459 EditorsPlugin.log(e); 460 fCurrentBlock= new ErrorPreferences(e.getLocalizedMessage()); 461 } 462 } 463 } 464 465 Control control= (Control) fProviderControls.get(id); 466 if (control == null) { 467 final Control[] result= new Control[1]; 468 ISafeRunnable runnable= new ISafeRunnable() { 469 public void run() throws Exception { 470 result[0]= fCurrentBlock.createControl(fGroup); 471 } 472 public void handleException(Throwable x) { 473 } 474 }; 475 SafeRunner.run(runnable); 476 control= result[0]; 477 if (control == null) { 478 String message= TextEditorMessages.SpellingConfigurationBlock_info_no_preferences; 479 EditorsPlugin.log(new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, message, null)); 480 control= new ErrorPreferences(message).createControl(fGroup); 481 } else { 482 fProviderControls.put(id, control); 483 } 484 } 485 Dialog.applyDialogFont(control); 486 fStackLayout.topControl= control; 487 control.pack(); 488 fGroup.layout(); 489 fGroup.getParent().layout(); 490 491 fStatusMonitor.statusChanged(new StatusInfo()); 492 ISafeRunnable runnable= new ISafeRunnable() { 493 public void run() throws Exception { 494 fCurrentBlock.initialize(fStatusMonitor); 495 } 496 public void handleException(Throwable x) { 497 } 498 }; 499 SafeRunner.run(runnable); 500 } 501 502 public void initialize() { 503 restoreFromPreferences(); 504 } 505 506 public boolean canPerformOk() { 507 SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore); 508 String id= desc != null ? desc.getId() : ""; final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) fProviderPreferences.get(id); 510 if (block == null) 511 return true; 512 513 final Boolean [] result= new Boolean [] { Boolean.TRUE }; 514 ISafeRunnable runnable= new ISafeRunnable() { 515 public void run() throws Exception { 516 result[0]= Boolean.valueOf(block.canPerformOk()); 517 } 518 public void handleException(Throwable x) { 519 } 520 }; 521 SafeRunner.run(runnable); 522 return result[0].booleanValue(); 523 } 524 525 public void performOk() { 526 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { 527 final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next(); 528 ISafeRunnable runnable= new ISafeRunnable() { 529 public void run() throws Exception { 530 block.performOk(); 531 } 532 public void handleException(Throwable x) { 533 } 534 }; 535 SafeRunner.run(runnable); 536 } 537 } 538 539 public void performDefaults() { 540 restoreFromPreferences(); 541 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { 542 final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next(); 543 ISafeRunnable runnable= new ISafeRunnable() { 544 public void run() throws Exception { 545 block.performDefaults(); 546 } 547 public void handleException(Throwable x) { 548 } 549 }; 550 SafeRunner.run(runnable); 551 } 552 } 553 554 public void dispose() { 555 for (Iterator it= fProviderPreferences.values().iterator(); it.hasNext();) { 556 final ISpellingPreferenceBlock block= (ISpellingPreferenceBlock) it.next(); 557 ISafeRunnable runnable= new ISafeRunnable() { 558 public void run() throws Exception { 559 block.dispose(); 560 } 561 public void handleException(Throwable x) { 562 } 563 }; 564 SafeRunner.run(runnable); 565 } 566 } 567 568 private void restoreFromPreferences() { 569 if (fEnablementCheckbox == null) 570 return; 571 572 boolean enabled= fStore.getBoolean(SpellingService.PREFERENCE_SPELLING_ENABLED); 573 fEnablementCheckbox.setSelection(enabled); 574 575 if (fProviderViewer == null) 576 updateListDependencies(); 577 else { 578 SpellingEngineDescriptor desc= EditorsUI.getSpellingService().getActiveSpellingEngineDescriptor(fStore); 579 if (desc != null) 580 fProviderViewer.setSelection(new StructuredSelection(desc), true); 581 } 582 583 updateCheckboxDependencies(); 584 } 585 } 586 | Popular Tags |