/******************************************************************************* * Copyright (c) 2007 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.ui.preferences; import java.util.ArrayList; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.corext.util.Messages; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock; import org.eclipse.jdt.internal.ui.preferences.PreferencesMessages; import org.eclipse.jdt.internal.ui.preferences.ScrolledPageContent; import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener; import org.eclipse.jface.dialogs.ControlEnableState; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; import org.jboss.tools.common.preferences.SeverityPreferences; /** * See more info in SeverityPreferences. * To modify section descriptions: * 1) If new option is to be added to existing description, * add array of two String objects, where first is the preference name * defined in SeverityPreferences, and second is label defined in * SeverityPreferencesMessages (do not forget put property to SeverirtyPreferencesMessages.properties * and constant to SeverityPreferencesMessages.java) * * 2) If new section named A is to be created create constant * private static SectionDescription SECTION_A = new SectionDescription( * SeamPreferencesMessages.SeamValidatorConfigurationBlock_section_a, * new String[][]{ * } * ); * create required constant and property in SeverityPreferencesMessages, * and add SECTION_A to array ALL_SECTIONS. * * Also, see ProblemSeveritiesConfigurationBlock * * @author Viacheslav Kabanovich */ abstract public class SeverityConfigurationBlock extends OptionsConfigurationBlock { protected static final String ERROR = SeverityPreferences.ERROR; protected static final String WARNING = SeverityPreferences.WARNING; protected static final String IGNORE = SeverityPreferences.IGNORE; protected static final String ENABLED = JavaCore.ENABLED; protected static final String DISABLED = JavaCore.DISABLED; protected String[] errorWarningIgnore = new String[] {ERROR, WARNING, IGNORE}; protected String[] enableDisableValues= new String[] {ENABLED, DISABLED}; protected String[] errorWarningIgnoreLabels = new String[] { SeverityPreferencesMessages.VALIDATOR_CONFIGURATION_BLOCK_ERROR, SeverityPreferencesMessages.VALIDATOR_CONFIGURATION_BLOCK_WARNING, SeverityPreferencesMessages.VALIDATOR_CONFIGURATION_BLOCK_IGNORE }; protected PixelConverter fPixelConverter; protected FilteredPreferenceTree fFilteredPrefTree; private ControlEnableState mainBlockEnableState; /** * Text control retrieved from fFilteredPrefTree. */ protected Text filterControl; protected IWorkbenchPreferenceContainer container; protected Button enableCheckBox; public SeverityConfigurationBlock(IStatusChangeListener context, IProject project, Key[] allKeys, IWorkbenchPreferenceContainer container) { super(context, project, allKeys, container); this.container = container; } /** * @return the container */ public IWorkbenchPreferenceContainer getContainer() { return container; } protected abstract String getCommonDescription(); protected abstract SectionDescription[] getAllSections(); protected abstract IDialogSettings getDialogSettings(); protected Composite createStyleTabContent(Composite folder) { int nColumns = 3; GridLayout layout= new GridLayout(nColumns, false); layout.marginHeight= 0; layout.marginWidth= 0; Composite c = new Composite(folder, 0); c.setLayout(layout); c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if(getMaxNumberOfProblemsKey() != null) { addMaxNumberOfMarkersField(c); } addWrongBuilderOrderField(c); Control[] currentControls = folder.getChildren(); fFilteredPrefTree = new FilteredPreferenceTree(this, folder, getCommonDescription()); filterControl = findText(folder, currentControls.length); final ScrolledPageContent sc1 = fFilteredPrefTree.getScrolledPageContent(); Composite composite = sc1.getBody(); composite.setLayout(layout); int defaultIndent = 0; for (SectionDescription section: getAllSections()) { createSection(null, section, composite, nColumns, defaultIndent); } restoreSectionExpansionStates(getDialogSettings()); return sc1; } Text findText(Composite composite, int startFromIndex) { Control[] cs = composite.getChildren(); for (int i = startFromIndex; i < cs.length; i++) { Control cl = cs[i]; if(cl instanceof Text) { return (Text)cl; } else if(cl instanceof Composite) { Text t = findText((Composite)cl, 0); if(t != null) { return t; } } } return null; } protected Composite createInnerComposite(ExpandableComposite excomposite, int nColumns, Font font) { Composite inner= new Composite(excomposite, SWT.NONE); inner.setFont(font); inner.setLayout(new GridLayout(nColumns, false)); excomposite.setClient(inner); return inner; } protected void createSection(PreferenceTreeNode parent, SectionDescription section, Composite composite, int nColumns, int defaultIndent) { String label = section.getLabel(); Key twistieKey = OptionsConfigurationBlock.getLocalKey(label.replace(' ', '_')); PreferenceTreeNode treeSection = fFilteredPrefTree.addExpandableComposite(composite, label, nColumns, twistieKey, parent, false); ExpandableComposite excomposite = getExpandableComposite(twistieKey); Composite inner = createInnerComposite(excomposite, nColumns, composite.getFont()); for (SectionDescription s: section.getSections()) { createSection(treeSection, s, inner, nColumns, defaultIndent); } for (OptionDescription option: section.getOptions()) { label = option.label; fFilteredPrefTree.addComboBox(inner, label, option.key, errorWarningIgnore, errorWarningIgnoreLabels, defaultIndent, treeSection); } } @Override public void performDefaults() { super.performDefaults(); updateMainPreferenceContent(); } protected Button addEnableField(Composite composite) { Button checkBox = addCheckBox(composite, SeverityPreferencesMessages.ENABLE_VALIDATION, getEnableBlockKey(), enableDisableValues, 0); checkBox.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updateMainPreferenceContent(); } public void widgetDefaultSelected(SelectionEvent e) { } }); return checkBox; } protected void addMaxNumberOfMarkersField(Composite composite) { Text text = addTextField(composite, SeverityPreferencesMessages.MAX_NUMBER_OF_MARKERS, getMaxNumberOfProblemsKey(), 0, 0); GridData gd = (GridData) text.getLayoutData(); gd.widthHint = fPixelConverter.convertWidthInCharsToPixels(8); gd.horizontalAlignment = GridData.BEGINNING; text.setLayoutData(gd); text.setTextLimit(6); } protected void addWrongBuilderOrderField(Composite composite) { if(getWrongBuilderOrderKey() != null) { addComboBox(composite, SeverityPreferencesMessages.WRONG_BUILDER_ORDER, getWrongBuilderOrderKey(), errorWarningIgnore, errorWarningIgnoreLabels, 0); } } private IStatus validateMaxNumberProblems() { StatusInfo status= new StatusInfo(); if(getMaxNumberOfProblemsKey() != null) { String number = getValue(getMaxNumberOfProblemsKey()); if (number == null || number.length() == 0) { status.setError(PreferencesMessages.JavaBuildConfigurationBlock_empty_input); } else { try { int value= Integer.parseInt(number); if (value <= 0) { status.setError(Messages.format(PreferencesMessages.JavaBuildConfigurationBlock_invalid_input, number)); } } catch (NumberFormatException e) { status.setError(Messages.format(PreferencesMessages.JavaBuildConfigurationBlock_invalid_input, number)); } } } return status; } abstract protected Key getEnableBlockKey(); abstract protected Key getMaxNumberOfProblemsKey(); /** * Returns Key object for preference controlling builders order if it is relevant. * If builders order is not relevant, returns null. * @return unique key or null */ protected Key getWrongBuilderOrderKey() { return null; } private Composite commonComposite; @Override protected Control createContents(Composite parent) { fPixelConverter = new PixelConverter(parent); setShell(parent.getShell()); Composite mainComp = new Composite(parent, SWT.NONE); mainComp.setFont(parent.getFont()); GridLayout layout= new GridLayout(); layout.marginHeight = 0; layout.marginWidth = 0; mainComp.setLayout(layout); mainComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); enableCheckBox = addEnableField(mainComp); commonComposite = createStyleTabContent(mainComp); GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true); gridData.heightHint = convertHeightInCharsToPixels(parent,20); commonComposite.setLayoutData(gridData); validateSettings(null, null, null); updateMainPreferenceContent(); return mainComp; } protected void updateMainPreferenceContent() { if (enableCheckBox.getSelection()) { if (mainBlockEnableState != null) { mainBlockEnableState.restore(); mainBlockEnableState= null; } } else { if (mainBlockEnableState == null) { mainBlockEnableState= ControlEnableState.disable(commonComposite); } } } private int convertHeightInCharsToPixels(Control control,int chars) { Font font = control.getFont(); GC gc = new GC(font.getDevice()); gc.setFont(font); FontMetrics fFontMetrics = gc.getFontMetrics(); gc.dispose(); return Dialog.convertHeightInCharsToPixels(fFontMetrics, chars); } @Override protected String[] getFullBuildDialogStrings(boolean workspaceSettings) { String title= SeverityPreferencesMessages.ValidatorConfigurationBlock_needsbuild_title; String message; if (workspaceSettings) { message= SeverityPreferencesMessages.ValidatorConfigurationBlock_needsfullbuild_message; } else { message= SeverityPreferencesMessages.ValidatorConfigurationBlock_needsprojectbuild_message; } return new String[] { title, message }; } @Override protected void validateSettings(Key changedKey, String oldValue, String newValue) { if (!areSettingsEnabled()) { return; } if(getMaxNumberOfProblemsKey() != null) { if (changedKey == null || getMaxNumberOfProblemsKey().equals(changedKey)) { fContext.statusChanged(validateMaxNumberProblems()); } } } public static class SectionDescription { private String label; private SectionDescription[] sections; private OptionDescription[] options; public SectionDescription(String label, String[][] optionLabelsAndKeys, String pluginId) { this(label, new SectionDescription[0], optionLabelsAndKeys, pluginId); } public SectionDescription(String label, SectionDescription[] sections, String[][] optionLabelsAndKeys, String pluginId) { this.label = label; this.sections = sections; options = new OptionDescription[optionLabelsAndKeys.length]; for (int i = 0; i < options.length; i++) { options[i] = new OptionDescription(optionLabelsAndKeys[i][0], optionLabelsAndKeys[i][1], pluginId); } } public String getLabel() { return label; } public SectionDescription[] getSections() { return sections; } public OptionDescription[] getOptions() { return options; } public void collectKeys(ArrayList<Key> keys) { for (SectionDescription s: sections) { s.collectKeys(keys); } for (OptionDescription o: options) { keys.add(o.key); } } } public static class OptionDescription { public String label; public Key key; public OptionDescription(String keyName, String label, String pluginId) { this.label = label; key = getKey(pluginId, keyName); } } public Text getFilterControl() { return filterControl; } public void doFilter(String prefId){ // String qualifier = getQualifier(); Key key = null; for(Key k : fAllKeys){ if(/*k.getQualifier().equals(qualifier) &&*/ k.getName().equals(prefId)) key = k; } if(key != null){ Combo combo = getComboBox(key); if(combo != null){ String value = ((Label)fLabels.get(combo)).getText(); if(value != null) { if(filterControl != null) { filterControl.setText(value); } else { fFilteredPrefTree.doFilter(value); } } } } } abstract protected String getQualifier(); }