/*******************************************************************************
* Copyright (c) 2004, 2010 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.client.ui.rcp.preferences;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jubula.client.ui.constants.ContextHelpIds;
import org.eclipse.jubula.client.ui.rcp.Plugin;
import org.eclipse.jubula.client.ui.rcp.i18n.Messages;
import org.eclipse.jubula.client.ui.rcp.utils.AutAgentManager;
import org.eclipse.jubula.client.ui.validator.cell.PortCellEditorValidator;
import org.eclipse.jubula.tools.internal.constants.EnvConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
/**
* Preference page for configuring available AUT-Agents.
*
* @author BREDEX GmbH
* @created Jan 19, 2010
*/
public class AutAgentPreferencePage extends PreferencePage
implements IWorkbenchPreferencePage {
/** <code>LAYOUT_NUM_COLUMNS</code> */
private static final int LAYOUT_NUM_COLUMNS = 2;
/**
* @author BREDEX GmbH
* @created Jan 18, 2010
*/
private class ServerPortEditingSupport extends EditingSupport {
/**
* Constructor
*
* @param viewer The viewer
*/
public ServerPortEditingSupport(ColumnViewer viewer) {
super(viewer);
}
/**
* {@inheritDoc}
*/
protected boolean canEdit(Object element) {
return true;
}
/**
* {@inheritDoc}
*/
protected CellEditor getCellEditor(Object element) {
final TextCellEditor editor =
new TextCellEditor((Composite)getViewer().getControl());
editor.setValidator(new PortCellEditorValidator(
Messages.AutAgentPreferencePageColumnHeaderPort));
editor.addListener(new ICellEditorListener() {
public void applyEditorValue() {
AutAgentPreferencePage.this.setErrorMessage(null);
}
public void cancelEditor() {
AutAgentPreferencePage.this.setErrorMessage(null);
}
public void editorValueChanged(
boolean oldValidState, boolean newValidState) {
if (newValidState) {
editor.getControl().setBackground(null);
} else {
editor.getControl().setBackground(
editor.getControl().getDisplay()
.getSystemColor(SWT.COLOR_RED));
}
AutAgentPreferencePage.this.setErrorMessage(
editor.getErrorMessage());
}
});
return editor;
}
/**
* {@inheritDoc}
*/
protected Object getValue(Object element) {
return String.valueOf(
((AutAgentManager.AutAgent)element).getPort());
}
/**
* {@inheritDoc}
*/
protected void setValue(Object element, Object value) {
try {
((AutAgentManager.AutAgent)element).setPort(
getPortValue(value));
getViewer().update(element, null);
} catch (NumberFormatException nfe) {
// The value cannot be set to the model.
// Do nothing.
}
}
/**
*
* @param value The value to parse into an integer.
* @return the integer value of <code>value</code>.
* @throws NumberFormatException if the given value cannot be parsed
* to an integer.
*/
private int getPortValue(Object value) throws NumberFormatException {
return Integer.parseInt(String.valueOf(value));
}
}
/**
*
* @author BREDEX GmbH
* @created Jan 18, 2010
*/
private static class ServerHostNameEditingSupport extends EditingSupport {
/**
* Constructor
*
* @param viewer The viewer
*/
public ServerHostNameEditingSupport(ColumnViewer viewer) {
super(viewer);
}
/**
* {@inheritDoc}
*/
protected boolean canEdit(Object element) {
return true;
}
/**
* {@inheritDoc}
*/
protected CellEditor getCellEditor(Object element) {
return new TextCellEditor((Composite)getViewer().getControl());
}
/**
* {@inheritDoc}
*/
protected Object getValue(Object element) {
return ((AutAgentManager.AutAgent)element).getName();
}
/**
* {@inheritDoc}
*/
protected void setValue(Object element, Object value) {
String hostNameValue = String.valueOf(value);
((AutAgentManager.AutAgent)element).setName(hostNameValue);
getViewer().update(element, null);
}
}
/**
* @author BREDEX GmbH
* @created Jan 15, 2010
*/
private static class AddressContentProvider
implements IStructuredContentProvider {
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public Object[] getElements(Object input) {
return ((List<AutAgentManager.AutAgent>)input).toArray();
}
/**
* {@inheritDoc}
*/
public void dispose() {
// Nothing to dispose
}
/**
* {@inheritDoc}
*/
public void inputChanged(
Viewer viewer, Object oldInput, Object newInput) {
// No listeners to deregister / register
}
}
/** viewer for AUT Agent addresses */
private TableViewer m_addressViewer;
/**
* Model for the information shown in the dialog. This model is persisted
* when the dialog's changes are applied.
*/
private List<AutAgentManager.AutAgent> m_viewModel;
/**
* {@inheritDoc}
*/
protected Control createContents(Composite parent) {
noDefaultAndApplyButton();
Plugin.getHelpSystem().setHelp(parent,
ContextHelpIds.PREFPAGE_SERVER);
/** Add layer to parent widget */
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(LAYOUT_NUM_COLUMNS, false);
composite.setLayout(layout);
m_addressViewer = createTableViewer(composite);
TableViewerFocusCellManager focusCellManager =
new TableViewerFocusCellManager(m_addressViewer,
new FocusCellOwnerDrawHighlighter(m_addressViewer));
ColumnViewerEditorActivationStrategy actSupport =
new ColumnViewerEditorActivationStrategy(m_addressViewer) {
protected boolean isEditorActivationEvent(
ColumnViewerEditorActivationEvent event) {
return event.eventType
== ColumnViewerEditorActivationEvent.TRAVERSAL
|| event.eventType
== ColumnViewerEditorActivationEvent.
MOUSE_DOUBLE_CLICK_SELECTION
|| (event.eventType
== ColumnViewerEditorActivationEvent.KEY_PRESSED
&& event.keyCode == SWT.CR)
|| event.eventType
== ColumnViewerEditorActivationEvent.PROGRAMMATIC;
}
};
TableViewerEditor.create(m_addressViewer, focusCellManager,
actSupport, ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
| ColumnViewerEditor.TABBING_VERTICAL
| ColumnViewerEditor.KEYBOARD_ACTIVATION);
m_viewModel = new LinkedList<AutAgentManager.AutAgent>();
if (AutAgentManager.getInstance().getAutAgents() != null) {
m_viewModel.addAll(AutAgentManager.getInstance().getAutAgents());
}
m_addressViewer.setInput(m_viewModel);
createButtons(composite);
return composite;
}
/**
* Adds buttons for managing server addresses to the given composite.
*
* @param parent The parent composite. The parent must have a GridLayout.
*/
private void createButtons(Composite parent) {
Button addButton = new Button(parent, SWT.NONE);
addButton.setText(Messages.AutAgentPreferencePageButtonAdd);
addButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
@SuppressWarnings("synthetic-access")
public void widgetSelected(SelectionEvent event) {
AutAgentManager.AutAgent newAUTAgent =
new AutAgentManager.AutAgent(
EnvConstants.LOCALHOST_ALIAS,
EnvConstants.AUT_AGENT_DEFAULT_PORT);
m_viewModel.add(newAUTAgent);
m_addressViewer.refresh();
m_addressViewer.editElement(newAUTAgent, 0);
}
});
final Button deleteButton = new Button(parent, SWT.NONE);
deleteButton.setText(Messages.AutAgentPreferencePageButtonDelete);
deleteButton.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {
widgetSelected(event);
}
@SuppressWarnings("synthetic-access")
public void widgetSelected(SelectionEvent event) {
IStructuredSelection sel =
(IStructuredSelection)m_addressViewer.getSelection();
m_viewModel.remove(sel.getFirstElement());
m_addressViewer.refresh();
}
});
}
/**
* {@inheritDoc}
*/
public boolean performOk() {
AutAgentManager.getInstance().setAutAgents(
new TreeSet<AutAgentManager.AutAgent>(m_viewModel));
AutAgentManager.getInstance().storeAutAgentList();
return super.performOk();
}
/**
* {@inheritDoc}
*/
public void init(IWorkbench workbench) {
setDescription(Messages.AutAgentPreferencePageDescription);
}
/**
* Creates and initializes a table viewer for managing server addresses.
*
* @param parent The parent composite. The parent must have a GridLayout.
* @return the initialized table viewer.
*/
@SuppressWarnings("synthetic-access")
private TableViewer createTableViewer(Composite parent) {
TableViewer viewer =
new TableViewer(parent, SWT.FULL_SELECTION | SWT.SINGLE);
Table addressTable = viewer.getTable();
addressTable.setLinesVisible(true);
addressTable.setHeaderVisible(true);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
layoutData.horizontalSpan = LAYOUT_NUM_COLUMNS;
addressTable.setLayoutData(layoutData);
viewer.setContentProvider(new AddressContentProvider());
TableLayout tableLayout = new TableLayout();
addressTable.setLayout(tableLayout);
tableLayout.addColumnData(new ColumnWeightData(15, 100));
TableViewerColumn column = new TableViewerColumn(viewer,
SWT.NONE);
column.getColumn().setText(Messages
.AutAgentPreferencePageColumnHeaderHostName);
column.setLabelProvider(new ColumnLabelProvider() {
public String getText(Object element) {
return ((AutAgentManager.AutAgent)element).getName();
}
});
column.setEditingSupport(
new ServerHostNameEditingSupport(viewer));
tableLayout.addColumnData(new ColumnWeightData(10, 100));
column = new TableViewerColumn(viewer,
SWT.NONE);
column.getColumn().setText(Messages
.AutAgentPreferencePageColumnHeaderPort);
column.setLabelProvider(new ColumnLabelProvider() {
public String getText(Object element) {
return String.valueOf(
((AutAgentManager.AutAgent)element).getPort());
}
});
column.setEditingSupport(new ServerPortEditingSupport(viewer));
// Prevents the "Return / Enter" key from closing the dialog when the
// table has focus. The event should be handled by the table itself
// (by activating a cell editor).
addressTable.addListener(SWT.Traverse, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.TRAVERSE_RETURN) {
// don't forward to the default button
event.doit = false;
}
}
});
return viewer;
}
}