package org.csstudio.sds.ui.internal.editor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import org.csstudio.platform.model.pvs.IProcessVariableAddress; import org.csstudio.sds.SdsPlugin; import org.csstudio.sds.internal.eventhandling.BehaviorDescriptor; import org.csstudio.sds.model.WidgetModelFactoryService; import org.csstudio.ui.util.CustomMediaFactory; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.model.BaseWorkbenchContentProvider; /** * Dialog that allows for choosing the main process variable and widget behavior * as well as the widget type (optional). * * @author Sven Wende, Kai Meyer */ final class WidgetCreationDialog extends Dialog { private List<IProcessVariableAddress> processVariables; private TreeViewer widgetTypeViewerLeft; private ComboViewer processVariablesCombo; private Text processVariableText; private String selectedWidgetType; private String selectedProcessVariable; private ListViewer behaviorViewer; private String selectedBehaviourId; private String fixWidgetType; private Label processVariableLabel; private Label widgetTypeLabel; private Label behaviorLabel; private TreeViewer widgetTypeViewerRight; public WidgetCreationDialog(final Shell parentShell, List<IProcessVariableAddress> processVariables, String fixWidgetType) { super(parentShell); this.processVariables = processVariables != null ? processVariables : new ArrayList<IProcessVariableAddress>(); this.fixWidgetType = fixWidgetType; } @Override protected void configureShell(final Shell shell) { super.configureShell(shell); shell.setText("Configure Widget"); shell.setSize(525, fixWidgetType != null ? 280 : 600); } @Override protected Control createDialogArea(final Composite parent) { Composite dialogArea = new Composite(parent, SWT.NONE); dialogArea.setLayoutData(new GridData(GridData.FILL_BOTH)); dialogArea.setFont(parent.getFont()); dialogArea.setLayout(new FormLayout()); createProcessVariableLabel(dialogArea); if (processVariables.size() > 1) { createProcessVariableCombo(dialogArea); } else { createProcessVariableTextbox(dialogArea); } createBehaviorLabel(dialogArea); createBehaviourViewer(dialogArea); if (fixWidgetType != null) { updateBehaviours(fixWidgetType); } else { createWidgetTypeLabel(dialogArea); createWidgetTypeViewers(dialogArea); } return dialogArea; } private void createWidgetTypeLabel(Composite dialogArea) { widgetTypeLabel = new Label(dialogArea, SWT.NONE); widgetTypeLabel.setText("Widget type:"); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(widgetTypeViewerLeft != null ? widgetTypeViewerLeft.getControl() : behaviorViewer.getControl(), 10); fd.right = new FormAttachment(100, -10); widgetTypeLabel.setLayoutData(fd); } private void createBehaviorLabel(Composite dialogArea) { behaviorLabel = new Label(dialogArea, SWT.NONE); behaviorLabel.setText("Behavior:"); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(processVariableText != null ? processVariableText : processVariablesCombo.getControl(), 10); fd.right = new FormAttachment(100, -10); behaviorLabel.setLayoutData(fd); } private void createProcessVariableLabel(Composite dialogArea) { processVariableLabel = new Label(dialogArea, SWT.NONE); processVariableLabel.setText("Process variable:"); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(0, 10); fd.right = new FormAttachment(100, -10); processVariableLabel.setLayoutData(fd); } private void createBehaviourViewer(Composite composite) { behaviorViewer = new ListViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(behaviorLabel, 5); fd.right = new FormAttachment(100, -10); if (fixWidgetType == null) { fd.height = 85; } else { fd.bottom = new FormAttachment(100, -10); } behaviorViewer.getControl().setLayoutData(fd); behaviorViewer.setContentProvider(new ArrayContentProvider()); behaviorViewer.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { BehaviorDescriptor d = (BehaviorDescriptor) element; return d.getDescription(); } }); } private void updateBehaviours(String widgetType) { List<BehaviorDescriptor> result = new ArrayList<BehaviorDescriptor>(); result.add(new BehaviorDescriptor("none", "*", "None", Collections.EMPTY_SET, null)); result.addAll(SdsPlugin.getDefault().getBehaviourService().getBehaviors(widgetType)); behaviorViewer.setInput(result); behaviorViewer.getControl().getParent().layout(); behaviorViewer.getControl().redraw(); } private void createProcessVariableTextbox(Composite parent) { processVariableText = new Text(parent, SWT.None); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(processVariableLabel, 5); fd.right = new FormAttachment(100, -10); fd.height = 20; processVariableText.setLayoutData(fd); processVariableText.setText(processVariables.size() > 0 ? processVariables.get(0).getFullName() : ""); } private void createProcessVariableCombo(Composite parent) { CCombo combo = new CCombo(parent, SWT.None); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(processVariableLabel, 5); fd.right = new FormAttachment(100, -10); fd.height = 30; combo.setLayoutData(fd); processVariablesCombo = new ComboViewer(combo); processVariablesCombo.setContentProvider(ArrayContentProvider.getInstance()); processVariablesCombo.setLabelProvider(new LabelProvider()); processVariablesCombo.setInput(processVariables.toArray()); processVariablesCombo.setSelection(new StructuredSelection(processVariables.get(0))); } private final class WidgetTypeSelectionListener implements ISelectionChangedListener { private TreeViewer secondWidgetTypeViewer; public WidgetTypeSelectionListener(TreeViewer secondWidgetTypeViewer) { this.secondWidgetTypeViewer = secondWidgetTypeViewer; } @Override public void selectionChanged(SelectionChangedEvent event) { if (event.getSelection() != null) { if (!event.getSelection().isEmpty()) { WidgetTypeInput widgetType = (WidgetTypeInput) ((IStructuredSelection) event.getSelection()).getFirstElement(); if (widgetType != null) { updateBehaviours(widgetType.getTypeId()); } secondWidgetTypeViewer.setSelection(new StructuredSelection()); } } } } private void createWidgetTypeViewers(final Composite parent) { Set<String> allWidgetTypes = WidgetModelFactoryService.getInstance().getUsedWidgetTypes(); WidgetTypeInput[] widgetTypes = new WidgetTypeInput[allWidgetTypes.size()]; int i = 0; for (String typeId : allWidgetTypes) { WidgetTypeInput widgetType = new WidgetTypeInput(); widgetType.setName(WidgetModelFactoryService.getInstance().getName(typeId)); widgetType.setTypeId(typeId); String contributingPluginId = WidgetModelFactoryService.getInstance().getContributingPluginId((String) typeId); String iconPath = WidgetModelFactoryService.getInstance().getIcon((String) typeId); widgetType.setIcon(CustomMediaFactory.getInstance().getImageFromPlugin(contributingPluginId, iconPath)); widgetTypes[i++] = widgetType; } Arrays.sort(widgetTypes); int n = widgetTypes.length; int cut = ((n - (n % 2)) / 2) + n % 2; widgetTypeViewerLeft = new TreeViewer(parent, SWT.SINGLE); FormData fd = new FormData(); fd.left = new FormAttachment(0, 10); fd.top = new FormAttachment(widgetTypeLabel, 5); fd.right = new FormAttachment(50, 0); fd.bottom = new FormAttachment(100, -10); widgetTypeViewerLeft.getControl().setLayoutData(fd); widgetTypeViewerLeft.setContentProvider(new WidgetTypeContentProvider()); widgetTypeViewerLeft.setLabelProvider(new WidgetTypeLabelProvider()); widgetTypeViewerLeft.setInput(Arrays.copyOfRange(widgetTypes, 0, cut - 1)); widgetTypeViewerRight = new TreeViewer(parent, SWT.SINGLE); fd = new FormData(); fd.left = new FormAttachment(widgetTypeViewerLeft.getControl(), 0); fd.top = new FormAttachment(widgetTypeLabel, 5); fd.right = new FormAttachment(100, -10); fd.bottom = new FormAttachment(100, -10); widgetTypeViewerRight.getControl().setLayoutData(fd); widgetTypeViewerRight.setContentProvider(new WidgetTypeContentProvider()); widgetTypeViewerRight.setLabelProvider(new WidgetTypeLabelProvider()); widgetTypeViewerRight.setInput(Arrays.copyOfRange(widgetTypes, cut, n)); widgetTypeViewerLeft.addSelectionChangedListener(new WidgetTypeSelectionListener(widgetTypeViewerRight)); widgetTypeViewerRight.addSelectionChangedListener(new WidgetTypeSelectionListener(widgetTypeViewerLeft)); } public String getSelectedWidgetType() { return selectedWidgetType; } public String getSelectedProcessVariable() { return selectedProcessVariable; } public String getSelectedBehaviourId() { return selectedBehaviourId; } @Override protected void okPressed() { if (processVariableText != null) { selectedProcessVariable = processVariableText.getText(); } else { selectedProcessVariable = processVariablesCombo.getCCombo().getText(); } if (behaviorViewer != null && behaviorViewer.getSelection() != null) { BehaviorDescriptor behavior = (BehaviorDescriptor) ((IStructuredSelection) behaviorViewer.getSelection()).getFirstElement(); selectedBehaviourId = behavior != null ? behavior.getBehaviorId() : null; } if (widgetTypeViewerLeft != null) { selectedWidgetType = resolveWidgetTypeFromSelection(widgetTypeViewerLeft.getSelection()); if (selectedWidgetType == null) { selectedWidgetType = resolveWidgetTypeFromSelection(widgetTypeViewerRight.getSelection()); } } super.okPressed(); } private String resolveWidgetTypeFromSelection(ISelection selection) { String result = null; if (selection != null && selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection) selection; if (!structuredSelection.isEmpty()) { Object o = structuredSelection.getFirstElement(); if (o instanceof WidgetTypeInput) { result = ((WidgetTypeInput) o).getTypeId(); } } } return result; } private final class WidgetTypeContentProvider extends BaseWorkbenchContentProvider { @Override public Object[] getElements(Object element) { return (WidgetTypeInput[]) element; } } private final class WidgetTypeLabelProvider extends LabelProvider { @Override public String getText(Object o) { return ((WidgetTypeInput) o).getName(); } @Override public Image getImage(Object o) { return ((WidgetTypeInput) o).getIcon(); } } private static class WidgetTypeInput implements Comparable<WidgetTypeInput> { private String typeId; private String name; private Image icon; public void setTypeId(String typeId) { this.typeId = typeId; } public void setName(String name) { this.name = name; } public void setIcon(Image icon) { this.icon = icon; } public String getTypeId() { return typeId; } public Image getIcon() { return icon; } public String getName() { return name; } @Override public int compareTo(WidgetTypeInput other) { return name.compareTo(other.name); } } }