1 11 12 package org.eclipse.ui.internal.editors.text; 13 14 15 import java.util.ArrayList ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.Set ; 19 20 import org.eclipse.swt.SWT; 21 import org.eclipse.swt.events.SelectionAdapter; 22 import org.eclipse.swt.events.SelectionEvent; 23 import org.eclipse.swt.events.SelectionListener; 24 import org.eclipse.swt.layout.GridData; 25 import org.eclipse.swt.layout.GridLayout; 26 import org.eclipse.swt.widgets.Button; 27 import org.eclipse.swt.widgets.Combo; 28 import org.eclipse.swt.widgets.Composite; 29 import org.eclipse.swt.widgets.Control; 30 import org.eclipse.swt.widgets.Label; 31 import org.eclipse.swt.widgets.Text; 32 33 import org.eclipse.core.runtime.Assert; 34 import org.eclipse.core.runtime.IStatus; 35 import org.eclipse.core.runtime.Preferences; 36 37 import org.eclipse.jface.dialogs.Dialog; 38 import org.eclipse.jface.dialogs.DialogPage; 39 import org.eclipse.jface.dialogs.IMessageProvider; 40 import org.eclipse.jface.preference.PreferencePage; 41 42 43 import org.eclipse.ui.editors.text.ITextEditorHelpContextIds; 44 45 import org.eclipse.ui.IWorkbench; 46 import org.eclipse.ui.IWorkbenchPreferencePage; 47 import org.eclipse.ui.PlatformUI; 48 import org.eclipse.ui.internal.editors.text.AccessibilityPreferencePage.EnumeratedDomain.EnumValue; 49 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants; 50 51 58 public class AccessibilityPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { 59 60 private abstract class Initializer { 61 62 protected final Preference fPreference; 63 64 protected Initializer(Preference preference) { 65 fPreference= preference; 66 } 67 68 public abstract void initialize(); 69 } 70 71 72 public final class InitializerFactory { 73 private class TextInitializer extends Initializer { 74 private final Text fText; 75 76 public TextInitializer(Preference preference, Text control) { 77 super(preference); 78 fText= control; 79 } 80 public void initialize() { 81 String value= fOverlayStore.getString(fPreference.getKey()); 82 fText.setText(value); 83 } 84 } 85 86 private class CheckboxInitializer extends Initializer { 87 private final Button fControl; 88 89 public CheckboxInitializer(Preference preference, Button control) { 90 super(preference); 91 fControl= control; 92 } 93 public void initialize() { 94 boolean value= fOverlayStore.getBoolean(fPreference.getKey()); 95 fControl.setSelection(value); 96 } 97 } 98 99 private class ComboInitializer extends Initializer { 100 private final Combo fControl; 101 private final EnumeratedDomain fDomain; 102 103 public ComboInitializer(Preference preference, Combo control, EnumeratedDomain domain) { 104 super(preference); 105 fControl= control; 106 fDomain= domain; 107 } 108 public void initialize() { 109 int value= fOverlayStore.getInt(fPreference.getKey()); 110 EnumValue enumValue= fDomain.getValueByInteger(value); 111 if (enumValue != null) { 112 int index= fDomain.getIndex(enumValue); 113 if (index >= 0) 114 fControl.select(index); 115 } 116 } 117 } 118 119 public Initializer create(Preference preference, Text control) { 120 return new TextInitializer(preference, control); 121 } 122 123 public Initializer create(Preference preference, Button control) { 124 return new CheckboxInitializer(preference, control); 125 } 126 127 public Initializer create(Preference preference, Combo control, EnumeratedDomain domain) { 128 return new ComboInitializer(preference, control, domain); 129 } 130 } 131 132 133 abstract static class Domain { 134 public abstract IStatus validate(Object value); 135 protected int parseInteger(Object val) throws NumberFormatException { 136 if (val instanceof Integer ) 137 return ((Integer ) val).intValue(); 138 139 if (val instanceof String ) 140 return Integer.parseInt((String ) val); 141 142 throw new NumberFormatException (NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(val))); 143 } 144 } 145 146 static class IntegerDomain extends Domain { 147 private final int fMax; 148 private final int fMin; 149 public IntegerDomain(int min, int max) { 150 Assert.isLegal(max >= min); 151 fMax= max; 152 fMin= min; 153 } 154 155 public IStatus validate(Object value) { 156 StatusInfo status= new StatusInfo(); 157 if (value instanceof String && ((String )value).length() == 0) { 158 status.setError(TextEditorMessages.TextEditorPreferencePage_emptyInput); 159 return status; 160 } 161 162 try { 163 int integer= parseInteger(value); 164 if (!rangeCheck(integer)) 165 status.setError(NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(integer))); 166 } catch (NumberFormatException e) { 167 status.setError(NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(value))); 168 } 169 return status; 170 } 171 172 protected boolean rangeCheck(int i) { 173 return (i >= fMin && i <= fMax); 174 } 175 176 } 177 178 static class EnumeratedDomain extends Domain { 179 public final static class EnumValue { 180 private final int fValue; 181 private final String fName; 182 public EnumValue(int value) { 183 this(value, null); 184 } 185 public EnumValue(int value, String name) { 186 fValue= value; 187 fName= name; 188 } 189 public String getLabel() { 190 return fName == null ? String.valueOf(fValue) : fName; 191 } 192 public int getIntValue() { 193 return fValue; 194 } 195 public final int hashCode() { 196 return getIntValue(); 197 } 198 public boolean equals(Object obj) { 199 if (obj instanceof EnumValue) { 200 return ((EnumValue) obj).getIntValue() == fValue; 201 } 202 return false; 203 } 204 } 205 206 private final java.util.List fItems= new ArrayList (); 207 private final Set fValueSet= new HashSet (); 208 209 public void addValue(EnumValue val) { 210 if (fValueSet.contains(val)) 211 fItems.remove(val); 212 fItems.add(val); 213 fValueSet.add(val); 214 } 215 216 public int getIndex(EnumValue enumValue) { 217 int i= 0; 218 for (Iterator it= fItems.iterator(); it.hasNext();) { 219 EnumValue ev= (EnumValue) it.next(); 220 if (ev.equals(enumValue)) 221 return i; 222 i++; 223 } 224 return -1; 225 } 226 227 public EnumValue getValueByIndex (int index) { 228 if (index >= 0 && fItems.size() > index) 229 return (EnumValue) fItems.get(index); 230 return null; 231 } 232 233 public EnumValue getValueByInteger(int intValue) { 234 for (Iterator it= fItems.iterator(); it.hasNext();) { 235 EnumValue e= (EnumValue) it.next(); 236 if (e.getIntValue() == intValue) 237 return e; 238 } 239 return null; 240 } 241 242 public void addValue(int val) { 243 addValue(new EnumValue(val)); 244 } 245 246 public void addRange(int from, int to) { 247 while (from <= to) 248 addValue(from++); 249 } 250 251 public IStatus validate(Object value) { 252 StatusInfo status= new StatusInfo(); 253 if (value instanceof String && ((String )value).length() == 0) { 254 status.setError(TextEditorMessages.TextEditorPreferencePage_emptyInput); 255 return status; 256 } 257 258 try { 259 EnumValue e= parseEnumValue(value); 260 if (!fValueSet.contains(e)) 261 status.setError(NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidRange, new String [] {getValueByIndex(0).getLabel(), getValueByIndex(fItems.size() - 1).getLabel()})); 262 } catch (NumberFormatException e) { 263 status.setError(NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(value))); 264 } 265 266 return status; 267 } 268 269 private EnumValue parseEnumValue(Object value) { 270 if (value instanceof EnumValue) 271 return (EnumValue) value; 272 int integer= parseInteger(value); 273 return getValueByInteger(integer); 274 } 275 } 276 277 static class BooleanDomain extends Domain { 278 public IStatus validate(Object value) { 279 StatusInfo status= new StatusInfo(); 280 if (value instanceof String && ((String )value).length() == 0) { 281 status.setError(TextEditorMessages.TextEditorPreferencePage_emptyInput); 282 return status; 283 } 284 285 try { 286 parseBoolean(value); 287 } catch (NumberFormatException e) { 288 status.setError(NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(value))); 289 } 290 291 return status; 292 } 293 294 private boolean parseBoolean(Object value) throws NumberFormatException { 295 if (value instanceof Boolean ) 296 return ((Boolean ) value).booleanValue(); 297 298 if (value instanceof String ) { 299 if (Boolean.TRUE.toString().equalsIgnoreCase((String ) value)) 300 return true; 301 if (Boolean.FALSE.toString().equalsIgnoreCase((String ) value)) 302 return false; 303 } 304 305 throw new NumberFormatException (NLSUtility.format(TextEditorMessages.TextEditorPreferencePage_invalidInput, String.valueOf(value))); 306 } 307 } 308 309 private static class Preference { 310 private String fKey; 311 private String fName; 312 private String fDescription; 314 public Preference(String key, String name, String description) { 315 Assert.isNotNull(key); 316 Assert.isNotNull(name); 317 fKey= key; 318 fName= name; 319 fDescription= description; 320 } 321 public final String getKey() { 322 return fKey; 323 } 324 public final String getName() { 325 return fName; 326 } 327 public final String getDescription() { 328 return fDescription; 329 } 330 } 331 332 private OverlayPreferenceStore fOverlayStore; 333 334 338 private boolean fFieldsInitialized= false; 339 340 private java.util.List fInitializers= new ArrayList (); 341 342 private InitializerFactory fInitializerFactory= new InitializerFactory(); 343 344 private Control fContents; 345 private ArrayList fMasterSlaveListeners= new ArrayList (); 346 347 348 public AccessibilityPreferencePage() { 349 setDescription(TextEditorMessages.AccessibilityPreferencePage_accessibility_title); 350 setPreferenceStore(EditorsPlugin.getDefault().getPreferenceStore()); 351 352 fOverlayStore= createOverlayStore(); 353 } 354 355 356 protected Label createDescriptionLabel(Composite parent) { 357 return null; } 359 360 private OverlayPreferenceStore createOverlayStore() { 361 362 ArrayList overlayKeys= new ArrayList (); 363 364 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_CUSTOM_CARETS)); 365 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WIDE_CARET)); 366 overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_CHARACTER_MODE)); 367 368 OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()]; 369 overlayKeys.toArray(keys); 370 return new OverlayPreferenceStore(getPreferenceStore(), keys); 371 } 372 373 376 public void init(IWorkbench workbench) { 377 } 378 379 382 public void createControl(Composite parent) { 383 super.createControl(parent); 384 PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), ITextEditorHelpContextIds.TEXT_EDITOR_PREFERENCE_PAGE); 385 } 386 387 protected Preferences getPreferences() { 388 return new Preferences(); 389 } 390 391 private Control createAppearancePage(Composite parent) { 392 393 394 Composite appearanceComposite= new Composite(parent, SWT.NONE); 395 GridLayout layout= new GridLayout(); 396 layout.numColumns= 2; 397 layout.marginHeight= 0; 398 layout.marginWidth= 0; 399 400 appearanceComposite.setLayout(layout); 401 402 String label= TextEditorMessages.TextEditorPreferencePage_accessibility_disableCustomCarets; 403 Preference customCarets= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_USE_CUSTOM_CARETS, label, null); 404 Button master= addCheckBox(appearanceComposite, customCarets, new BooleanDomain(), 0); 405 406 label= TextEditorMessages.TextEditorPreferencePage_accessibility_wideCaret; 407 Preference wideCaret= new Preference(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_WIDE_CARET, label, null); 408 Button slave= addCheckBox(appearanceComposite, wideCaret, new BooleanDomain(), 0); 409 createDependency(master, customCarets, new Control[] { slave }); 410 411 label= TextEditorMessages.QuickDiffConfigurationBlock_characterMode; 412 Preference quickDiffTextMode= new Preference(AbstractDecoratedTextEditorPreferenceConstants.QUICK_DIFF_CHARACTER_MODE, label, null); 413 addCheckBox(appearanceComposite, quickDiffTextMode, new BooleanDomain(), 0); 414 415 return appearanceComposite; 416 } 417 418 421 protected Control createContents(Composite parent) { 422 423 fOverlayStore.load(); 424 fOverlayStore.start(); 425 426 fContents= createAppearancePage(parent); 427 428 initialize(); 429 Dialog.applyDialogFont(fContents); 430 return fContents; 431 } 432 433 private void initialize() { 434 initializeFields(); 435 } 436 437 private void initializeFields() { 438 439 for (Iterator it= fInitializers.iterator(); it.hasNext();) { 440 Initializer initializer= (Initializer) it.next(); 441 initializer.initialize(); 442 } 443 444 fFieldsInitialized= true; 445 446 updateStatus(new StatusInfo()); 447 448 } 449 450 453 public boolean performOk() { 454 fOverlayStore.propagate(); 455 EditorsPlugin.getDefault().savePluginPreferences(); 456 return true; 457 } 458 459 462 protected void performDefaults() { 463 464 fOverlayStore.loadDefaults(); 465 466 initializeFields(); 467 468 super.performDefaults(); 469 } 470 471 474 public void dispose() { 475 476 if (fOverlayStore != null) { 477 fOverlayStore.stop(); 478 fOverlayStore= null; 479 } 480 481 super.dispose(); 482 } 483 484 485 486 private Button addCheckBox(Composite composite, final Preference preference, final Domain domain, int indentation) { 487 final Button checkBox= new Button(composite, SWT.CHECK); 488 checkBox.setText(preference.getName()); 489 checkBox.setToolTipText(preference.getDescription()); 490 491 GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); 492 gd.horizontalIndent= indentation; 493 gd.horizontalSpan= 2; 494 checkBox.setLayoutData(gd); 495 checkBox.addSelectionListener(new SelectionAdapter() { 496 public void widgetSelected(SelectionEvent e) { 497 boolean value= checkBox.getSelection(); 498 IStatus status= domain.validate(Boolean.valueOf(value)); 499 if (!status.matches(IStatus.ERROR)) 500 fOverlayStore.setValue(preference.getKey(), value); 501 updateStatus(status); 502 } 503 }); 504 505 fInitializers.add(fInitializerFactory.create(preference, checkBox)); 506 507 return checkBox; 508 } 509 510 private void createDependency(final Button master, Preference preference, final Control[] slaves) { 511 indent(slaves[0]); 512 513 boolean masterState= fOverlayStore.getBoolean(preference.getKey()); 514 for (int i= 0; i < slaves.length; i++) { 515 slaves[i].setEnabled(masterState); 516 } 517 518 SelectionListener listener= new SelectionListener() { 519 public void widgetSelected(SelectionEvent e) { 520 boolean state= master.getSelection(); 521 for (int i= 0; i < slaves.length; i++) { 522 slaves[i].setEnabled(state); 523 } 524 } 525 526 public void widgetDefaultSelected(SelectionEvent e) {} 527 }; 528 master.addSelectionListener(listener); 529 fMasterSlaveListeners.add(listener); 530 } 531 532 private static void indent(Control control) { 533 GridData gridData= new GridData(); 534 gridData.horizontalIndent= 20; 535 control.setLayoutData(gridData); 536 } 537 538 void updateStatus(IStatus status) { 539 if (!fFieldsInitialized) 540 return; 541 542 setValid(!status.matches(IStatus.ERROR)); 543 applyToStatusLine(this, status); 544 } 545 546 552 public void applyToStatusLine(DialogPage page, IStatus status) { 553 String message= status.getMessage(); 554 switch (status.getSeverity()) { 555 case IStatus.OK: 556 page.setMessage(message, IMessageProvider.NONE); 557 page.setErrorMessage(null); 558 break; 559 case IStatus.WARNING: 560 page.setMessage(message, IMessageProvider.WARNING); 561 page.setErrorMessage(null); 562 break; 563 case IStatus.INFO: 564 page.setMessage(message, IMessageProvider.INFORMATION); 565 page.setErrorMessage(null); 566 break; 567 default: 568 if (message.length() == 0) { 569 message= null; 570 } 571 page.setMessage(null); 572 page.setErrorMessage(message); 573 break; 574 } 575 } 576 } 577 | Popular Tags |