1 11 package org.eclipse.jdt.internal.ui.preferences.formatter; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.List ; 16 import java.util.Map ; 17 import java.util.Observable ; 18 import java.util.Observer ; 19 20 import org.eclipse.core.runtime.IStatus; 21 import org.eclipse.core.runtime.Status; 22 23 import org.eclipse.swt.SWT; 24 import org.eclipse.swt.custom.SashForm; 25 import org.eclipse.swt.custom.ScrolledComposite; 26 import org.eclipse.swt.events.ControlEvent; 27 import org.eclipse.swt.events.ControlListener; 28 import org.eclipse.swt.events.FocusAdapter; 29 import org.eclipse.swt.events.FocusEvent; 30 import org.eclipse.swt.events.FocusListener; 31 import org.eclipse.swt.events.ModifyEvent; 32 import org.eclipse.swt.events.ModifyListener; 33 import org.eclipse.swt.events.SelectionAdapter; 34 import org.eclipse.swt.events.SelectionEvent; 35 import org.eclipse.swt.graphics.Point; 36 import org.eclipse.swt.graphics.Rectangle; 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.Combo; 41 import org.eclipse.swt.widgets.Composite; 42 import org.eclipse.swt.widgets.Control; 43 import org.eclipse.swt.widgets.Group; 44 import org.eclipse.swt.widgets.Label; 45 import org.eclipse.swt.widgets.Layout; 46 import org.eclipse.swt.widgets.Text; 47 48 import org.eclipse.jface.dialogs.IDialogConstants; 49 import org.eclipse.jface.dialogs.IDialogSettings; 50 51 import org.eclipse.jdt.internal.corext.util.Messages; 52 53 import org.eclipse.jdt.ui.JavaUI; 54 55 import org.eclipse.jdt.internal.ui.JavaPlugin; 56 import org.eclipse.jdt.internal.ui.util.PixelConverter; 57 58 59 public abstract class ModifyDialogTabPage { 60 61 public interface IModificationListener { 62 63 void updateStatus(IStatus status); 64 65 void valuesModified(); 66 67 } 68 69 74 protected final Observer fUpdater= new Observer () { 75 public void update(Observable o, Object arg) { 76 doUpdatePreview(); 77 notifyValuesModified(); 78 } 79 }; 80 81 82 87 protected abstract class Preference extends Observable { 88 private final Map fPreferences; 89 private boolean fEnabled; 90 private String fKey; 91 92 97 public Preference(Map preferences, String key) { 98 fPreferences= preferences; 99 fEnabled= true; 100 fKey= key; 101 } 102 105 protected final Map getPreferences() { 106 return fPreferences; 107 } 108 109 113 public final void setEnabled(boolean enabled) { 114 fEnabled= enabled; 115 updateWidget(); 116 } 117 118 121 public final boolean getEnabled() { 122 return fEnabled; 123 } 124 125 129 public final void setKey(String key) { 130 if (key == null || !fKey.equals(key)) { 131 fKey= key; 132 updateWidget(); 133 } 134 } 135 138 public final String getKey() { 139 return fKey; 140 } 141 142 148 public abstract Control getControl(); 149 150 154 protected abstract void updateWidget(); 155 } 156 157 160 protected class ButtonPreference extends Preference { 161 private final String [] fValues; 162 private final Button fCheckbox; 163 164 174 public ButtonPreference(Composite composite, int numColumns, 175 Map preferences, String key, 176 String [] values, String text, int style) { 177 super(preferences, key); 178 if (values == null || text == null) 179 throw new IllegalArgumentException (FormatterMessages.ModifyDialogTabPage_error_msg_values_text_unassigned); 180 fValues= values; 181 182 fCheckbox= new Button(composite, style); 183 fCheckbox.setText(text); 184 fCheckbox.setLayoutData(createGridData(numColumns, GridData.FILL_HORIZONTAL, SWT.DEFAULT)); 185 fCheckbox.setFont(composite.getFont()); 186 187 updateWidget(); 188 189 fCheckbox.addSelectionListener(new SelectionAdapter() { 190 public void widgetSelected(SelectionEvent e) { 191 checkboxChecked(((Button)e.widget).getSelection()); 192 } 193 }); 194 } 195 196 protected void checkboxChecked(boolean state) { 197 getPreferences().put(getKey(), state ? fValues[1] : fValues[0]); 198 setChanged(); 199 notifyObservers(); 200 } 201 202 protected void updateWidget() { 203 if (getKey() != null) { 204 fCheckbox.setEnabled(getEnabled()); 205 fCheckbox.setSelection(getChecked()); 206 } else { 207 fCheckbox.setSelection(false); 208 fCheckbox.setEnabled(false); 209 } 210 } 211 212 public boolean getChecked() { 213 return fValues[1].equals(getPreferences().get(getKey())); 214 } 215 216 public void setChecked(boolean checked) { 217 getPreferences().put(getKey(), checked ? fValues[1] : fValues[0]); 218 updateWidget(); 219 checkboxChecked(checked); 220 } 221 222 public Control getControl() { 223 return fCheckbox; 224 } 225 } 226 227 protected final class CheckboxPreference extends ButtonPreference { 228 public CheckboxPreference(Composite composite, int numColumns, Map preferences, String key, String [] values, String text) { 229 super(composite, numColumns, preferences, key, values, text, SWT.CHECK); 230 } 231 } 232 233 protected final class RadioPreference extends ButtonPreference { 234 public RadioPreference(Composite composite, int numColumns, Map preferences, String key, String [] values, String text) { 235 super(composite, numColumns, preferences, key, values, text, SWT.RADIO); 236 } 237 } 238 239 242 protected final class ComboPreference extends Preference { 243 private final String [] fItems; 244 private final String [] fValues; 245 private final Combo fCombo; 246 247 257 public ComboPreference(Composite composite, int numColumns, 258 Map preferences, String key, 259 String [] values, String text, String [] items) { 260 super(preferences, key); 261 if (values == null || items == null || text == null) 262 throw new IllegalArgumentException (FormatterMessages.ModifyDialogTabPage_error_msg_values_items_text_unassigned); 263 fValues= values; 264 fItems= items; 265 createLabel(numColumns - 1, composite, text); 266 fCombo= new Combo(composite, SWT.SINGLE | SWT.READ_ONLY); 267 fCombo.setFont(composite.getFont()); 268 fCombo.setItems(items); 269 270 int max= 0; 271 for (int i= 0; i < items.length; i++) 272 if (items[i].length() > max) max= items[i].length(); 273 274 fCombo.setLayoutData(createGridData(1, GridData.HORIZONTAL_ALIGN_FILL, fCombo.computeSize(SWT.DEFAULT, SWT.DEFAULT).x)); 275 276 updateWidget(); 277 278 fCombo.addSelectionListener(new SelectionAdapter() { 279 public void widgetSelected(SelectionEvent e) { 280 comboSelected(((Combo)e.widget).getSelectionIndex()); 281 } 282 }); 283 } 284 285 protected void comboSelected(int index) { 286 getPreferences().put(getKey(), fValues[index]); 287 setChanged(); 288 notifyObservers(fValues[index]); 289 } 290 291 protected void updateWidget() { 292 if (getKey() != null) { 293 fCombo.setEnabled(getEnabled()); 294 fCombo.setText(getSelectedItem()); 295 } else { 296 fCombo.setText(""); fCombo.setEnabled(false); 298 } 299 } 300 301 public String getSelectedItem() { 302 final String selected= (String )getPreferences().get(getKey()); 303 for (int i= 0; i < fValues.length; i++) { 304 if (fValues[i].equals(selected)) { 305 return fItems[i]; 306 } 307 } 308 return ""; } 310 311 public boolean hasValue(String value) { 312 return value.equals(getPreferences().get(getKey())); 313 } 314 315 public Control getControl() { 316 return fCombo; 317 } 318 } 319 320 323 protected final class NumberPreference extends Preference { 324 325 private final int fMinValue, fMaxValue; 326 private final Label fNumberLabel; 327 private final Text fNumberText; 328 329 protected int fSelected; 330 protected int fOldSelected; 331 332 333 343 public NumberPreference(Composite composite, int numColumns, 344 Map preferences, String key, 345 int minValue, int maxValue, String text) { 346 super(preferences, key); 347 348 fNumberLabel= createLabel(numColumns - 1, composite, text, GridData.FILL_HORIZONTAL); 349 fNumberText= new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.RIGHT); 350 fNumberText.setFont(composite.getFont()); 351 352 final int length= Integer.toString(maxValue).length() + 3; 353 fNumberText.setLayoutData(createGridData(1, GridData.HORIZONTAL_ALIGN_END, fPixelConverter.convertWidthInCharsToPixels(length))); 354 355 fMinValue= minValue; 356 fMaxValue= maxValue; 357 358 updateWidget(); 359 360 fNumberText.addFocusListener(new FocusListener() { 361 public void focusGained(FocusEvent e) { 362 NumberPreference.this.focusGained(); 363 } 364 public void focusLost(FocusEvent e) { 365 NumberPreference.this.focusLost(); 366 } 367 }); 368 369 fNumberText.addModifyListener(new ModifyListener() { 370 public void modifyText(ModifyEvent e) { 371 fieldModified(); 372 } 373 }); 374 } 375 376 private IStatus createErrorStatus() { 377 return new Status(IStatus.ERROR, JavaPlugin.getPluginId(), 0, Messages.format(FormatterMessages.ModifyDialogTabPage_NumberPreference_error_invalid_value, new String [] {Integer.toString(fMinValue), Integer.toString(fMaxValue)}), null); 378 379 } 380 381 protected void focusGained() { 382 fOldSelected= fSelected; 383 fNumberText.setSelection(0, fNumberText.getCharCount()); 384 } 385 386 protected void focusLost() { 387 updateStatus(null); 388 final String input= fNumberText.getText(); 389 if (!validInput(input)) 390 fSelected= fOldSelected; 391 else 392 fSelected= Integer.parseInt(input); 393 if (fSelected != fOldSelected) { 394 saveSelected(); 395 fNumberText.setText(Integer.toString(fSelected)); 396 } 397 } 398 399 400 protected void fieldModified() { 401 final String trimInput= fNumberText.getText().trim(); 402 final boolean valid= validInput(trimInput); 403 404 updateStatus(valid ? null : createErrorStatus()); 405 406 if (valid) { 407 final int number= Integer.parseInt(trimInput); 408 if (fSelected != number) { 409 fSelected= number; 410 saveSelected(); 411 } 412 } 413 } 414 415 private boolean validInput(String trimInput) { 416 int number; 417 418 try { 419 number= Integer.parseInt(trimInput); 420 } catch (NumberFormatException x) { 421 return false; 422 } 423 424 if (number < fMinValue) return false; 425 if (number > fMaxValue) return false; 426 return true; 427 } 428 429 private void saveSelected() { 430 getPreferences().put(getKey(), Integer.toString(fSelected)); 431 setChanged(); 432 notifyObservers(); 433 } 434 435 protected void updateWidget() { 436 final boolean hasKey= getKey() != null; 437 438 fNumberLabel.setEnabled(hasKey && getEnabled()); 439 fNumberText.setEnabled(hasKey && getEnabled()); 440 441 if (hasKey) { 442 String s= (String )getPreferences().get(getKey()); 443 try { 444 fSelected= Integer.parseInt(s); 445 } catch (NumberFormatException e) { 446 final String message= Messages.format(FormatterMessages.ModifyDialogTabPage_NumberPreference_error_invalid_key, getKey()); 447 JavaPlugin.log(new Status(IStatus.ERROR, JavaPlugin.getPluginId(), IStatus.OK, message, e)); 448 s= ""; } 450 fNumberText.setText(s); 451 } else { 452 fNumberText.setText(""); } 454 } 455 456 public Control getControl() { 457 return fNumberText; 458 } 459 } 460 461 462 472 protected final static class DefaultFocusManager extends FocusAdapter { 473 474 private final static String PREF_LAST_FOCUS_INDEX= JavaUI.ID_PLUGIN + "formatter_page.modify_dialog_tab_page.last_focus_index"; 476 private final IDialogSettings fDialogSettings; 477 478 private final Map fItemMap; 479 private final List fItemList; 480 481 private int fIndex; 482 483 public DefaultFocusManager() { 484 fDialogSettings= JavaPlugin.getDefault().getDialogSettings(); 485 fItemMap= new HashMap (); 486 fItemList= new ArrayList (); 487 fIndex= 0; 488 } 489 490 public void focusGained(FocusEvent e) { 491 fDialogSettings.put(PREF_LAST_FOCUS_INDEX, ((Integer )fItemMap.get(e.widget)).intValue()); 492 } 493 494 public void add(Control control) { 495 control.addFocusListener(this); 496 fItemList.add(fIndex, control); 497 fItemMap.put(control, new Integer (fIndex++)); 498 } 499 500 public void add(Preference preference) { 501 final Control control= preference.getControl(); 502 if (control != null) 503 add(control); 504 } 505 506 public boolean isUsed() { 507 return fIndex != 0; 508 } 509 510 public void restoreFocus() { 511 int index= 0; 512 try { 513 index= fDialogSettings.getInt(PREF_LAST_FOCUS_INDEX); 514 if ((index >= 0) && (index <= fItemList.size() - 1)) { 516 ((Control)fItemList.get(index)).setFocus(); 517 } 518 } catch (NumberFormatException ex) { 519 } 521 } 522 523 public void resetFocus() { 524 fDialogSettings.put(PREF_LAST_FOCUS_INDEX, -1); 525 } 526 } 527 528 532 private static class PageLayout extends Layout { 533 534 private final ScrolledComposite fContainer; 535 private final int fMinimalWidth; 536 private final int fMinimalHight; 537 538 private PageLayout(ScrolledComposite container, int minimalWidth, int minimalHight) { 539 fContainer= container; 540 fMinimalWidth= minimalWidth; 541 fMinimalHight= minimalHight; 542 } 543 544 public Point computeSize(Composite composite, int wHint, int hHint, boolean force) { 545 if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { 546 return new Point(wHint, hHint); 547 } 548 549 int x = fMinimalWidth; 550 int y = fMinimalHight; 551 Control[] children = composite.getChildren(); 552 for (int i = 0; i < children.length; i++) { 553 Point size = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, force); 554 x = Math.max(x, size.x); 555 y = Math.max(y, size.y); 556 } 557 558 Rectangle area= fContainer.getClientArea(); 559 if (area.width > x) { 560 fContainer.setExpandHorizontal(true); 561 } else { 562 fContainer.setExpandHorizontal(false); 563 } 564 565 if (area.height > y) { 566 fContainer.setExpandVertical(true); 567 } else { 568 fContainer.setExpandVertical(false); 569 } 570 571 if (wHint != SWT.DEFAULT) { 572 x = wHint; 573 } 574 if (hHint != SWT.DEFAULT) { 575 y = hHint; 576 } 577 578 return new Point(x, y); 579 } 580 581 public void layout(Composite composite, boolean force) { 582 Rectangle rect = composite.getClientArea(); 583 Control[] children = composite.getChildren(); 584 for (int i = 0; i < children.length; i++) { 585 children[i].setSize(rect.width, rect.height); 586 } 587 } 588 } 589 590 600 protected final DefaultFocusManager fDefaultFocusManager; 601 602 605 protected PixelConverter fPixelConverter; 606 607 608 611 protected final Map fWorkingValues; 612 613 616 private final IModificationListener fModifyListener; 617 618 619 622 public ModifyDialogTabPage(IModificationListener modifyListener, Map workingValues) { 623 fWorkingValues= workingValues; 624 fModifyListener= modifyListener; 625 fDefaultFocusManager= new DefaultFocusManager(); 626 } 627 628 635 public final Composite createContents(Composite parent) { 636 final int numColumns= 4; 637 638 if (fPixelConverter == null) { 639 fPixelConverter= new PixelConverter(parent); 640 } 641 642 final SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL); 643 sashForm.setFont(parent.getFont()); 644 645 Composite scrollContainer = new Composite(sashForm, SWT.NONE); 646 647 GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); 648 scrollContainer.setLayoutData(gridData); 649 650 GridLayout layout= new GridLayout(2, false); 651 layout.marginHeight= 0; 652 layout.marginWidth= 0; 653 layout.horizontalSpacing= 0; 654 layout.verticalSpacing= 0; 655 scrollContainer.setLayout(layout); 656 657 ScrolledComposite scroll= new ScrolledComposite(scrollContainer, SWT.V_SCROLL | SWT.H_SCROLL); 658 scroll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 659 scroll.setExpandHorizontal(true); 660 scroll.setExpandVertical(true); 661 662 final Composite settingsContainer= new Composite(scroll, SWT.NONE); 663 settingsContainer.setFont(sashForm.getFont()); 664 665 scroll.setContent(settingsContainer); 666 667 settingsContainer.setLayout(new PageLayout(scroll, 400, 400)); 668 settingsContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 669 670 Composite settingsPane= new Composite(settingsContainer, SWT.NONE); 671 settingsPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 672 673 layout= new GridLayout(numColumns, false); 674 layout.verticalSpacing= (int)(1.5 * fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING)); 675 layout.horizontalSpacing= fPixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); 676 layout.marginHeight= fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); 677 layout.marginWidth= fPixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); 678 settingsPane.setLayout(layout); 679 doCreatePreferences(settingsPane, numColumns); 680 681 settingsContainer.setSize(settingsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 682 683 scroll.addControlListener(new ControlListener() { 684 685 public void controlMoved(ControlEvent e) { 686 } 687 688 public void controlResized(ControlEvent e) { 689 settingsContainer.setSize(settingsContainer.computeSize(SWT.DEFAULT, SWT.DEFAULT)); 690 } 691 }); 692 693 Label sashHandle = new Label(scrollContainer, SWT.SEPARATOR | SWT.VERTICAL); 694 gridData= new GridData(SWT.RIGHT, SWT.FILL, false, true); 695 sashHandle.setLayoutData(gridData); 696 697 final Composite previewPane= new Composite(sashForm, SWT.NONE); 698 previewPane.setLayout(createGridLayout(numColumns, true)); 699 previewPane.setFont(sashForm.getFont()); 700 doCreatePreviewPane(previewPane, numColumns); 701 702 initializePage(); 703 704 sashForm.setWeights(new int [] {3, 3}); 705 return sashForm; 706 } 707 708 713 protected abstract void initializePage(); 714 715 716 721 protected abstract void doCreatePreferences(Composite composite, int numColumns); 722 723 724 732 protected Composite doCreatePreviewPane(Composite composite, int numColumns) { 733 734 createLabel(numColumns, composite, FormatterMessages.ModifyDialogTabPage_preview_label_text); 735 736 final JavaPreview preview= doCreateJavaPreview(composite); 737 fDefaultFocusManager.add(preview.getControl()); 738 739 final GridData gd= createGridData(numColumns, GridData.FILL_BOTH, 0); 740 gd.widthHint= 0; 741 gd.heightHint=0; 742 preview.getControl().setLayoutData(gd); 743 744 return composite; 745 } 746 747 748 756 protected abstract JavaPreview doCreateJavaPreview(Composite parent); 757 758 759 766 final public void makeVisible() { 767 fDefaultFocusManager.resetFocus(); 768 doUpdatePreview(); 769 } 770 771 774 protected abstract void doUpdatePreview(); 775 776 protected void notifyValuesModified() { 777 fModifyListener.valuesModified(); 778 } 779 785 public void setInitialFocus() { 786 if (fDefaultFocusManager.isUsed()) { 787 fDefaultFocusManager.restoreFocus(); 788 } 789 } 790 791 792 797 protected void updateStatus(IStatus status) { 798 fModifyListener.updateStatus(status); 799 } 800 801 804 805 809 protected GridLayout createGridLayout(int numColumns, boolean margins) { 810 final GridLayout layout= new GridLayout(numColumns, false); 811 layout.verticalSpacing= fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); 812 layout.horizontalSpacing= fPixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); 813 if (margins) { 814 layout.marginHeight= fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); 815 layout.marginWidth= fPixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); 816 } else { 817 layout.marginHeight= 0; 818 layout.marginWidth= 0; 819 } 820 return layout; 821 } 822 823 826 protected static GridData createGridData(int numColumns, int style, int widthHint) { 827 final GridData gd= new GridData(style); 828 gd.horizontalSpan= numColumns; 829 gd.widthHint= widthHint; 830 return gd; 831 } 832 833 834 837 protected static Label createLabel(int numColumns, Composite parent, String text) { 838 return createLabel(numColumns, parent, text, GridData.FILL_HORIZONTAL); 839 } 840 841 844 protected static Label createLabel(int numColumns, Composite parent, String text, int gridDataStyle) { 845 final Label label= new Label(parent, SWT.WRAP); 846 label.setFont(parent.getFont()); 847 label.setText(text); 848 849 PixelConverter pixelConverter= new PixelConverter(parent); 850 label.setLayoutData(createGridData(numColumns, gridDataStyle, pixelConverter.convertHorizontalDLUsToPixels(150))); 851 return label; 852 } 853 854 857 protected Group createGroup(int numColumns, Composite parent, String text ) { 858 final Group group= new Group(parent, SWT.NONE); 859 group.setFont(parent.getFont()); 860 group.setLayoutData(createGridData(numColumns, GridData.FILL_HORIZONTAL, SWT.DEFAULT)); 861 862 final GridLayout layout= new GridLayout(numColumns, false); 863 layout.verticalSpacing= fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); 864 layout.horizontalSpacing= fPixelConverter.convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); 865 layout.marginHeight= fPixelConverter.convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); 866 867 870 group.setLayout(layout); group.setText(text); 872 return group; 873 } 874 875 876 880 protected NumberPreference createNumberPref(Composite composite, int numColumns, String name, String key, 881 int minValue, int maxValue) { 882 final NumberPreference pref= new NumberPreference(composite, numColumns, fWorkingValues, 883 key, minValue, maxValue, name); 884 fDefaultFocusManager.add(pref); 885 pref.addObserver(fUpdater); 886 return pref; 887 } 888 889 893 protected ComboPreference createComboPref(Composite composite, int numColumns, String name, 894 String key, String [] values, String [] items) { 895 final ComboPreference pref= new ComboPreference(composite, numColumns, 896 fWorkingValues, key, values, name, items); 897 fDefaultFocusManager.add(pref); 898 pref.addObserver(fUpdater); 899 return pref; 900 } 901 902 906 protected CheckboxPreference createCheckboxPref(Composite composite, int numColumns, String name, String key, 907 String [] values) { 908 final CheckboxPreference pref= new CheckboxPreference(composite, numColumns, 909 fWorkingValues, key, values, name); 910 fDefaultFocusManager.add(pref); 911 pref.addObserver(fUpdater); 912 return pref; 913 } 914 915 protected RadioPreference createRadioPref(Composite composite, int numColumns, String name, String key, 916 String [] values) { 917 final RadioPreference pref= new RadioPreference(composite, numColumns, 918 fWorkingValues, key, values, name); 919 fDefaultFocusManager.add(pref); 920 pref.addObserver(fUpdater); 921 return pref; 922 } 923 924 925 928 protected static String createPreviewHeader(String title) { 929 return "/**\n* " + title + "\n*/\n"; } 931 } 932 | Popular Tags |