/******************************************************************************* * Copyright (c) 2016 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are 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: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.extensions.wizard.view; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener; import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.jubula.extensions.wizard.edit.ActionEditingSupport; import org.eclipse.jubula.extensions.wizard.i18n.Messages; import org.eclipse.jubula.extensions.wizard.model.Action; import org.eclipse.jubula.extensions.wizard.model.Parameter; import org.eclipse.jubula.extensions.wizard.model.Storage; import org.eclipse.jubula.extensions.wizard.utils.Status; import org.eclipse.jubula.extensions.wizard.utils.Tools; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; /** * The fourth New Jubula Extension Wizard page in which the user can specify * the tester class name and the tester actions. * * @author BREDEX GmbH */ public final class NewJubulaExtensionWizardPageFour extends WizardPage { /** The page's ID */ private static final String PAGE_NAME = Messages.PageFour_PageName; /** The page's title */ private static final String PAGE_TITLE = Messages.PageFour_PageTitle; /** The page's description */ private static final String PAGE_DESCRIPTION = Messages.PageFour_PageDescription; /** The parent container */ private Composite m_container; /** The class name textbox */ private Text m_className; /** * The actions group which contains the actions table and * the control buttons. */ private Group m_actionsGroup; /** The tableviewer */ private TableViewer m_tableViewer; /** The "New" button */ private Button m_newButton; /** The "Remove" button */ private Button m_removeButton; /** The "Properties" button */ private Button m_parametersButton; /** The "Up" button */ private Button m_upButton; /** The "Down" button */ private Button m_downButton; /** The actions list */ private List<Action> m_actions = new ArrayList<>(); /** The instance of this wizard's storage */ private final Storage m_storage; /** * The constructor * @param storage the storage instance this page instance should use */ public NewJubulaExtensionWizardPageFour(Storage storage) { super(PAGE_NAME); setTitle(PAGE_TITLE); setDescription(PAGE_DESCRIPTION); m_storage = storage; } @Override public void createControl(Composite parent) { m_container = new Composite(parent, SWT.NONE); setControl(m_container); m_container.setLayout(new FormLayout()); createClassName(); createGroup(); createNewButton(); createTable(); createParametersButton(); createRemoveButton(); createUpButton(); createDownButton(); createSeparatorLine(); m_actionsGroup.setTabList(new Control[] { m_tableViewer.getTable(), m_newButton, m_parametersButton, m_removeButton, m_upButton, m_downButton }); m_storage.setActions(m_actions); } @Override public void setVisible(boolean visible) { if (visible) { setDefaultClassName(); PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), Messages.PageFourQualifier); } super.setVisible(visible); } /** Creates the class name label, textbox and their controls */ private void createClassName() { final Storage storage = m_storage; Label lblClassName = new Label(m_container, SWT.NONE); FormData fdLblClassName = new FormData(); fdLblClassName.top = new FormAttachment(0, 13); lblClassName.setLayoutData(fdLblClassName); lblClassName.setText(Messages.PageFour_ClassNameTxt); m_className = new Text(m_container, SWT.BORDER); fdLblClassName.right = new FormAttachment(m_className, 0); fdLblClassName.left = new FormAttachment(0, 10); FormData fdClassName = new FormData(); fdClassName.top = new FormAttachment(0, 10); fdClassName.left = new FormAttachment(lblClassName, 30); fdClassName.right = new FormAttachment(100, -10); m_className.setLayoutData(fdClassName); m_className.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (Tools .isJavaIdentifier(m_className.getText())) { setErrorMessage(null); storage.setClassName(m_className.getText()); } else { setErrorMessage(Messages.PageFour_ClassnameInvalidMsg); } } }); } /** * Initializes the class name text field with a default value */ private void setDefaultClassName() { Storage storage = m_storage; String component = storage.getComponent(); String defaultClassName = "My" + component.substring(//$NON-NLS-1$ component.lastIndexOf('.') + 1) + "Tester"; //$NON-NLS-1$ m_className.setText(defaultClassName); storage.setClassName(defaultClassName); } /** Creates the actions group */ private void createGroup() { m_actionsGroup = new Group(m_container, SWT.NONE); m_actionsGroup.setText(Messages.PageFour_ActionsTxt); m_actionsGroup.setLayout(new FormLayout()); FormData fdMethodsGroup = new FormData(); fdMethodsGroup.right = new FormAttachment(100, -10); fdMethodsGroup.bottom = new FormAttachment(m_className, 218, SWT.BOTTOM); fdMethodsGroup.top = new FormAttachment(m_className, 17); fdMethodsGroup.left = new FormAttachment(0, 10); m_actionsGroup.setLayoutData(fdMethodsGroup); } /** Creates the "New" button and its controls */ private void createNewButton() { m_newButton = new Button(m_actionsGroup, SWT.NONE); FormData fdNewButton = new FormData(); fdNewButton.height = 25; fdNewButton.width = 75; fdNewButton.right = new FormAttachment(100, -10); fdNewButton.top = new FormAttachment(0, 9); m_newButton.setLayoutData(fdNewButton); m_newButton.setText(Messages.PageFour_NewButtonTxt); m_newButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int lastIndex = m_tableViewer.getTable().getItems().length; m_actions.add(new Action("Action " + (lastIndex + 1))); //$NON-NLS-1$ refreshTableData(); m_tableViewer.getTable().setSelection(lastIndex); controlButtonActivation(); validatePageComplete(); } }); } /** Creates the table and its controls */ private void createTable() { m_tableViewer = new TableViewer(m_actionsGroup, SWT.BORDER); FormData fdMethodsList = new FormData(); fdMethodsList.left = new FormAttachment(0, 10); fdMethodsList.right = new FormAttachment(m_newButton, -10); fdMethodsList.bottom = new FormAttachment(100, -10); fdMethodsList.top = new FormAttachment(0, 10); m_tableViewer.getControl().setLayoutData(fdMethodsList); m_tableViewer.getTable().setHeaderVisible(true); m_tableViewer.getTable().setLinesVisible(false); m_tableViewer.addSelectionChangedListener( new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { if (m_tableViewer.getTable().getSelectionCount() == 0) { m_parametersButton.setEnabled(false); } else { m_parametersButton.setEnabled(true); } } }); createColumns(); m_tableViewer.getColumnViewerEditor().addEditorActivationListener( new ColumnViewerEditorActivationListener() { @Override public void beforeEditorDeactivated( ColumnViewerEditorDeactivationEvent event) { // Not needed } @Override public void beforeEditorActivated( ColumnViewerEditorActivationEvent event) { // Not needed } @Override public void afterEditorDeactivated( ColumnViewerEditorDeactivationEvent event) { refreshTableData(); } @Override public void afterEditorActivated( ColumnViewerEditorActivationEvent event) { // Not needed } }); m_tableViewer.setContentProvider(new ArrayContentProvider()); refreshTableData(); } /** Fills the table with data */ public void refreshTableData() { m_tableViewer.setInput(m_actions); validatePageComplete(); } /** Creates the table's columns */ private void createColumns() { TableViewerColumn nameColumn = new TableViewerColumn(m_tableViewer, SWT.NONE); nameColumn.getColumn().setText(Messages.PageFour_NameColumnTxt); nameColumn.getColumn().setWidth(150); nameColumn.getColumn().setResizable(true); nameColumn.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof Action) { Action action = (Action) element; return action.getName(); } return null; } }); nameColumn.setEditingSupport(new ActionEditingSupport(m_tableViewer)); TableViewerColumn parametersColumn = new TableViewerColumn(m_tableViewer, SWT.NONE); parametersColumn.getColumn() .setText(Messages.PageFour_ParametersColumnTxt); parametersColumn.getColumn().setWidth(150); parametersColumn.getColumn().setResizable(true); parametersColumn.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof Action) { Action action = (Action) element; return action.getParametersAsString(); } return null; } }); parametersColumn.getViewer().addDoubleClickListener( new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { openPropertiesWindow(); } }); } /** Creates the parameters button and its controls */ private void createParametersButton() { m_parametersButton = new Button(m_actionsGroup, SWT.NONE); FormData fdParametersButton = new FormData(); fdParametersButton.right = new FormAttachment(100, -10); fdParametersButton.top = new FormAttachment(0, 40); fdParametersButton.left = new FormAttachment(m_tableViewer.getControl(), 10); m_parametersButton.setLayoutData(fdParametersButton); m_parametersButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { openPropertiesWindow(); } }); m_parametersButton.setText(Messages.PageFour_ParametersButtonTxt); m_parametersButton.setEnabled(false); } /** Creates the "Remove" button and its controls */ private void createRemoveButton() { m_removeButton = new Button(m_actionsGroup, SWT.NONE); FormData fdRemoveButton = new FormData(); fdRemoveButton.right = new FormAttachment(100, -10); fdRemoveButton.top = new FormAttachment(0, 71); fdRemoveButton.left = new FormAttachment(m_tableViewer.getControl(), 10); m_removeButton.setLayoutData(fdRemoveButton); m_removeButton.setText(Messages.PageFour_RemoveButonTxt); m_removeButton.setEnabled(false); m_removeButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int[] selectionIndices = m_tableViewer.getTable() .getSelectionIndices(); if (selectionIndices.length > 0) { removeActions(selectionIndices); refreshTableData(); m_tableViewer.getTable().setSelection(m_actions.size() - 1); } controlButtonActivation(); validatePageComplete(); } }); } /** * Creates the horizontal separator line between the "Remove" and "Up" * button. */ private void createSeparatorLine() { Label label = new Label(m_actionsGroup, SWT.SEPARATOR | SWT.HORIZONTAL); FormData fdLabel = new FormData(); fdLabel.bottom = new FormAttachment(m_upButton, 7, SWT.TOP); fdLabel.top = new FormAttachment(m_removeButton, -7, SWT.BOTTOM); fdLabel.left = new FormAttachment(m_newButton, 0, SWT.LEFT); fdLabel.right = new FormAttachment(100, -10); label.setLayoutData(fdLabel); } /** * Removes the actions at the given indices * @param indices the indices of the actions to be deleted */ private void removeActions(int[] indices) { for (int i : indices) { m_actions.remove(i); } } /** Creates the "Up" button and its controls */ private void createUpButton() { m_upButton = new Button(m_actionsGroup, SWT.NONE); FormData fdUpButton = new FormData(); fdUpButton.right = new FormAttachment(100, -10); fdUpButton.top = new FormAttachment(m_removeButton, 14); fdUpButton.left = new FormAttachment(m_tableViewer.getControl(), 10); m_upButton.setLayoutData(fdUpButton); m_upButton.setText(Messages.PageFour_UpButtonTxt); m_upButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int index = m_tableViewer.getTable().getSelectionIndex(); if (index > 0) { Collections.swap(m_actions, index, index - 1); refreshTableData(); m_tableViewer.getTable().select(index - 1); } } }); } /** Creates the "Down" button and its controls */ private void createDownButton() { m_downButton = new Button(m_actionsGroup, SWT.NONE); FormData fdDownButton = new FormData(); fdDownButton.right = new FormAttachment(100, -10); fdDownButton.top = new FormAttachment(m_upButton, 7); fdDownButton.left = new FormAttachment(m_tableViewer.getControl(), 10); m_downButton.setLayoutData(fdDownButton); m_downButton.setText(Messages.PageFour_DownButtonTxt); m_downButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Table table = m_tableViewer.getTable(); int index = m_tableViewer.getTable().getSelectionIndex(); if (index > -1 && index < (table.getItemCount() - 1)) { Collections.swap(m_actions, index, index + 1); refreshTableData(); m_tableViewer.getTable().select(index + 1); } } }); } /** * Updates the action's data * @param action the action whose data should be updated */ public void updateMethodData(Action action) { m_tableViewer.update(action, null); validatePageComplete(); } /** Opens the "Properties" window */ private void openPropertiesWindow() { if (m_tableViewer.getTable().getSelectionCount() == 1) { new ActionParametersWindow(m_container.getShell(), (Action) m_tableViewer.getElementAt( m_tableViewer.getTable().getSelectionIndex()), this); } } /** * Activates the control buttons if there is more than one item in the list * and it is selected. Deactivates them otherwise. */ private void controlButtonActivation() { if (m_tableViewer.getTable().getItemCount() == 0) { m_removeButton.setEnabled(false); m_parametersButton.setEnabled(false); } else { m_removeButton.setEnabled(true); m_parametersButton.setEnabled(true); } } /** * Validates whether the page is complete. * @return {@code true} if the page is complete, {@code false} otherwise */ private boolean validatePageComplete() { Status status = validateActions(); switch (status) { case ACTIONS_NAME_ALREADY_EXISTS: setErrorMessage(Messages.PageFour_ActionNamesDuplicatesMsg); setPageComplete(false); return false; case ACTIONS_OK: setErrorMessage(null); setPageComplete(true); return true; case ACTIONS_PARAMETERS_NAME_ALREADY_EXISTS: setErrorMessage(Messages.PageFour_ParameterNamesDuplicatesMsg); setPageComplete(false); return false; default: throw new IllegalArgumentException(); } } /** * Validates whether the actions and their parameters do not contain * duplicates. * @return the suitable Status */ private Status validateActions() { Set<String> actionSet = new HashSet<>(); for (Action action : m_actions) { if (!actionSet.add(Tools .getCamelCase(action.getName()))) { return Status.ACTIONS_NAME_ALREADY_EXISTS; } List<Parameter> parameters = action.getParameters(); Set<String> paramSet = new HashSet<>(); for (Parameter param : parameters) { if (!paramSet.add(Tools.getCamelCase(param.getName()))) { return Status.ACTIONS_PARAMETERS_NAME_ALREADY_EXISTS; } } } return Status.ACTIONS_OK; } }