/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow.execute; import java.awt.GraphicsEnvironment; import java.io.ByteArrayInputStream; import java.text.CollationKey; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import de.rcenvironment.core.component.validation.api.ComponentValidationMessage; import de.rcenvironment.core.component.validation.api.ComponentValidationMessage.Type; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription; import de.rcenvironment.core.component.workflow.model.api.WorkflowNode; import de.rcenvironment.core.gui.resources.api.ImageManager; import de.rcenvironment.core.gui.resources.api.StandardImages; import de.rcenvironment.core.gui.workflow.Activator; /** * * A message dialog displaying a list of error and warning messages. * * @author Jascha Riedel */ public class WorkflowExecutionWizardValidationDialog extends TitleAreaDialog { private static final String DIALOG_TITLE = "Validation Report"; private static final String INDEX = "index"; private static final String ORDER = "order"; private static final int MINUS_ONE = -1; /** * This ensures that the table extends to the end of the window since * grabExcessVerticalSpace does not seem to work correctly. */ private static final int MINIMUM_TABLE_SIZE = 10000; private Table table; /** * * Enum to save last order state. * * @author Jascha Riedel */ private enum OrderState { COMPONENT_UP, COMPONENT_DOWN, TYPE_UP, TYPE_DOWN, MESSAGE_UP, MESSAGE_DOWN; } private final Map<String, List<ComponentValidationMessage>> messagesMap; private final WorkflowDescription wfDescription; private final PlaceholderPage placeholderPage; private final ImageManager imageManger = ImageManager.getInstance(); public WorkflowExecutionWizardValidationDialog(Shell parentShell, Map<String, List<ComponentValidationMessage>> messagesMap, WorkflowDescription wfDescription, PlaceholderPage placeholderPage) { super(parentShell); this.messagesMap = messagesMap; this.wfDescription = wfDescription; this.placeholderPage = placeholderPage; } @Override protected void setShellStyle(int newShellStyle) { super.setShellStyle(newShellStyle | SWT.RESIZE); } @Override public void create() { super.create(); setTitle(DIALOG_TITLE); setMessageText(); } @Override protected Control createDialogArea(Composite parent) { Composite area = (Composite) super.createDialogArea(parent); area.setLayoutData(new GridData(SWT.FILL, GridData.FILL, true, true)); Composite container = new Composite(area, SWT.FILL); GridData data = new GridData(GridData.FILL_BOTH); data.heightHint = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode() .getHeight() * 2 / 5; data.widthHint = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode() .getWidth() * 2 / 3; data.grabExcessVerticalSpace = true; container.setLayoutData(data); GridLayout layout = new GridLayout(1, false); layout.marginWidth = 0; container.setLayout(layout); initilizeTable(container); createColumns(); fillTable(); Label horizontalBar = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL); horizontalBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); return container; } @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, 0, Messages.proceedButton, false); createButton(parent, 1, Messages.cancelButton, true); } private void setMessageText() { int messageCount = 0; for (String key : messagesMap.keySet()) { messageCount += messagesMap.get(key).size(); if (messageCount > 1) { break; } } for (String key : placeholderPage.getPlaceholderValidators().keySet()) { if (messageCount > 1) { break; } messageCount += placeholderPage.getPlaceholderValidators().get(key).size(); } boolean hasErrorMessage = false; for (String key : messagesMap.keySet()) { for (ComponentValidationMessage message : messagesMap.get(key)) { if (message.getType() == ComponentValidationMessage.Type.ERROR) { hasErrorMessage = true; break; } } if (hasErrorMessage) { break; } } String titleText; if (messageCount > 1) { titleText = Messages.validationProblems; } else { titleText = Messages.validationProblem; } if (hasErrorMessage) { setMessage(titleText, IMessageProvider.ERROR); } else { setMessage(titleText, IMessageProvider.WARNING); } } private void initilizeTable(Composite parent) { table = new Table(parent, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL); table.setLinesVisible(true); table.setHeaderVisible(true); GridData data = new GridData(GridData.FILL_BOTH); data.verticalAlignment = GridData.CENTER; data.grabExcessVerticalSpace = true; data.heightHint = MINIMUM_TABLE_SIZE; table.setLayoutData(data); table.addKeyListener(new TableCopyKeyListener()); table.addMouseListener(new TableCopyMouseListener()); } private void createColumns() { TableColumn componentColumn = new TableColumn(table, SWT.NONE); componentColumn.setText("Component"); componentColumn.setData(INDEX, 0); componentColumn.addSelectionListener(new SortColumnListener()); componentColumn.setData(ORDER, OrderState.COMPONENT_UP); table.notifyListeners(SWT.Selection, new Event()); TableColumn typeColumn = new TableColumn(table, SWT.NONE); typeColumn.setText("Type"); typeColumn.setData(INDEX, 1); typeColumn.addSelectionListener(new SortColumnListener()); typeColumn.setData(ORDER, OrderState.TYPE_UP); TableColumn messageColumn = new TableColumn(table, SWT.NONE); messageColumn.setText("Message"); messageColumn.setData(INDEX, 2); messageColumn.addSelectionListener(new SortColumnListener()); messageColumn.setData(ORDER, OrderState.MESSAGE_UP); } private void fillTable() { for (String nodeIdentifier : messagesMap.keySet()) { WorkflowNode currentNode = null; for (WorkflowNode node : wfDescription.getWorkflowNodes()) { if (node.getIdentifier().equals(nodeIdentifier)) { currentNode = node; break; } } if (currentNode == null) { continue; } String nodeName = currentNode.getName(); if (placeholderPage.getPlaceholderValidators().containsKey(nodeName)) { for (String placeholderName : placeholderPage.getPlaceholderValidators().get(nodeName)) { addMessageItem(currentNode, Type.ERROR, Messages.missingPlaceholder + placeholderName); } } for (ComponentValidationMessage message : messagesMap.get(nodeIdentifier)) { addMessageItem(currentNode, message.getType(), message.getAbsoluteMessage()); } } new SortColumnListener().intialSort(); table.getColumn(0).pack(); table.getColumn(1).pack(); table.getColumn(2).pack(); } private Image getImage(WorkflowNode element) { byte[] icon = element.getComponentDescription().getIcon16(); Image image; if (icon != null) { image = new Image(Display.getCurrent(), new ByteArrayInputStream(icon)); } else { image = Activator.getInstance().getImageRegistry().get(Activator.IMAGE_RCE_ICON_16); } return image; } private void addMessageItem(WorkflowNode node, ComponentValidationMessage.Type type, String message) { TableItem item = new TableItem(table, SWT.NONE); item.setImage(0, getImage(node)); item.setText(0, node.getName()); switch (type) { case ERROR: item.setImage(1, imageManger.getSharedImage(StandardImages.ERROR_16)); item.setText(1, type.toString()); break; case WARNING: item.setImage(1, imageManger.getSharedImage(StandardImages.WARNING_16)); item.setText(1, type.toString()); break; default: item.setImage(1, imageManger.getSharedImage(StandardImages.ERROR_16)); item.setText(1, Type.ERROR.toString()); break; } item.setText(2, message); } private String buildCopyString(TableItem[] tableItems) { String returnString = ""; for (int i = 0; i < tableItems.length; i++) { returnString += tableItems[i].getText(0); returnString += " - "; returnString += tableItems[i].getText(1); returnString += " - "; returnString += tableItems[i].getText(2); returnString += "\n"; } return returnString; } /** * * Table copy key listener. * * @author Jascha Riedel */ private class TableCopyKeyListener implements KeyListener { @Override public void keyPressed(KeyEvent arg0) { if (arg0.getSource() instanceof Table) { if (arg0.stateMask == SWT.CTRL && arg0.keyCode == 'c') { TableItem[] tableItems = ((Table) arg0.getSource()).getSelection(); Clipboard clipboard = new Clipboard(getShell().getDisplay()); TextTransfer textTransfer = TextTransfer.getInstance(); String copyString = buildCopyString(tableItems); clipboard.setContents(new String[] { copyString }, new Transfer[] { textTransfer }); clipboard.dispose(); } } } @Override public void keyReleased(KeyEvent arg0) { } } /** * * Table Copy Mouse Listener. * * @author Jascha Riedel */ private class TableCopyMouseListener implements MouseListener { @Override public void mouseDoubleClick(MouseEvent arg0) { } @Override public void mouseDown(MouseEvent event) { if (event.button == 3) { final Menu menu = new Menu(table); MenuItem newItem = new MenuItem(menu, SWT.NONE); newItem.setText("Copy"); newItem.setImage(imageManger.getSharedImage(StandardImages.COPY_16)); menu.setVisible(true); newItem.addSelectionListener(new SelectionListener() { @Override public void widgetDefaultSelected(SelectionEvent arg0) { } @Override public void widgetSelected(SelectionEvent arg0) { TableItem[] tableItems = table.getSelection(); Clipboard clipboard = new Clipboard(getShell().getDisplay()); TextTransfer textTransfer = TextTransfer.getInstance(); String copyString = buildCopyString(tableItems); clipboard.setContents(new String[] { copyString }, new Transfer[] { textTransfer }); clipboard.dispose(); menu.dispose(); } }); } } @Override public void mouseUp(MouseEvent arg0) { } } /** * Sort Column Listener. * * @author Jascha Riedel */ private class SortColumnListener implements SelectionListener { @Override public void widgetDefaultSelected(SelectionEvent arg0) { } @Override public void widgetSelected(SelectionEvent arg0) { TableColumn tableColumn = (TableColumn) arg0.getSource(); sortColumn(tableColumn); } public void intialSort() { sortColumn(table.getColumn(0)); } private void sortColumn(TableColumn tableColumn) { int index = (int) tableColumn.getData(INDEX); final int orderdir; orderdir = setOrderDirFromTableColumn(tableColumn); List<Object[]> list = new ArrayList<Object[]>(); Collator collator = Collator.getInstance(); collator.setStrength(Collator.PRIMARY); TableItem[] items = table.getItems(); for (int i = 0; i < items.length; i++) { list.add(new Object[] { collator.getCollationKey(items[i].getText(index)), getItemData(items[i]) }); } Collections.sort(list, new Comparator<Object[]>() { @Override public int compare(Object[] arg0, Object[] arg1) { return orderdir * ((CollationKey) arg0[0]).compareTo((CollationKey) arg1[0]); } }); for (int i = 0; i < items.length; i++) { setItemData(items[i], (Object[]) list.get(i)[1]); } } private int setOrderDirFromTableColumn(TableColumn tableColumn) { int orderdir; OrderState orderState = (OrderState) tableColumn.getData(ORDER); switch ((Integer) tableColumn.getData(INDEX)) { case 0: switch (orderState) { case COMPONENT_UP: orderdir = 1; tableColumn.setData(ORDER, OrderState.COMPONENT_DOWN); break; case COMPONENT_DOWN: orderdir = MINUS_ONE; tableColumn.setData(ORDER, OrderState.COMPONENT_UP); break; default: orderdir = 1; tableColumn.setData(ORDER, OrderState.COMPONENT_DOWN); break; } break; case 1: switch (orderState) { case TYPE_UP: orderdir = 1; tableColumn.setData(ORDER, OrderState.TYPE_DOWN); break; case TYPE_DOWN: orderdir = MINUS_ONE; tableColumn.setData(ORDER, OrderState.TYPE_UP); break; default: orderdir = 1; tableColumn.setData(ORDER, OrderState.TYPE_DOWN); break; } break; case 2: switch (orderState) { case MESSAGE_UP: orderdir = 1; tableColumn.setData(ORDER, OrderState.MESSAGE_DOWN); break; case MESSAGE_DOWN: orderdir = MINUS_ONE; tableColumn.setData(ORDER, OrderState.MESSAGE_UP); break; default: orderdir = 1; tableColumn.setData(ORDER, OrderState.MESSAGE_DOWN); break; } break; default: orderdir = 1; tableColumn.setData(ORDER, OrderState.COMPONENT_DOWN); break; } return orderdir; } private Object[] getItemData(TableItem item) { return new Object[] { item.getText(0), item.getText(1), item.getText(2), item.getImage(0), item.getImage(1), item.getImage(2) }; } private void setItemData(TableItem item, Object[] object) { String[] values = { (String) object[0], (String) object[1], (String) object[2] }; Image[] images = { (Image) object[3], (Image) object[4], (Image) object[5] }; item.setText(values); item.setImage(images); } } }