blob: 35b7aae8b917fc8703370aab535596edade48233 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.editors.text;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.preference.ColorSelector;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.editors.text.OverlayPreferenceStore.OverlayKey;
import org.eclipse.ui.texteditor.AnnotationPreference;
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
/**
* Configures Annotation preferences.
*
* @since 3.0
*/
class AnnotationsConfigurationBlock implements IPreferenceConfigurationBlock {
private static final class ListItem {
final String label;
final Image image;
final String colorKey;
final String highlightKey;
final String overviewRulerKey;
final String textStyleKey;
final String textKey;
final String verticalRulerKey;
final String isNextPreviousNavigationKey;
ListItem(String label, Image image, String colorKey, String textKey, String overviewRulerKey, String highlightKey, String verticalRulerKey, String textStyleKey, String navigationKey) {
this.label= label;
this.image= image;
this.colorKey= colorKey;
this.highlightKey= highlightKey;
this.overviewRulerKey= overviewRulerKey;
this.textKey= textKey;
this.textStyleKey= textStyleKey;
this.verticalRulerKey= verticalRulerKey;
this.isNextPreviousNavigationKey= navigationKey;
}
}
private static final class ItemContentProvider implements IStructuredContentProvider {
@Override
public Object[] getElements(Object inputElement) {
return (ListItem[]) inputElement;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private static final class ItemLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
return ((ListItem)element).label;
}
@Override
public Image getImage(Object element) {
ListItem item= (ListItem)element;
return item.image;
}
}
private static class ArrayLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
return ((String[]) element)[0].toString();
}
}
final static String[] HIGHLIGHT= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_HIGHLIGHT, "not used"}; //$NON-NLS-1$
final static String[] UNDERLINE= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_UNDERLINE, AnnotationPreference.STYLE_UNDERLINE};
final static String[] BOX= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_BOX, AnnotationPreference.STYLE_BOX};
final static String[] DASHED_BOX= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_DASHED_BOX, AnnotationPreference.STYLE_DASHED_BOX};
final static String[] IBEAM= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_IBEAM, AnnotationPreference.STYLE_IBEAM};
final static String[] SQUIGGLES= new String[] {TextEditorMessages.AnnotationsConfigurationBlock_SQUIGGLES, AnnotationPreference.STYLE_SQUIGGLES};
final static String[] PROBLEM_UNDERLINE= new String[] { TextEditorMessages.AnnotationsConfigurationBlock_PROBLEM_UNDERLINE, AnnotationPreference.STYLE_PROBLEM_UNDERLINE };
private OverlayPreferenceStore fStore;
private ColorSelector fAnnotationForegroundColorEditor;
private Button fShowInTextCheckBox;
private Button fShowInOverviewRulerCheckBox;
private Button fShowInVerticalRulerCheckBox;
private Button fIsNextPreviousTargetCheckBox;
private StructuredViewer fAnnotationTypeViewer;
private final ListItem[] fListModel;
private ComboViewer fDecorationViewer;
private final Set<String> fImageKeys= new HashSet<>();
public AnnotationsConfigurationBlock(OverlayPreferenceStore store) {
Assert.isNotNull(store);
MarkerAnnotationPreferences markerAnnotationPreferences= EditorsPlugin.getDefault().getMarkerAnnotationPreferences();
fStore= store;
fStore.addKeys(createOverlayStoreKeys(markerAnnotationPreferences));
fListModel= createAnnotationTypeListModel(markerAnnotationPreferences);
}
private OverlayPreferenceStore.OverlayKey[] createOverlayStoreKeys(MarkerAnnotationPreferences preferences) {
ArrayList<OverlayKey> overlayKeys= new ArrayList<>();
Iterator<AnnotationPreference> e= preferences.getAnnotationPreferences().iterator();
while (e.hasNext()) {
AnnotationPreference info= e.next();
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, info.getColorPreferenceKey()));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getTextPreferenceKey()));
if (info.getHighlightPreferenceKey() != null)
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getHighlightPreferenceKey()));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getOverviewRulerPreferenceKey()));
if (info.getVerticalRulerPreferenceKey() != null)
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getVerticalRulerPreferenceKey()));
if (info.getTextStylePreferenceKey() != null)
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, info.getTextStylePreferenceKey()));
if (info.getIsGoToNextNavigationTargetKey() != null)
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, info.getIsGoToNextNavigationTargetKey()));
}
OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
overlayKeys.toArray(keys);
return keys;
}
@Override
public Control createControl(Composite parent) {
PixelConverter pixelConverter= new PixelConverter(parent);
Composite composite= new Composite(parent, SWT.NULL);
GridLayout layout= new GridLayout();
layout.numColumns= 2;
layout.marginHeight= 0;
layout.marginWidth= 0;
composite.setLayout(layout);
Label label= new Label(composite, SWT.LEFT);
label.setText(TextEditorMessages.AnnotationsConfigurationBlock_annotationPresentationOptions);
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan= 2;
label.setLayoutData(gd);
Composite editorComposite= new Composite(composite, SWT.NONE);
layout= new GridLayout();
layout.numColumns= 2;
layout.marginHeight= 0;
layout.marginWidth= 0;
editorComposite.setLayout(layout);
gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
gd.horizontalSpan= 2;
editorComposite.setLayoutData(gd);
fAnnotationTypeViewer= new TableViewer(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER | SWT.FULL_SELECTION);
fAnnotationTypeViewer.setLabelProvider(new ItemLabelProvider());
fAnnotationTypeViewer.setContentProvider(new ItemContentProvider());
gd= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
gd.heightHint= pixelConverter.convertHeightInCharsToPixels(20);
fAnnotationTypeViewer.getControl().setLayoutData(gd);
Composite optionsComposite= new Composite(editorComposite, SWT.NONE);
layout= new GridLayout();
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.numColumns= 2;
optionsComposite.setLayout(layout);
optionsComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
label= new Label(optionsComposite, SWT.LEFT);
label.setText(TextEditorMessages.AnnotationsConfigurationBlock_labels_showIn);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
gd.horizontalSpan= 2;
label.setLayoutData(gd);
fShowInVerticalRulerCheckBox= new Button(optionsComposite, SWT.CHECK);
fShowInVerticalRulerCheckBox.setText(TextEditorMessages.AnnotationsConfigurationBlock_showInVerticalRuler);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
gd.horizontalSpan= 2;
fShowInVerticalRulerCheckBox.setLayoutData(gd);
fShowInOverviewRulerCheckBox= new Button(optionsComposite, SWT.CHECK);
fShowInOverviewRulerCheckBox.setText(TextEditorMessages.AnnotationsConfigurationBlock_showInOverviewRuler);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
gd.horizontalSpan= 2;
fShowInOverviewRulerCheckBox.setLayoutData(gd);
fShowInTextCheckBox= new Button(optionsComposite, SWT.CHECK);
fShowInTextCheckBox.setText(TextEditorMessages.AnnotationsConfigurationBlock_showInText);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
fShowInTextCheckBox.setLayoutData(gd);
fDecorationViewer= new ComboViewer(optionsComposite, SWT.READ_ONLY);
fDecorationViewer.setContentProvider(ArrayContentProvider.getInstance());
fDecorationViewer.setLabelProvider(new ArrayLabelProvider());
fDecorationViewer.setComparator(new ViewerComparator(Collator.getInstance()));
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
fDecorationViewer.getControl().setLayoutData(gd);
fDecorationViewer.setInput(new Object[] { HIGHLIGHT, SQUIGGLES, BOX, DASHED_BOX, UNDERLINE, PROBLEM_UNDERLINE, IBEAM });
fDecorationViewer.getCombo().setVisibleItemCount(fDecorationViewer.getCombo().getItemCount());
label= new Label(optionsComposite, SWT.LEFT);
label.setText(TextEditorMessages.AnnotationsConfigurationBlock_color);
gd= new GridData();
gd.horizontalAlignment= GridData.BEGINNING;
label.setLayoutData(gd);
fAnnotationForegroundColorEditor= new ColorSelector(optionsComposite);
Button foregroundColorButton= fAnnotationForegroundColorEditor.getButton();
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
foregroundColorButton.setLayoutData(gd);
addFiller(optionsComposite);
fIsNextPreviousTargetCheckBox= new Button(optionsComposite, SWT.CHECK);
fIsNextPreviousTargetCheckBox.setText(TextEditorMessages.AnnotationsConfigurationBlock_isNavigationTarget);
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
gd.horizontalSpan= 2;
gd.horizontalIndent= 0;
fIsNextPreviousTargetCheckBox.setLayoutData(gd);
fAnnotationTypeViewer.addSelectionChangedListener(event -> handleAnnotationListSelection());
fShowInTextCheckBox.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
@Override
public void widgetSelected(SelectionEvent e) {
ListItem item= getSelectedItem();
final boolean value= fShowInTextCheckBox.getSelection();
if (value) {
// enable whatever is in the combo
String[] decoration= (String[]) fDecorationViewer.getStructuredSelection().getFirstElement();
if (HIGHLIGHT.equals(decoration))
fStore.setValue(item.highlightKey, true);
else
fStore.setValue(item.textKey, true);
} else {
// disable both
if (item.textKey != null)
fStore.setValue(item.textKey, false);
if (item.highlightKey != null)
fStore.setValue(item.highlightKey, false);
}
fStore.setValue(item.textKey, value);
updateDecorationViewer(item, false);
fAnnotationTypeViewer.refresh(item);
}
});
fShowInOverviewRulerCheckBox.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
@Override
public void widgetSelected(SelectionEvent e) {
ListItem item= getSelectedItem();
fStore.setValue(item.overviewRulerKey, fShowInOverviewRulerCheckBox.getSelection());
fAnnotationTypeViewer.refresh(item);
}
});
fShowInVerticalRulerCheckBox.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
@Override
public void widgetSelected(SelectionEvent e) {
ListItem item= getSelectedItem();
fStore.setValue(item.verticalRulerKey, fShowInVerticalRulerCheckBox.getSelection());
fAnnotationTypeViewer.refresh(item);
}
});
fIsNextPreviousTargetCheckBox.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
@Override
public void widgetSelected(SelectionEvent e) {
ListItem item= getSelectedItem();
fStore.setValue(item.isNextPreviousNavigationKey, fIsNextPreviousTargetCheckBox.getSelection());
fAnnotationTypeViewer.refresh(item);
}
});
foregroundColorButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// do nothing
}
@Override
public void widgetSelected(SelectionEvent e) {
ListItem item= getSelectedItem();
PreferenceConverter.setValue(fStore, item.colorKey, fAnnotationForegroundColorEditor.getColorValue());
fAnnotationTypeViewer.refresh(item);
}
});
fDecorationViewer.addSelectionChangedListener(event -> {
String[] decoration= (String[]) fDecorationViewer.getStructuredSelection().getFirstElement();
ListItem item= getSelectedItem();
if (fShowInTextCheckBox.getSelection()) {
if (HIGHLIGHT.equals(decoration)) {
fStore.setValue(item.highlightKey, true);
if (item.textKey != null) {
fStore.setValue(item.textKey, false);
if (item.textStyleKey != null)
fStore.setValue(item.textStyleKey, AnnotationPreference.STYLE_NONE);
}
} else {
if (item.highlightKey != null)
fStore.setValue(item.highlightKey, false);
if (item.textKey != null) {
fStore.setValue(item.textKey, true);
if (item.textStyleKey != null)
fStore.setValue(item.textStyleKey, decoration[1]);
}
}
}
fAnnotationTypeViewer.refresh(item);
});
composite.layout();
return composite;
}
private void addFiller(Composite composite) {
PixelConverter pixelConverter= new PixelConverter(composite);
Label filler= new Label(composite, SWT.LEFT);
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan= 2;
gd.heightHint= pixelConverter.convertHeightInCharsToPixels(1) / 2;
filler.setLayoutData(gd);
}
/**
* Applies the given data.
*
* @param data the annotation type to select in the list or <code>null</code>
* @see org.eclipse.ui.internal.editors.text.IPreferenceConfigurationBlock#applyData(java.lang.Object)
* @since 3.4
*/
@Override
public void applyData(Object data) {
if (!(data instanceof String))
return;
for (ListItem element : fListModel) {
if (data.equals(element.label)) {
final Control control= fAnnotationTypeViewer.getControl();
control.getDisplay().asyncExec(() -> {
control.setFocus();
fAnnotationTypeViewer.setSelection(new StructuredSelection(element), true);
});
return;
}
}
}
@Override
public boolean canPerformOk() {
return true;
}
@Override
public void performOk() {
}
@Override
public void performDefaults() {
fStore.loadDefaults();
fAnnotationTypeViewer.refresh();
handleAnnotationListSelection();
}
private void handleAnnotationListSelection() {
ListItem item= getSelectedItem();
RGB rgb= PreferenceConverter.getColor(fStore, item.colorKey);
fAnnotationForegroundColorEditor.setColorValue(rgb);
boolean highlight= item.highlightKey == null ? false : fStore.getBoolean(item.highlightKey);
boolean showInText = item.textKey == null ? false : fStore.getBoolean(item.textKey);
fShowInTextCheckBox.setSelection(showInText || highlight);
updateDecorationViewer(item, true);
fShowInOverviewRulerCheckBox.setSelection(fStore.getBoolean(item.overviewRulerKey));
if (item.isNextPreviousNavigationKey != null) {
fIsNextPreviousTargetCheckBox.setEnabled(true);
fIsNextPreviousTargetCheckBox.setSelection(fStore.getBoolean(item.isNextPreviousNavigationKey));
} else {
fIsNextPreviousTargetCheckBox.setEnabled(false);
fIsNextPreviousTargetCheckBox.setSelection(false);
}
if (item.verticalRulerKey != null) {
fShowInVerticalRulerCheckBox.setSelection(fStore.getBoolean(item.verticalRulerKey));
fShowInVerticalRulerCheckBox.setEnabled(true);
} else {
fShowInVerticalRulerCheckBox.setSelection(true);
fShowInVerticalRulerCheckBox.setEnabled(false);
}
}
@Override
public void initialize() {
fAnnotationTypeViewer.setInput(fListModel);
fAnnotationTypeViewer.getControl().getDisplay().asyncExec(() -> {
if (fAnnotationTypeViewer != null && !fAnnotationTypeViewer.getControl().isDisposed()) {
fAnnotationTypeViewer.setSelection(new StructuredSelection(fListModel[0]));
}
});
}
private ListItem[] createAnnotationTypeListModel(MarkerAnnotationPreferences preferences) {
ArrayList<ListItem> listModelItems= new ArrayList<>();
Iterator<AnnotationPreference> e= preferences.getAnnotationPreferences().iterator();
while (e.hasNext()) {
AnnotationPreference info= e.next();
if (info.isIncludeOnPreferencePage()) {
String label= info.getPreferenceLabel();
if (containsMoreThanOne(preferences.getAnnotationPreferences().iterator(), label))
label += " (" + info.getAnnotationType() + ")"; //$NON-NLS-1$//$NON-NLS-2$
Image image= getImage(info);
listModelItems.add(new ListItem(label, image, info.getColorPreferenceKey(), info.getTextPreferenceKey(), info.getOverviewRulerPreferenceKey(), info.getHighlightPreferenceKey(), info
.getVerticalRulerPreferenceKey(), info.getTextStylePreferenceKey(), info.getIsGoToNextNavigationTargetKey()));
}
}
Comparator<ListItem> comparator= (o1, o2) -> {
String label1= o1.label;
String label2= o2.label;
return Collator.getInstance().compare(label1, label2);
};
Collections.sort(listModelItems, comparator);
ListItem[] items= new ListItem[listModelItems.size()];
listModelItems.toArray(items);
return items;
}
/**
* Returns the image for the given annotation and the given annotation preferences or
* <code>null</code> if there is no such image.
*
* @param preference the annotation preference
* @return the image or <code>null</code>
* @since 3.1
*/
private Image getImage(AnnotationPreference preference) {
ImageRegistry registry= EditorsPlugin.getDefault().getImageRegistry();
String annotationType= (String) preference.getAnnotationType();
if (annotationType == null)
return null;
String customImage= annotationType + "__AnnotationsConfigurationBlock_Image"; //$NON-NLS-1$
Image image;
image= registry.get(customImage);
if (image != null)
return image;
image= registry.get(annotationType);
if (image == null) {
AnnotationPreference delegatingPreference= EditorsPlugin.getDefault().getAnnotationPreferenceLookup().getAnnotationPreference(annotationType);
ImageDescriptor descriptor= delegatingPreference.getImageDescriptor();
if (descriptor != null) {
registry.put(annotationType, descriptor);
image= registry.get(annotationType);
} else {
String symbolicImageName= preference.getSymbolicImageName();
if (symbolicImageName != null) {
String key= DefaultMarkerAnnotationAccess.getSharedImageName(symbolicImageName);
if (key != null) {
ISharedImages sharedImages= PlatformUI.getWorkbench().getSharedImages();
image= sharedImages.getImage(key);
}
}
}
}
if (image == null)
return null;
// create custom image
final int SIZE= 16; // square images
ImageData data= image.getImageData();
Image copy;
if (data.height > SIZE || data.width > SIZE) {
// scale down to icon size
copy= new Image(Display.getCurrent(), data.scaledTo(SIZE, SIZE));
} else if (data.height == SIZE && data.width == SIZE) {
// nothing to scale, return the image
return image;
} else {
// don't scale up, but rather copy into the middle and mark everything else transparent
ImageData mask= data.getTransparencyMask();
ImageData resized= new ImageData(SIZE, SIZE, data.depth, data.palette);
ImageData resizedMask= new ImageData(SIZE, SIZE, mask.depth, mask.palette);
int xo= Math.max(0, (SIZE - data.width) / 2);
int yo= Math.max(0, (SIZE - data.height) / 2);
for (int y= 0; y < SIZE; y++) {
for (int x= 0; x < SIZE; x++) {
if (y >= yo && x >= xo && y < yo + data.height && x < xo + data.width) {
resized.setPixel(x, y, data.getPixel(x - xo, y - yo));
resizedMask.setPixel(x, y, mask.getPixel(x - xo, y - yo));
}
}
}
copy= new Image(Display.getCurrent(), resized, resizedMask);
}
fImageKeys.add(customImage);
registry.put(customImage, copy);
return copy;
}
private boolean containsMoreThanOne(Iterator<AnnotationPreference> annotationPrefernceIterator, String label) {
if (label == null)
return false;
int count= 0;
while (annotationPrefernceIterator.hasNext()) {
if (label.equals(annotationPrefernceIterator.next().getPreferenceLabel()))
count++;
if (count == 2)
return true;
}
return false;
}
@Override
public void dispose() {
ImageRegistry registry= EditorsPlugin.getDefault().getImageRegistry();
for (String string : fImageKeys) {
registry.remove(string);
}
fImageKeys.clear();
}
private ListItem getSelectedItem() {
return (ListItem) fAnnotationTypeViewer.getStructuredSelection().getFirstElement();
}
private void updateDecorationViewer(ListItem item, boolean changed) {
// decoration selection: if the checkbox is enabled, there is
// only one case where the combo is not enabled: if both the highlight and textStyle keys are null
final boolean enabled= fShowInTextCheckBox.getSelection() && !(item.highlightKey == null && item.textStyleKey == null);
fDecorationViewer.getControl().setEnabled(enabled);
if (changed) {
String[] selection= null;
ArrayList<String[]> list= new ArrayList<>();
// highlighting
if (item.highlightKey != null) {
list.add(HIGHLIGHT);
if (fStore.getBoolean(item.highlightKey))
selection= HIGHLIGHT;
}
// legacy default= squiggly lines
list.add(SQUIGGLES);
// advanced styles
if (item.textStyleKey != null) {
list.add(UNDERLINE);
list.add(PROBLEM_UNDERLINE);
list.add(BOX);
list.add(DASHED_BOX);
list.add(IBEAM);
}
// set selection
if (selection == null) {
String val= item.textStyleKey == null ? SQUIGGLES[1] : fStore.getString(item.textStyleKey);
for (String[] elem : list) {
if (elem[1].equals(val)) {
selection= elem;
break;
}
}
}
fDecorationViewer.setInput(list.toArray(new Object[list.size()]));
if (selection != null)
fDecorationViewer.setSelection(new StructuredSelection((Object) selection), true);
}
}
}