0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2006 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.internal.ui.preferences;
0011:
0012: import java.io.BufferedReader;
0013: import java.io.IOException;
0014: import java.io.InputStreamReader;
0015: import java.util.ArrayList;
0016: import java.util.Iterator;
0017:
0018: import org.eclipse.core.runtime.Preferences;
0019:
0020: import org.eclipse.swt.SWT;
0021: import org.eclipse.swt.events.SelectionAdapter;
0022: import org.eclipse.swt.events.SelectionEvent;
0023: import org.eclipse.swt.events.SelectionListener;
0024: import org.eclipse.swt.graphics.Font;
0025: import org.eclipse.swt.graphics.FontMetrics;
0026: import org.eclipse.swt.graphics.GC;
0027: import org.eclipse.swt.graphics.Point;
0028: import org.eclipse.swt.graphics.RGB;
0029: import org.eclipse.swt.layout.GridData;
0030: import org.eclipse.swt.layout.GridLayout;
0031: import org.eclipse.swt.widgets.Button;
0032: import org.eclipse.swt.widgets.Composite;
0033: import org.eclipse.swt.widgets.Control;
0034: import org.eclipse.swt.widgets.Label;
0035: import org.eclipse.swt.widgets.Link;
0036: import org.eclipse.swt.widgets.ScrollBar;
0037: import org.eclipse.swt.widgets.Scrollable;
0038:
0039: import org.eclipse.jface.dialogs.Dialog;
0040: import org.eclipse.jface.preference.ColorSelector;
0041: import org.eclipse.jface.preference.IPreferenceStore;
0042: import org.eclipse.jface.preference.PreferenceConverter;
0043: import org.eclipse.jface.resource.JFaceResources;
0044: import org.eclipse.jface.util.PropertyChangeEvent;
0045: import org.eclipse.jface.viewers.ISelectionChangedListener;
0046: import org.eclipse.jface.viewers.IStructuredSelection;
0047: import org.eclipse.jface.viewers.ITreeContentProvider;
0048: import org.eclipse.jface.viewers.LabelProvider;
0049: import org.eclipse.jface.viewers.SelectionChangedEvent;
0050: import org.eclipse.jface.viewers.StructuredSelection;
0051: import org.eclipse.jface.viewers.StructuredViewer;
0052: import org.eclipse.jface.viewers.TreeViewer;
0053: import org.eclipse.jface.viewers.Viewer;
0054: import org.eclipse.jface.viewers.ViewerComparator;
0055:
0056: import org.eclipse.jface.text.BadLocationException;
0057: import org.eclipse.jface.text.Document;
0058: import org.eclipse.jface.text.IDocument;
0059:
0060: import org.eclipse.ui.dialogs.PreferencesUtil;
0061: import org.eclipse.ui.texteditor.ChainedPreferenceStore;
0062:
0063: import org.eclipse.ui.editors.text.EditorsUI;
0064:
0065: import org.eclipse.jdt.core.JavaCore;
0066:
0067: import org.eclipse.jdt.ui.PreferenceConstants;
0068: import org.eclipse.jdt.ui.text.IColorManager;
0069: import org.eclipse.jdt.ui.text.IJavaPartitions;
0070:
0071: import org.eclipse.jdt.internal.ui.JavaPlugin;
0072: import org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer;
0073: import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlighting;
0074: import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingManager;
0075: import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightings;
0076: import org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingManager.HighlightedRange;
0077: import org.eclipse.jdt.internal.ui.text.JavaColorManager;
0078: import org.eclipse.jdt.internal.ui.text.PreferencesAdapter;
0079: import org.eclipse.jdt.internal.ui.text.SimpleJavaSourceViewerConfiguration;
0080: import org.eclipse.jdt.internal.ui.util.PixelConverter;
0081:
0082: /**
0083: * Configures Java Editor hover preferences.
0084: *
0085: * @since 2.1
0086: */
0087: class JavaEditorColoringConfigurationBlock extends
0088: AbstractConfigurationBlock {
0089:
0090: /**
0091: * Item in the highlighting color list.
0092: *
0093: * @since 3.0
0094: */
0095: private static class HighlightingColorListItem {
0096: /** Display name */
0097: private String fDisplayName;
0098: /** Color preference key */
0099: private String fColorKey;
0100: /** Bold preference key */
0101: private String fBoldKey;
0102: /** Italic preference key */
0103: private String fItalicKey;
0104: /**
0105: * Strikethrough preference key.
0106: * @since 3.1
0107: */
0108: private String fStrikethroughKey;
0109: /** Underline preference key.
0110: * @since 3.1
0111: */
0112: private String fUnderlineKey;
0113:
0114: /**
0115: * Initialize the item with the given values.
0116: * @param displayName the display name
0117: * @param colorKey the color preference key
0118: * @param boldKey the bold preference key
0119: * @param italicKey the italic preference key
0120: * @param strikethroughKey the strikethrough preference key
0121: * @param underlineKey the underline preference key
0122: */
0123: public HighlightingColorListItem(String displayName,
0124: String colorKey, String boldKey, String italicKey,
0125: String strikethroughKey, String underlineKey) {
0126: fDisplayName = displayName;
0127: fColorKey = colorKey;
0128: fBoldKey = boldKey;
0129: fItalicKey = italicKey;
0130: fStrikethroughKey = strikethroughKey;
0131: fUnderlineKey = underlineKey;
0132: }
0133:
0134: /**
0135: * @return the bold preference key
0136: */
0137: public String getBoldKey() {
0138: return fBoldKey;
0139: }
0140:
0141: /**
0142: * @return the bold preference key
0143: */
0144: public String getItalicKey() {
0145: return fItalicKey;
0146: }
0147:
0148: /**
0149: * @return the strikethrough preference key
0150: * @since 3.1
0151: */
0152: public String getStrikethroughKey() {
0153: return fStrikethroughKey;
0154: }
0155:
0156: /**
0157: * @return the underline preference key
0158: * @since 3.1
0159: */
0160: public String getUnderlineKey() {
0161: return fUnderlineKey;
0162: }
0163:
0164: /**
0165: * @return the color preference key
0166: */
0167: public String getColorKey() {
0168: return fColorKey;
0169: }
0170:
0171: /**
0172: * @return the display name
0173: */
0174: public String getDisplayName() {
0175: return fDisplayName;
0176: }
0177: }
0178:
0179: private static class SemanticHighlightingColorListItem extends
0180: HighlightingColorListItem {
0181:
0182: /** Enablement preference key */
0183: private final String fEnableKey;
0184:
0185: /**
0186: * Initialize the item with the given values.
0187: * @param displayName the display name
0188: * @param colorKey the color preference key
0189: * @param boldKey the bold preference key
0190: * @param italicKey the italic preference key
0191: * @param strikethroughKey the strikethroughKey preference key
0192: * @param underlineKey the underlineKey preference key
0193: * @param enableKey the enable preference key
0194: */
0195: public SemanticHighlightingColorListItem(String displayName,
0196: String colorKey, String boldKey, String italicKey,
0197: String strikethroughKey, String underlineKey,
0198: String enableKey) {
0199: super (displayName, colorKey, boldKey, italicKey,
0200: strikethroughKey, underlineKey);
0201: fEnableKey = enableKey;
0202: }
0203:
0204: /**
0205: * @return the enablement preference key
0206: */
0207: public String getEnableKey() {
0208: return fEnableKey;
0209: }
0210: }
0211:
0212: /**
0213: * Color list label provider.
0214: *
0215: * @since 3.0
0216: */
0217: private class ColorListLabelProvider extends LabelProvider {
0218: /*
0219: * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
0220: */
0221: public String getText(Object element) {
0222: if (element instanceof String)
0223: return (String) element;
0224: return ((HighlightingColorListItem) element)
0225: .getDisplayName();
0226: }
0227: }
0228:
0229: /**
0230: * Color list content provider.
0231: *
0232: * @since 3.0
0233: */
0234: private class ColorListContentProvider implements
0235: ITreeContentProvider {
0236:
0237: /*
0238: * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
0239: */
0240: public Object[] getElements(Object inputElement) {
0241: return new String[] { fJavaCategory, fJavadocCategory,
0242: fCommentsCategory };
0243: }
0244:
0245: /*
0246: * @see org.eclipse.jface.viewers.IContentProvider#dispose()
0247: */
0248: public void dispose() {
0249: }
0250:
0251: /*
0252: * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
0253: */
0254: public void inputChanged(Viewer viewer, Object oldInput,
0255: Object newInput) {
0256: }
0257:
0258: public Object[] getChildren(Object parentElement) {
0259: if (parentElement instanceof String) {
0260: String entry = (String) parentElement;
0261: if (fJavaCategory.equals(entry))
0262: return fListModel.subList(7, fListModel.size())
0263: .toArray();
0264: if (fJavadocCategory.equals(entry))
0265: return fListModel.subList(0, 4).toArray();
0266: if (fCommentsCategory.equals(entry))
0267: return fListModel.subList(4, 7).toArray();
0268: }
0269: return new Object[0];
0270: }
0271:
0272: public Object getParent(Object element) {
0273: if (element instanceof String)
0274: return null;
0275: int index = fListModel.indexOf(element);
0276: if (index < 4)
0277: return fJavadocCategory;
0278: if (index >= 7)
0279: return fJavaCategory;
0280: return fCommentsCategory;
0281: }
0282:
0283: public boolean hasChildren(Object element) {
0284: return element instanceof String;
0285: }
0286: }
0287:
0288: private static final String BOLD = PreferenceConstants.EDITOR_BOLD_SUFFIX;
0289: /**
0290: * Preference key suffix for italic preferences.
0291: * @since 3.0
0292: */
0293: private static final String ITALIC = PreferenceConstants.EDITOR_ITALIC_SUFFIX;
0294: /**
0295: * Preference key suffix for strikethrough preferences.
0296: * @since 3.1
0297: */
0298: private static final String STRIKETHROUGH = PreferenceConstants.EDITOR_STRIKETHROUGH_SUFFIX;
0299: /**
0300: * Preference key suffix for underline preferences.
0301: * @since 3.1
0302: */
0303: private static final String UNDERLINE = PreferenceConstants.EDITOR_UNDERLINE_SUFFIX;
0304:
0305: private static final String COMPILER_TASK_TAGS = JavaCore.COMPILER_TASK_TAGS;
0306: /**
0307: * The keys of the overlay store.
0308: */
0309: private final String[][] fSyntaxColorListModel = new String[][] {
0310: {
0311: PreferencesMessages.JavaEditorPreferencePage_javaDocKeywords,
0312: PreferenceConstants.EDITOR_JAVADOC_KEYWORD_COLOR },
0313: {
0314: PreferencesMessages.JavaEditorPreferencePage_javaDocHtmlTags,
0315: PreferenceConstants.EDITOR_JAVADOC_TAG_COLOR },
0316: {
0317: PreferencesMessages.JavaEditorPreferencePage_javaDocLinks,
0318: PreferenceConstants.EDITOR_JAVADOC_LINKS_COLOR },
0319: {
0320: PreferencesMessages.JavaEditorPreferencePage_javaDocOthers,
0321: PreferenceConstants.EDITOR_JAVADOC_DEFAULT_COLOR },
0322: {
0323: PreferencesMessages.JavaEditorPreferencePage_multiLineComment,
0324: PreferenceConstants.EDITOR_MULTI_LINE_COMMENT_COLOR },
0325: {
0326: PreferencesMessages.JavaEditorPreferencePage_singleLineComment,
0327: PreferenceConstants.EDITOR_SINGLE_LINE_COMMENT_COLOR },
0328: {
0329: PreferencesMessages.JavaEditorPreferencePage_javaCommentTaskTags,
0330: PreferenceConstants.EDITOR_TASK_TAG_COLOR },
0331: { PreferencesMessages.JavaEditorPreferencePage_keywords,
0332: PreferenceConstants.EDITOR_JAVA_KEYWORD_COLOR },
0333: {
0334: PreferencesMessages.JavaEditorPreferencePage_returnKeyword,
0335: PreferenceConstants.EDITOR_JAVA_KEYWORD_RETURN_COLOR },
0336: { PreferencesMessages.JavaEditorPreferencePage_operators,
0337: PreferenceConstants.EDITOR_JAVA_OPERATOR_COLOR },
0338: { PreferencesMessages.JavaEditorPreferencePage_brackets,
0339: PreferenceConstants.EDITOR_JAVA_BRACKET_COLOR },
0340: { PreferencesMessages.JavaEditorPreferencePage_strings,
0341: PreferenceConstants.EDITOR_STRING_COLOR },
0342: { PreferencesMessages.JavaEditorPreferencePage_others,
0343: PreferenceConstants.EDITOR_JAVA_DEFAULT_COLOR }, };
0344:
0345: private final String fJavaCategory = PreferencesMessages.JavaEditorPreferencePage_coloring_category_java;
0346: private final String fJavadocCategory = PreferencesMessages.JavaEditorPreferencePage_coloring_category_javadoc;
0347: private final String fCommentsCategory = PreferencesMessages.JavaEditorPreferencePage_coloring_category_comments;
0348:
0349: private ColorSelector fSyntaxForegroundColorEditor;
0350: private Label fColorEditorLabel;
0351: private Button fBoldCheckBox;
0352: private Button fEnableCheckbox;
0353: /**
0354: * Check box for italic preference.
0355: * @since 3.0
0356: */
0357: private Button fItalicCheckBox;
0358: /**
0359: * Check box for strikethrough preference.
0360: * @since 3.1
0361: */
0362: private Button fStrikethroughCheckBox;
0363: /**
0364: * Check box for underline preference.
0365: * @since 3.1
0366: */
0367: private Button fUnderlineCheckBox;
0368: /**
0369: * Highlighting color list
0370: * @since 3.0
0371: */
0372: private final java.util.List fListModel = new ArrayList();
0373: /**
0374: * Highlighting color list viewer
0375: * @since 3.0
0376: */
0377: private StructuredViewer fListViewer;
0378: /**
0379: * Semantic highlighting manager
0380: * @since 3.0
0381: */
0382: private SemanticHighlightingManager fSemanticHighlightingManager;
0383: /**
0384: * The previewer.
0385: * @since 3.0
0386: */
0387: private JavaSourceViewer fPreviewViewer;
0388: /**
0389: * The color manager.
0390: * @since 3.1
0391: */
0392: private IColorManager fColorManager;
0393: /**
0394: * The font metrics.
0395: * @since 3.1
0396: */
0397: private FontMetrics fFontMetrics;
0398:
0399: public JavaEditorColoringConfigurationBlock(
0400: OverlayPreferenceStore store) {
0401: super (store);
0402:
0403: fColorManager = new JavaColorManager(false);
0404:
0405: for (int i = 0, n = fSyntaxColorListModel.length; i < n; i++)
0406: fListModel.add(new HighlightingColorListItem(
0407: fSyntaxColorListModel[i][0],
0408: fSyntaxColorListModel[i][1],
0409: fSyntaxColorListModel[i][1] + BOLD,
0410: fSyntaxColorListModel[i][1] + ITALIC,
0411: fSyntaxColorListModel[i][1] + STRIKETHROUGH,
0412: fSyntaxColorListModel[i][1] + UNDERLINE));
0413:
0414: SemanticHighlighting[] semanticHighlightings = SemanticHighlightings
0415: .getSemanticHighlightings();
0416: for (int i = 0, n = semanticHighlightings.length; i < n; i++)
0417: fListModel
0418: .add(new SemanticHighlightingColorListItem(
0419: semanticHighlightings[i].getDisplayName(),
0420: SemanticHighlightings
0421: .getColorPreferenceKey(semanticHighlightings[i]),
0422: SemanticHighlightings
0423: .getBoldPreferenceKey(semanticHighlightings[i]),
0424: SemanticHighlightings
0425: .getItalicPreferenceKey(semanticHighlightings[i]),
0426: SemanticHighlightings
0427: .getStrikethroughPreferenceKey(semanticHighlightings[i]),
0428: SemanticHighlightings
0429: .getUnderlinePreferenceKey(semanticHighlightings[i]),
0430: SemanticHighlightings
0431: .getEnabledPreferenceKey(semanticHighlightings[i])));
0432:
0433: store.addKeys(createOverlayStoreKeys());
0434: }
0435:
0436: private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys() {
0437:
0438: ArrayList overlayKeys = new ArrayList();
0439:
0440: for (int i = 0, n = fListModel.size(); i < n; i++) {
0441: HighlightingColorListItem item = (HighlightingColorListItem) fListModel
0442: .get(i);
0443: overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
0444: OverlayPreferenceStore.STRING, item.getColorKey()));
0445: overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
0446: OverlayPreferenceStore.BOOLEAN, item.getBoldKey()));
0447: overlayKeys
0448: .add(new OverlayPreferenceStore.OverlayKey(
0449: OverlayPreferenceStore.BOOLEAN, item
0450: .getItalicKey()));
0451: overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
0452: OverlayPreferenceStore.BOOLEAN, item
0453: .getStrikethroughKey()));
0454: overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
0455: OverlayPreferenceStore.BOOLEAN, item
0456: .getUnderlineKey()));
0457:
0458: if (item instanceof SemanticHighlightingColorListItem)
0459: overlayKeys.add(new OverlayPreferenceStore.OverlayKey(
0460: OverlayPreferenceStore.BOOLEAN,
0461: ((SemanticHighlightingColorListItem) item)
0462: .getEnableKey()));
0463: }
0464:
0465: OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys
0466: .size()];
0467: overlayKeys.toArray(keys);
0468: return keys;
0469: }
0470:
0471: /**
0472: * Creates page for hover preferences.
0473: *
0474: * @param parent the parent composite
0475: * @return the control for the preference page
0476: */
0477: public Control createControl(Composite parent) {
0478: initializeDialogUnits(parent);
0479:
0480: ScrolledPageContent scrolled = new ScrolledPageContent(parent,
0481: SWT.H_SCROLL | SWT.V_SCROLL);
0482: scrolled.setExpandHorizontal(true);
0483: scrolled.setExpandVertical(true);
0484:
0485: Control control = createSyntaxPage(scrolled);
0486:
0487: scrolled.setContent(control);
0488: final Point size = control
0489: .computeSize(SWT.DEFAULT, SWT.DEFAULT);
0490: scrolled.setMinSize(size.x, size.y);
0491:
0492: return scrolled;
0493: }
0494:
0495: /**
0496: * Returns the number of pixels corresponding to the width of the given
0497: * number of characters.
0498: * <p>
0499: * This method may only be called after <code>initializeDialogUnits</code>
0500: * has been called.
0501: * </p>
0502: * <p>
0503: * Clients may call this framework method, but should not override it.
0504: * </p>
0505: *
0506: * @param chars
0507: * the number of characters
0508: * @return the number of pixels
0509: */
0510: private int convertWidthInCharsToPixels(int chars) {
0511: // test for failure to initialize for backward compatibility
0512: if (fFontMetrics == null)
0513: return 0;
0514: return Dialog.convertWidthInCharsToPixels(fFontMetrics, chars);
0515: }
0516:
0517: /**
0518: * Returns the number of pixels corresponding to the height of the given
0519: * number of characters.
0520: * <p>
0521: * This method may only be called after <code>initializeDialogUnits</code>
0522: * has been called.
0523: * </p>
0524: * <p>
0525: * Clients may call this framework method, but should not override it.
0526: * </p>
0527: *
0528: * @param chars
0529: * the number of characters
0530: * @return the number of pixels
0531: */
0532: private int convertHeightInCharsToPixels(int chars) {
0533: // test for failure to initialize for backward compatibility
0534: if (fFontMetrics == null)
0535: return 0;
0536: return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars);
0537: }
0538:
0539: public void initialize() {
0540: super .initialize();
0541:
0542: fListViewer.setInput(fListModel);
0543: fListViewer
0544: .setSelection(new StructuredSelection(fJavaCategory));
0545: }
0546:
0547: public void performDefaults() {
0548: super .performDefaults();
0549:
0550: handleSyntaxColorListSelection();
0551:
0552: uninstallSemanticHighlighting();
0553: installSemanticHighlighting();
0554:
0555: fPreviewViewer.invalidateTextPresentation();
0556: }
0557:
0558: /*
0559: * @see org.eclipse.jdt.internal.ui.preferences.IPreferenceConfigurationBlock#dispose()
0560: */
0561: public void dispose() {
0562: uninstallSemanticHighlighting();
0563: fColorManager.dispose();
0564:
0565: super .dispose();
0566: }
0567:
0568: private void handleSyntaxColorListSelection() {
0569: HighlightingColorListItem item = getHighlightingColorListItem();
0570: if (item == null) {
0571: fEnableCheckbox.setEnabled(false);
0572: fSyntaxForegroundColorEditor.getButton().setEnabled(false);
0573: fColorEditorLabel.setEnabled(false);
0574: fBoldCheckBox.setEnabled(false);
0575: fItalicCheckBox.setEnabled(false);
0576: fStrikethroughCheckBox.setEnabled(false);
0577: fUnderlineCheckBox.setEnabled(false);
0578: return;
0579: }
0580: RGB rgb = PreferenceConverter.getColor(getPreferenceStore(),
0581: item.getColorKey());
0582: fSyntaxForegroundColorEditor.setColorValue(rgb);
0583: fBoldCheckBox.setSelection(getPreferenceStore().getBoolean(
0584: item.getBoldKey()));
0585: fItalicCheckBox.setSelection(getPreferenceStore().getBoolean(
0586: item.getItalicKey()));
0587: fStrikethroughCheckBox.setSelection(getPreferenceStore()
0588: .getBoolean(item.getStrikethroughKey()));
0589: fUnderlineCheckBox.setSelection(getPreferenceStore()
0590: .getBoolean(item.getUnderlineKey()));
0591: if (item instanceof SemanticHighlightingColorListItem) {
0592: fEnableCheckbox.setEnabled(true);
0593: boolean enable = getPreferenceStore().getBoolean(
0594: ((SemanticHighlightingColorListItem) item)
0595: .getEnableKey());
0596: fEnableCheckbox.setSelection(enable);
0597: fSyntaxForegroundColorEditor.getButton().setEnabled(enable);
0598: fColorEditorLabel.setEnabled(enable);
0599: fBoldCheckBox.setEnabled(enable);
0600: fItalicCheckBox.setEnabled(enable);
0601: fStrikethroughCheckBox.setEnabled(enable);
0602: fUnderlineCheckBox.setEnabled(enable);
0603: } else {
0604: fSyntaxForegroundColorEditor.getButton().setEnabled(true);
0605: fColorEditorLabel.setEnabled(true);
0606: fBoldCheckBox.setEnabled(true);
0607: fItalicCheckBox.setEnabled(true);
0608: fStrikethroughCheckBox.setEnabled(true);
0609: fUnderlineCheckBox.setEnabled(true);
0610: fEnableCheckbox.setEnabled(false);
0611: fEnableCheckbox.setSelection(true);
0612: }
0613: }
0614:
0615: private Control createSyntaxPage(final Composite parent) {
0616:
0617: Composite colorComposite = new Composite(parent, SWT.NONE);
0618: GridLayout layout = new GridLayout();
0619: layout.marginHeight = 0;
0620: layout.marginWidth = 0;
0621: colorComposite.setLayout(layout);
0622:
0623: Link link = new Link(colorComposite, SWT.NONE);
0624: link
0625: .setText(PreferencesMessages.JavaEditorColoringConfigurationBlock_link);
0626: link.addSelectionListener(new SelectionAdapter() {
0627: public void widgetSelected(SelectionEvent e) {
0628: PreferencesUtil.createPreferenceDialogOn(parent
0629: .getShell(), e.text, null, null);
0630: }
0631: });
0632: // TODO replace by link-specific tooltips when
0633: // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=88866 gets fixed
0634: // link.setToolTipText(PreferencesMessages.JavaEditorColoringConfigurationBlock_link_tooltip);
0635:
0636: GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true,
0637: false);
0638: gridData.widthHint = 150; // only expand further if anyone else requires it
0639: gridData.horizontalSpan = 2;
0640: link.setLayoutData(gridData);
0641:
0642: addFiller(colorComposite, 1);
0643:
0644: Label label;
0645: label = new Label(colorComposite, SWT.LEFT);
0646: label
0647: .setText(PreferencesMessages.JavaEditorPreferencePage_coloring_element);
0648: label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0649:
0650: Composite editorComposite = new Composite(colorComposite,
0651: SWT.NONE);
0652: layout = new GridLayout();
0653: layout.numColumns = 2;
0654: layout.marginHeight = 0;
0655: layout.marginWidth = 0;
0656: editorComposite.setLayout(layout);
0657: GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
0658: editorComposite.setLayoutData(gd);
0659:
0660: fListViewer = new TreeViewer(editorComposite, SWT.SINGLE
0661: | SWT.BORDER);
0662: fListViewer.setLabelProvider(new ColorListLabelProvider());
0663: fListViewer.setContentProvider(new ColorListContentProvider());
0664: fListViewer.setComparator(new ViewerComparator() {
0665: public int category(Object element) {
0666: // don't sort the top level categories
0667: if (fJavaCategory.equals(element))
0668: return 0;
0669: if (fJavadocCategory.equals(element))
0670: return 1;
0671: if (fCommentsCategory.equals(element))
0672: return 2;
0673: // to sort semantic settings after partition based ones:
0674: // if (element instanceof SemanticHighlightingColorListItem)
0675: // return 1;
0676: return 0;
0677: }
0678: });
0679: gd = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, true);
0680: gd.heightHint = convertHeightInCharsToPixels(9);
0681: int maxWidth = 0;
0682: for (Iterator it = fListModel.iterator(); it.hasNext();) {
0683: HighlightingColorListItem item = (HighlightingColorListItem) it
0684: .next();
0685: maxWidth = Math.max(maxWidth,
0686: convertWidthInCharsToPixels(item.getDisplayName()
0687: .length()));
0688: }
0689: ScrollBar vBar = ((Scrollable) fListViewer.getControl())
0690: .getVerticalBar();
0691: if (vBar != null)
0692: maxWidth += vBar.getSize().x * 3; // scrollbars and tree indentation guess
0693: gd.widthHint = maxWidth;
0694:
0695: fListViewer.getControl().setLayoutData(gd);
0696:
0697: Composite stylesComposite = new Composite(editorComposite,
0698: SWT.NONE);
0699: layout = new GridLayout();
0700: layout.marginHeight = 0;
0701: layout.marginWidth = 0;
0702: layout.numColumns = 2;
0703: stylesComposite.setLayout(layout);
0704: stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
0705:
0706: fEnableCheckbox = new Button(stylesComposite, SWT.CHECK);
0707: fEnableCheckbox
0708: .setText(PreferencesMessages.JavaEditorPreferencePage_enable);
0709: gd = new GridData(GridData.FILL_HORIZONTAL);
0710: gd.horizontalAlignment = GridData.BEGINNING;
0711: gd.horizontalSpan = 2;
0712: fEnableCheckbox.setLayoutData(gd);
0713:
0714: fColorEditorLabel = new Label(stylesComposite, SWT.LEFT);
0715: fColorEditorLabel
0716: .setText(PreferencesMessages.JavaEditorPreferencePage_color);
0717: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0718: gd.horizontalIndent = 20;
0719: fColorEditorLabel.setLayoutData(gd);
0720:
0721: fSyntaxForegroundColorEditor = new ColorSelector(
0722: stylesComposite);
0723: Button foregroundColorButton = fSyntaxForegroundColorEditor
0724: .getButton();
0725: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0726: foregroundColorButton.setLayoutData(gd);
0727:
0728: fBoldCheckBox = new Button(stylesComposite, SWT.CHECK);
0729: fBoldCheckBox
0730: .setText(PreferencesMessages.JavaEditorPreferencePage_bold);
0731: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0732: gd.horizontalIndent = 20;
0733: gd.horizontalSpan = 2;
0734: fBoldCheckBox.setLayoutData(gd);
0735:
0736: fItalicCheckBox = new Button(stylesComposite, SWT.CHECK);
0737: fItalicCheckBox
0738: .setText(PreferencesMessages.JavaEditorPreferencePage_italic);
0739: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0740: gd.horizontalIndent = 20;
0741: gd.horizontalSpan = 2;
0742: fItalicCheckBox.setLayoutData(gd);
0743:
0744: fStrikethroughCheckBox = new Button(stylesComposite, SWT.CHECK);
0745: fStrikethroughCheckBox
0746: .setText(PreferencesMessages.JavaEditorPreferencePage_strikethrough);
0747: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0748: gd.horizontalIndent = 20;
0749: gd.horizontalSpan = 2;
0750: fStrikethroughCheckBox.setLayoutData(gd);
0751:
0752: fUnderlineCheckBox = new Button(stylesComposite, SWT.CHECK);
0753: fUnderlineCheckBox
0754: .setText(PreferencesMessages.JavaEditorPreferencePage_underline);
0755: gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
0756: gd.horizontalIndent = 20;
0757: gd.horizontalSpan = 2;
0758: fUnderlineCheckBox.setLayoutData(gd);
0759:
0760: label = new Label(colorComposite, SWT.LEFT);
0761: label
0762: .setText(PreferencesMessages.JavaEditorPreferencePage_preview);
0763: label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0764:
0765: Control previewer = createPreviewer(colorComposite);
0766: gd = new GridData(GridData.FILL_BOTH);
0767: gd.widthHint = convertWidthInCharsToPixels(20);
0768: gd.heightHint = convertHeightInCharsToPixels(5);
0769: previewer.setLayoutData(gd);
0770:
0771: fListViewer
0772: .addSelectionChangedListener(new ISelectionChangedListener() {
0773: public void selectionChanged(
0774: SelectionChangedEvent event) {
0775: handleSyntaxColorListSelection();
0776: }
0777: });
0778:
0779: foregroundColorButton
0780: .addSelectionListener(new SelectionListener() {
0781: public void widgetDefaultSelected(SelectionEvent e) {
0782: // do nothing
0783: }
0784:
0785: public void widgetSelected(SelectionEvent e) {
0786: HighlightingColorListItem item = getHighlightingColorListItem();
0787: PreferenceConverter.setValue(
0788: getPreferenceStore(), item
0789: .getColorKey(),
0790: fSyntaxForegroundColorEditor
0791: .getColorValue());
0792: }
0793: });
0794:
0795: fBoldCheckBox.addSelectionListener(new SelectionListener() {
0796: public void widgetDefaultSelected(SelectionEvent e) {
0797: // do nothing
0798: }
0799:
0800: public void widgetSelected(SelectionEvent e) {
0801: HighlightingColorListItem item = getHighlightingColorListItem();
0802: getPreferenceStore().setValue(item.getBoldKey(),
0803: fBoldCheckBox.getSelection());
0804: }
0805: });
0806:
0807: fItalicCheckBox.addSelectionListener(new SelectionListener() {
0808: public void widgetDefaultSelected(SelectionEvent e) {
0809: // do nothing
0810: }
0811:
0812: public void widgetSelected(SelectionEvent e) {
0813: HighlightingColorListItem item = getHighlightingColorListItem();
0814: getPreferenceStore().setValue(item.getItalicKey(),
0815: fItalicCheckBox.getSelection());
0816: }
0817: });
0818: fStrikethroughCheckBox
0819: .addSelectionListener(new SelectionListener() {
0820: public void widgetDefaultSelected(SelectionEvent e) {
0821: // do nothing
0822: }
0823:
0824: public void widgetSelected(SelectionEvent e) {
0825: HighlightingColorListItem item = getHighlightingColorListItem();
0826: getPreferenceStore().setValue(
0827: item.getStrikethroughKey(),
0828: fStrikethroughCheckBox.getSelection());
0829: }
0830: });
0831:
0832: fUnderlineCheckBox
0833: .addSelectionListener(new SelectionListener() {
0834: public void widgetDefaultSelected(SelectionEvent e) {
0835: // do nothing
0836: }
0837:
0838: public void widgetSelected(SelectionEvent e) {
0839: HighlightingColorListItem item = getHighlightingColorListItem();
0840: getPreferenceStore().setValue(
0841: item.getUnderlineKey(),
0842: fUnderlineCheckBox.getSelection());
0843: }
0844: });
0845:
0846: fEnableCheckbox.addSelectionListener(new SelectionListener() {
0847: public void widgetDefaultSelected(SelectionEvent e) {
0848: // do nothing
0849: }
0850:
0851: public void widgetSelected(SelectionEvent e) {
0852: HighlightingColorListItem item = getHighlightingColorListItem();
0853: if (item instanceof SemanticHighlightingColorListItem) {
0854: boolean enable = fEnableCheckbox.getSelection();
0855: getPreferenceStore().setValue(
0856: ((SemanticHighlightingColorListItem) item)
0857: .getEnableKey(), enable);
0858: fEnableCheckbox.setSelection(enable);
0859: fSyntaxForegroundColorEditor.getButton()
0860: .setEnabled(enable);
0861: fColorEditorLabel.setEnabled(enable);
0862: fBoldCheckBox.setEnabled(enable);
0863: fItalicCheckBox.setEnabled(enable);
0864: fStrikethroughCheckBox.setEnabled(enable);
0865: fUnderlineCheckBox.setEnabled(enable);
0866: uninstallSemanticHighlighting();
0867: installSemanticHighlighting();
0868: }
0869: }
0870: });
0871:
0872: colorComposite.layout(false);
0873:
0874: return colorComposite;
0875: }
0876:
0877: private void addFiller(Composite composite, int horizontalSpan) {
0878: PixelConverter pixelConverter = new PixelConverter(composite);
0879: Label filler = new Label(composite, SWT.LEFT);
0880: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
0881: gd.horizontalSpan = horizontalSpan;
0882: gd.heightHint = pixelConverter.convertHeightInCharsToPixels(1) / 2;
0883: filler.setLayoutData(gd);
0884: }
0885:
0886: private Control createPreviewer(Composite parent) {
0887:
0888: IPreferenceStore generalTextStore = EditorsUI
0889: .getPreferenceStore();
0890: IPreferenceStore store = new ChainedPreferenceStore(
0891: new IPreferenceStore[] {
0892: getPreferenceStore(),
0893: new PreferencesAdapter(
0894: createTemporaryCorePreferenceStore()),
0895: generalTextStore });
0896: fPreviewViewer = new JavaSourceViewer(parent, null, null,
0897: false, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER, store);
0898: SimpleJavaSourceViewerConfiguration configuration = new SimpleJavaSourceViewerConfiguration(
0899: fColorManager, store, null,
0900: IJavaPartitions.JAVA_PARTITIONING, false);
0901: fPreviewViewer.configure(configuration);
0902: // fake 1.5 source to get 1.5 features right.
0903: configuration
0904: .handlePropertyChangeEvent(new PropertyChangeEvent(
0905: this , JavaCore.COMPILER_SOURCE,
0906: JavaCore.VERSION_1_4, JavaCore.VERSION_1_5));
0907: Font font = JFaceResources
0908: .getFont(PreferenceConstants.EDITOR_TEXT_FONT);
0909: fPreviewViewer.getTextWidget().setFont(font);
0910: new JavaSourcePreviewerUpdater(fPreviewViewer, configuration,
0911: store);
0912: fPreviewViewer.setEditable(false);
0913:
0914: String content = loadPreviewContentFromFile("ColorSettingPreviewCode.txt"); //$NON-NLS-1$
0915: IDocument document = new Document(content);
0916: JavaPlugin.getDefault().getJavaTextTools()
0917: .setupJavaDocumentPartitioner(document,
0918: IJavaPartitions.JAVA_PARTITIONING);
0919: fPreviewViewer.setDocument(document);
0920:
0921: installSemanticHighlighting();
0922:
0923: return fPreviewViewer.getControl();
0924: }
0925:
0926: private Preferences createTemporaryCorePreferenceStore() {
0927: Preferences result = new Preferences();
0928:
0929: result.setValue(COMPILER_TASK_TAGS, "TASK,TODO"); //$NON-NLS-1$
0930:
0931: return result;
0932: }
0933:
0934: private String loadPreviewContentFromFile(String filename) {
0935: String line;
0936: String separator = System.getProperty("line.separator"); //$NON-NLS-1$
0937: StringBuffer buffer = new StringBuffer(512);
0938: BufferedReader reader = null;
0939: try {
0940: reader = new BufferedReader(new InputStreamReader(
0941: getClass().getResourceAsStream(filename)));
0942: while ((line = reader.readLine()) != null) {
0943: buffer.append(line);
0944: buffer.append(separator);
0945: }
0946: } catch (IOException io) {
0947: JavaPlugin.log(io);
0948: } finally {
0949: if (reader != null) {
0950: try {
0951: reader.close();
0952: } catch (IOException e) {
0953: }
0954: }
0955: }
0956: return buffer.toString();
0957: }
0958:
0959: /**
0960: * Install Semantic Highlighting on the previewer
0961: *
0962: * @since 3.0
0963: */
0964: private void installSemanticHighlighting() {
0965: if (fSemanticHighlightingManager == null) {
0966: fSemanticHighlightingManager = new SemanticHighlightingManager();
0967: fSemanticHighlightingManager.install(fPreviewViewer,
0968: fColorManager, getPreferenceStore(),
0969: createPreviewerRanges());
0970: }
0971: }
0972:
0973: /**
0974: * Uninstall Semantic Highlighting from the previewer
0975: *
0976: * @since 3.0
0977: */
0978: private void uninstallSemanticHighlighting() {
0979: if (fSemanticHighlightingManager != null) {
0980: fSemanticHighlightingManager.uninstall();
0981: fSemanticHighlightingManager = null;
0982: }
0983: }
0984:
0985: /**
0986: * Create the hard coded previewer ranges
0987: *
0988: * @return the hard coded previewer ranges
0989: * @since 3.0
0990: */
0991: private SemanticHighlightingManager.HighlightedRange[][] createPreviewerRanges() {
0992: return new SemanticHighlightingManager.HighlightedRange[][] {
0993: {
0994: createHighlightedRange(6, 13, 9,
0995: SemanticHighlightings.DEPRECATED_MEMBER),
0996: createHighlightedRange(6, 13, 9,
0997: SemanticHighlightings.CLASS), },
0998: {
0999: createHighlightedRange(6, 23, 1,
1000: SemanticHighlightings.TYPE_VARIABLE),
1001: createHighlightedRange(6, 23, 1,
1002: SemanticHighlightings.TYPE_ARGUMENT), },
1003: { createHighlightedRange(6, 37, 9,
1004: SemanticHighlightings.INTERFACE) },
1005: {
1006: createHighlightedRange(6, 47, 6,
1007: SemanticHighlightings.TYPE_ARGUMENT),
1008: createHighlightedRange(6, 47, 6,
1009: SemanticHighlightings.CLASS) },
1010: { createHighlightedRange(7, 6, 5,
1011: SemanticHighlightings.ENUM), },
1012: {
1013: createHighlightedRange(
1014: 7,
1015: 14,
1016: 3,
1017: SemanticHighlightings.STATIC_FINAL_FIELD),
1018: createHighlightedRange(7, 14, 3,
1019: SemanticHighlightings.STATIC_FIELD),
1020: createHighlightedRange(7, 14, 3,
1021: SemanticHighlightings.FIELD) },
1022: {
1023: createHighlightedRange(
1024: 7,
1025: 19,
1026: 5,
1027: SemanticHighlightings.STATIC_FINAL_FIELD),
1028: createHighlightedRange(7, 19, 5,
1029: SemanticHighlightings.STATIC_FIELD),
1030: createHighlightedRange(7, 19, 5,
1031: SemanticHighlightings.FIELD) },
1032: {
1033: createHighlightedRange(
1034: 7,
1035: 26,
1036: 4,
1037: SemanticHighlightings.STATIC_FINAL_FIELD),
1038: createHighlightedRange(7, 26, 4,
1039: SemanticHighlightings.STATIC_FIELD),
1040: createHighlightedRange(7, 26, 4,
1041: SemanticHighlightings.FIELD) },
1042: { createHighlightedRange(9, 8, 6,
1043: SemanticHighlightings.CLASS), },
1044: {
1045: createHighlightedRange(9, 15, 11,
1046: SemanticHighlightings.STATIC_FIELD),
1047: createHighlightedRange(9, 15, 11,
1048: SemanticHighlightings.FIELD) },
1049: { createHighlightedRange(11, 9, 1,
1050: SemanticHighlightings.TYPE_VARIABLE) },
1051: { createHighlightedRange(11, 11, 5,
1052: SemanticHighlightings.FIELD) },
1053: { createHighlightedRange(13, 2, 16,
1054: SemanticHighlightings.ANNOTATION) },
1055: { createHighlightedRange(
1056: 13,
1057: 19,
1058: 5,
1059: SemanticHighlightings.ANNOTATION_ELEMENT_REFERENCE) },
1060: {
1061: createHighlightedRange(
1062: 14,
1063: 12,
1064: 3,
1065: SemanticHighlightings.METHOD_DECLARATION),
1066: createHighlightedRange(14, 12, 3,
1067: SemanticHighlightings.METHOD) },
1068: { createHighlightedRange(14, 24, 9,
1069: SemanticHighlightings.PARAMETER_VARIABLE) },
1070: {
1071: createHighlightedRange(
1072: 15,
1073: 2,
1074: 14,
1075: SemanticHighlightings.ABSTRACT_METHOD_INVOCATION),
1076: createHighlightedRange(15, 2, 14,
1077: SemanticHighlightings.METHOD) },
1078: { createHighlightedRange(
1079: 16,
1080: 6,
1081: 5,
1082: SemanticHighlightings.LOCAL_VARIABLE_DECLARATION) },
1083: {
1084: createHighlightedRange(
1085: 16,
1086: 16,
1087: 8,
1088: SemanticHighlightings.INHERITED_METHOD_INVOCATION),
1089: createHighlightedRange(16, 16, 8,
1090: SemanticHighlightings.METHOD) },
1091: {
1092: createHighlightedRange(
1093: 17,
1094: 2,
1095: 12,
1096: SemanticHighlightings.STATIC_METHOD_INVOCATION),
1097: createHighlightedRange(17, 2, 12,
1098: SemanticHighlightings.METHOD) },
1099: { createHighlightedRange(18, 9, 3,
1100: SemanticHighlightings.METHOD) },
1101: { createHighlightedRange(18, 13, 5,
1102: SemanticHighlightings.LOCAL_VARIABLE) },
1103: { createHighlightedRange(18, 22, 9,
1104: SemanticHighlightings.AUTOBOXING) }, };
1105: }
1106:
1107: /**
1108: * Create a highlighted range on the previewers document with the given line, column, length and key.
1109: *
1110: * @param line the line
1111: * @param column the column
1112: * @param length the length
1113: * @param key the key
1114: * @return the highlighted range
1115: * @since 3.0
1116: */
1117: private HighlightedRange createHighlightedRange(int line,
1118: int column, int length, String key) {
1119: try {
1120: IDocument document = fPreviewViewer.getDocument();
1121: int offset = document.getLineOffset(line) + column;
1122: return new HighlightedRange(offset, length, key);
1123: } catch (BadLocationException x) {
1124: JavaPlugin.log(x);
1125: }
1126: return null;
1127: }
1128:
1129: /**
1130: * Returns the current highlighting color list item.
1131: *
1132: * @return the current highlighting color list item
1133: * @since 3.0
1134: */
1135: private HighlightingColorListItem getHighlightingColorListItem() {
1136: IStructuredSelection selection = (IStructuredSelection) fListViewer
1137: .getSelection();
1138: Object element = selection.getFirstElement();
1139: if (element instanceof String)
1140: return null;
1141: return (HighlightingColorListItem) element;
1142: }
1143:
1144: /**
1145: * Initializes the computation of horizontal and vertical dialog units based
1146: * on the size of current font.
1147: * <p>
1148: * This method must be called before any of the dialog unit based conversion
1149: * methods are called.
1150: * </p>
1151: *
1152: * @param testControl
1153: * a control from which to obtain the current font
1154: */
1155: private void initializeDialogUnits(Control testControl) {
1156: // Compute and store a font metric
1157: GC gc = new GC(testControl);
1158: gc.setFont(JFaceResources.getDialogFont());
1159: fFontMetrics = gc.getFontMetrics();
1160: gc.dispose();
1161: }
1162: }
|