| package org.eclipse.dltk.tcl.internal.tclchecker.ui.preferences; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.databinding.DataBindingContext; |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.dltk.compiler.util.Util; |
| import org.eclipse.dltk.internal.databinging.RadioButtonListValue; |
| import org.eclipse.dltk.tcl.internal.tclchecker.TclCheckerProblemDescription; |
| import org.eclipse.dltk.tcl.tclchecker.model.configs.CheckerConfig; |
| import org.eclipse.dltk.tcl.tclchecker.model.configs.CheckerMode; |
| import org.eclipse.dltk.tcl.tclchecker.model.configs.ConfigsPackage; |
| import org.eclipse.dltk.tcl.tclchecker.model.configs.MessageState; |
| import org.eclipse.dltk.tcl.tclchecker.model.messages.CheckerMessage; |
| import org.eclipse.dltk.tcl.tclchecker.model.messages.MessageCategory; |
| import org.eclipse.dltk.tcl.tclchecker.model.messages.MessageGroup; |
| import org.eclipse.dltk.ui.dialogs.StatusInfo; |
| import org.eclipse.dltk.ui.util.PixelConverter; |
| import org.eclipse.dltk.ui.util.SWTFactory; |
| import org.eclipse.dltk.validators.configs.ValidatorsPackage; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.databinding.EMFObservables; |
| import org.eclipse.jface.databinding.swt.typed.WidgetProperties; |
| import org.eclipse.jface.dialogs.StatusDialog; |
| import org.eclipse.jface.layout.TreeColumnLayout; |
| import org.eclipse.jface.viewers.CellEditor; |
| import org.eclipse.jface.viewers.ColumnViewer; |
| import org.eclipse.jface.viewers.ColumnWeightData; |
| import org.eclipse.jface.viewers.ComboBoxCellEditor; |
| import org.eclipse.jface.viewers.EditingSupport; |
| import org.eclipse.jface.viewers.ITableLabelProvider; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.TreeViewerColumn; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerComparator; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| 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.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeColumn; |
| |
| public class TclCheckerConfigurationDialog extends StatusDialog { |
| |
| private class MessageLabelProvider extends LabelProvider implements ITableLabelProvider { |
| |
| @Override |
| public Image getColumnImage(Object element, int columnIndex) { |
| return null; |
| } |
| |
| @Override |
| public String getText(Object element) { |
| return getColumnText(element, 0); |
| } |
| |
| @Override |
| public String getColumnText(Object element, int columnIndex) { |
| if (element instanceof MessageGroup) { |
| if (columnIndex == 0) { |
| return ((MessageGroup) element).getName(); |
| } |
| } else if (element instanceof CheckerMessage) { |
| final CheckerMessage message = (CheckerMessage) element; |
| switch (columnIndex) { |
| case 0: { |
| final String id = message.getMessageId(); |
| final int index = id.indexOf(TclCheckerProblemDescription.MESSAGE_ID_SEPARATOR); |
| if (index >= 0) { |
| return id.substring(index + TclCheckerProblemDescription.MESSAGE_ID_SEPARATOR.length()); |
| } else { |
| return id; |
| } |
| } |
| case 1: { |
| final MessageCategory category = message.getCategory(); |
| if (category.isError()) { |
| return Messages.TclChecker_error; |
| } else if (category.isWarning()) { |
| return Messages.TclChecker_warning; |
| } |
| } |
| case 2: |
| return stateToString.get(instance.getMessageStates().get(message.getMessageId())); |
| } |
| } else { |
| return element.toString(); |
| } |
| return Util.EMPTY_STRING; |
| } |
| } |
| |
| private static final Map<MessageState, String> stateToString = new HashMap<>(); |
| |
| static { |
| stateToString.put(MessageState.DEFAULT, Messages.TclChecker_processType_default); |
| stateToString.put(null, Messages.TclChecker_processType_default); |
| stateToString.put(MessageState.CHECK, Messages.TclChecker_processType_check); |
| stateToString.put(MessageState.SUPPRESS, Messages.TclChecker_processType_suppress); |
| } |
| |
| private static class MessageContentProvider implements ITreeContentProvider { |
| |
| @Override |
| public Object[] getChildren(Object parentElement) { |
| if (parentElement instanceof MessageGroup) { |
| return ((MessageGroup) parentElement).getMessages().toArray(); |
| } else { |
| return new Object[0]; |
| } |
| } |
| |
| @Override |
| public Object getParent(Object element) { |
| if (element instanceof CheckerMessage) { |
| return ((CheckerMessage) element).getGroup(); |
| } else { |
| return null; |
| } |
| } |
| |
| @Override |
| public boolean hasChildren(Object element) { |
| return element instanceof MessageGroup; |
| } |
| |
| @Override |
| public Object[] getElements(Object inputElement) { |
| if (inputElement instanceof List) { |
| return ((List) inputElement).toArray(); |
| } else { |
| return new Object[0]; |
| } |
| } |
| |
| @Override |
| public void dispose() { |
| // empty |
| } |
| |
| @Override |
| public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
| // empty |
| } |
| |
| } |
| |
| private static class MessageViewerComparator extends ViewerComparator { |
| |
| @Override |
| public int category(Object element) { |
| if (element instanceof MessageGroup) { |
| return -(((MessageGroup) element).getPriority() + 2); |
| } else if (element instanceof CheckerMessage) { |
| return 1; |
| } else { |
| return super.category(element); |
| } |
| } |
| |
| } |
| |
| private class TclCheckerMessageActionEditingSupport extends EditingSupport { |
| |
| /** |
| * @param viewer |
| */ |
| public TclCheckerMessageActionEditingSupport(ColumnViewer viewer) { |
| super(viewer); |
| } |
| |
| @Override |
| protected boolean canEdit(Object element) { |
| return element instanceof CheckerMessage; |
| } |
| |
| @Override |
| protected CellEditor getCellEditor(Object element) { |
| final String[] items = new String[MessageState.VALUES.size()]; |
| for (int i = 0; i < items.length; ++i) { |
| items[i] = stateToString.get(MessageState.VALUES.get(i)); |
| } |
| return new ComboBoxCellEditor((Composite) getViewer().getControl(), items, SWT.READ_ONLY); |
| } |
| |
| @Override |
| protected Object getValue(Object element) { |
| if (element instanceof CheckerMessage) { |
| final MessageState state = instance.getMessageStates().get(((CheckerMessage) element).getMessageId()); |
| return MessageState.VALUES.indexOf(state != null ? state : MessageState.DEFAULT); |
| } |
| return null; |
| } |
| |
| @Override |
| protected void setValue(Object element, Object value) { |
| if (element instanceof CheckerMessage && value instanceof Integer) { |
| final MessageState state = MessageState.VALUES.get((Integer) value); |
| final String messageId = ((CheckerMessage) element).getMessageId(); |
| if (state == MessageState.DEFAULT) { |
| instance.getMessageStates().removeKey(messageId); |
| } else { |
| instance.getMessageStates().put(messageId, state); |
| } |
| getViewer().refresh(element); |
| } |
| } |
| } |
| |
| private final CheckerConfig instance; |
| private final DataBindingContext bindingContext; |
| |
| public TclCheckerConfigurationDialog(Shell parent, CheckerConfig instance) { |
| super(parent); |
| Assert.isNotNull(instance); |
| this.instance = instance; |
| setShellStyle(getShellStyle() | SWT.RESIZE); |
| bindingContext = new DataBindingContext(); |
| instance.eAdapters().add(new AdapterImpl() { |
| @Override |
| public void notifyChanged(Notification msg) { |
| updateStatus(); |
| } |
| }); |
| updateStatus(); |
| } |
| |
| private Text name; |
| private Group workingMode; |
| private Text commandLineOptions; |
| private Button summary; |
| private Button useTclVer; |
| private TreeViewer messageViewer; |
| |
| @Override |
| protected Control createDialogArea(Composite parent) { |
| Composite dialogArea = (Composite) super.createDialogArea(parent); |
| Composite content = new Composite(dialogArea, SWT.NONE); |
| content.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| final GridLayout contentLayout = new GridLayout(2, false); |
| contentLayout.marginHeight = 0; |
| content.setLayout(contentLayout); |
| initNameGroup(content); |
| GridData modeLayoutData = new GridData(GridData.FILL_HORIZONTAL); |
| modeLayoutData.horizontalSpan = 2; |
| initModeGroup(content, modeLayoutData); |
| initOptions(content); |
| initMessageOptions(content); |
| return dialogArea; |
| } |
| |
| protected void initNameGroup(Composite parent) { |
| Label nameLabel = new Label(parent, SWT.NONE); |
| nameLabel.setText(Messages.TclCheckerConfigurationDialog_ConfigurationName); |
| name = new Text(parent, SWT.BORDER); |
| name.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(name), |
| EMFObservables.observeValue(instance, ValidatorsPackage.Literals.VALIDATOR_CONFIG__NAME), null, null); |
| } |
| |
| protected void initModeGroup(Composite parent, Object layoutData) { |
| workingMode = new Group(parent, SWT.NONE); |
| workingMode.setText(Messages.TclChecker_mode); |
| workingMode.setLayoutData(layoutData); |
| |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 1; |
| layout.verticalSpacing = 2; |
| workingMode.setLayout(layout); |
| |
| Map<Button, CheckerMode> modeOptions = new HashMap<>(); |
| createModeOption(workingMode, Messages.TclChecker_mode_default, modeOptions, CheckerMode.DEFAULT); |
| createModeOption(workingMode, Messages.TclChecker_mode_none, modeOptions, CheckerMode.W0); |
| createModeOption(workingMode, Messages.TclChecker_mode_errors, modeOptions, CheckerMode.W1); |
| createModeOption(workingMode, Messages.TclChecker_mode_errorsAndUsageWarnings, modeOptions, CheckerMode.W2); |
| createModeOption(workingMode, Messages.TclChecker_mode_errorsAndWarningsExceptUpgrade, modeOptions, |
| CheckerMode.W3); |
| createModeOption(workingMode, Messages.TclChecker_mode_all, modeOptions, CheckerMode.W4); |
| bindingContext.bindValue(new RadioButtonListValue<>(CheckerMode.class, modeOptions), |
| EMFObservables.observeValue(instance, ConfigsPackage.Literals.CHECKER_CONFIG__MODE), null, null); |
| } |
| |
| private void createModeOption(Group parent, String text, Map<Button, CheckerMode> modeOptions, |
| CheckerMode checkerMode) { |
| final Button button = new Button(parent, SWT.RADIO); |
| button.setText(text); |
| modeOptions.put(button, checkerMode); |
| } |
| |
| protected void initOptions(Composite parent) { |
| Group group = SWTFactory.createGroup(parent, Messages.TclCheckerConfigurationDialog_Options, 2, 2, |
| GridData.FILL_HORIZONTAL); |
| Label nameLabel = new Label(group, SWT.NONE); |
| nameLabel.setText(Messages.TclCheckerConfigurationDialog_CommandLineOptions); |
| commandLineOptions = new Text(group, SWT.BORDER); |
| commandLineOptions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(commandLineOptions), EMFObservables |
| .observeValue(instance, ValidatorsPackage.Literals.VALIDATOR_CONFIG__COMMAND_LINE_OPTIONS), null, null); |
| summary = SWTFactory.createCheckButton(group, Messages.TclCheckerConfigurationDialog_Summary, null, false, 2); |
| bindingContext.bindValue(WidgetProperties.buttonSelection().observe(summary), |
| EMFObservables.observeValue(instance, ConfigsPackage.Literals.CHECKER_CONFIG__SUMMARY), null, null); |
| useTclVer = SWTFactory.createCheckButton(group, Messages.TclCheckerConfigurationDialog_UseTclVer, null, false, |
| 2); |
| bindingContext.bindValue(WidgetProperties.buttonSelection().observe(useTclVer), |
| EMFObservables.observeValue(instance, ConfigsPackage.Literals.CHECKER_CONFIG__USE_TCL_VER), null, null); |
| } |
| |
| private void initMessageOptions(Composite parent) { |
| final Group group = SWTFactory.createGroup(parent, Messages.TclChecker_suppressProblems, 2, 2, |
| GridData.FILL_BOTH); |
| final Button individualMessageConfiguration = SWTFactory.createCheckButton(group, |
| Messages.TclCheckerConfigurationDialog_MessageConfiguration, null, false, 2); |
| bindingContext.bindValue(WidgetProperties.buttonSelection().observe(individualMessageConfiguration), EMFObservables |
| .observeValue(instance, ConfigsPackage.Literals.CHECKER_CONFIG__INDIVIDUAL_MESSAGE_STATES), null, null); |
| final Composite messageContainer = new Composite(group, SWT.NONE); |
| final GridLayout messageContainerLayout = new GridLayout(2, false); |
| messageContainerLayout.marginWidth = 0; |
| messageContainerLayout.marginHeight = 0; |
| messageContainer.setLayout(messageContainerLayout); |
| messageContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| final Composite messageComposite = new Composite(messageContainer, SWT.NONE); |
| final TreeColumnLayout messageTreeLayout = new TreeColumnLayout(); |
| messageComposite.setLayout(messageTreeLayout); |
| final GridData messageGridData = new GridData(GridData.FILL_BOTH); |
| messageGridData.heightHint = new PixelConverter(parent).convertHeightInCharsToPixels(16); |
| messageComposite.setLayoutData(messageGridData); |
| final Tree messageTree = new Tree(messageComposite, SWT.BORDER | SWT.FULL_SELECTION); |
| messageTree.setHeaderVisible(true); |
| messageTree.setLinesVisible(true); |
| final TreeColumn nameColumn = new TreeColumn(messageTree, SWT.LEFT); |
| nameColumn.setText(Messages.TclChecker_problems_name); |
| messageTreeLayout.setColumnData(nameColumn, new ColumnWeightData(60)); |
| final TreeColumn typeColumn = new TreeColumn(messageTree, SWT.LEFT); |
| typeColumn.setText(Messages.TclChecker_problems_type); |
| messageTreeLayout.setColumnData(typeColumn, new ColumnWeightData(20)); |
| final TreeColumn actionColumn = new TreeColumn(messageTree, SWT.LEFT); |
| actionColumn.setText(Messages.TclChecker_problems_action); |
| messageTreeLayout.setColumnData(actionColumn, new ColumnWeightData(20)); |
| messageViewer = new TreeViewer(messageTree); |
| new TreeViewerColumn(messageViewer, actionColumn) |
| .setEditingSupport(new TclCheckerMessageActionEditingSupport(messageViewer)); |
| messageViewer.setLabelProvider(new MessageLabelProvider()); |
| messageViewer.setContentProvider(new MessageContentProvider()); |
| messageViewer.setComparator(new MessageViewerComparator()); |
| final List<MessageGroup> problemGroups = TclCheckerProblemDescription.getProblemGroups(); |
| messageViewer.setInput(problemGroups); |
| messageViewer.expandToLevel(problemGroups.get(0), 1); |
| final Composite buttonContainer = new Composite(messageContainer, SWT.NONE); |
| final GridLayout buttonContainerLayout = new GridLayout(1, false); |
| buttonContainerLayout.marginHeight = 0; |
| buttonContainerLayout.marginWidth = 0; |
| buttonContainerLayout.marginLeft = 5; |
| buttonContainer.setLayout(buttonContainerLayout); |
| final GridData buttonContainerLayoutData = new GridData(SWT.CENTER, SWT.BEGINNING, false, true); |
| buttonContainer.setLayoutData(buttonContainerLayoutData); |
| SWTFactory.createPushButton(buttonContainer, Messages.TclChecker_processType_defaultAll, null) |
| .addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| instance.getMessageStates().clear(); |
| messageViewer.refresh(); |
| } |
| }); |
| SWTFactory.createPushButton(buttonContainer, Messages.TclChecker_processType_checkAll) |
| .addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fillMessageState(MessageState.CHECK); |
| } |
| }); |
| SWTFactory.createPushButton(buttonContainer, Messages.TclChecker_processType_suppressAll) |
| .addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fillMessageState(MessageState.SUPPRESS); |
| } |
| }); |
| individualMessageConfiguration.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| updateMessageViewerStatus(buttonContainer, individualMessageConfiguration.getSelection()); |
| } |
| }); |
| updateMessageViewerStatus(buttonContainer, instance.isIndividualMessageStates()); |
| } |
| |
| private void updateMessageViewerStatus(final Composite buttonContainer, final boolean enable) { |
| messageViewer.getControl().setEnabled(enable); |
| for (Control child : buttonContainer.getChildren()) { |
| if (child instanceof Button) { |
| child.setEnabled(enable); |
| } |
| } |
| } |
| |
| /** |
| * @param newState |
| */ |
| protected void fillMessageState(MessageState newState) { |
| for (String messageId : TclCheckerProblemDescription.getProblemIdentifiers()) { |
| MessageState oldState = instance.getMessageStates().get(messageId); |
| if (oldState != newState) { |
| instance.getMessageStates().put(messageId, newState); |
| } |
| } |
| messageViewer.refresh(); |
| } |
| |
| private void updateStatus() { |
| updateStatus(validate()); |
| } |
| |
| /** |
| * @return |
| */ |
| protected IStatus validate() { |
| final String configurationName = instance.getName(); |
| if (configurationName == null || configurationName.trim().length() == 0) { |
| return new StatusInfo(IStatus.ERROR, Messages.TclCheckerConfigurationDialog_errorEmptyConfigurationName); |
| } |
| return StatusInfo.OK_STATUS; |
| } |
| |
| @Override |
| public boolean close() { |
| bindingContext.dispose(); |
| return super.close(); |
| } |
| |
| @Override |
| protected Point getInitialSize() { |
| final Point p = super.getInitialSize(); |
| final int expectedWidth = new PixelConverter(getShell()).convertWidthInCharsToPixels(110); |
| if (p.x < expectedWidth) { |
| p.x = expectedWidth; |
| } |
| return p; |
| } |
| |
| } |