/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.runtime.ui.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;
import org.teiid.core.designer.event.IChangeListener;
import org.teiid.core.designer.event.IChangeNotifier;
import org.teiid.core.designer.util.CoreStringUtil;
import org.teiid.core.designer.util.I18nUtil;
import org.teiid.designer.core.metamodel.aspect.sql.SqlAspectHelper;
import org.teiid.designer.core.metamodel.aspect.sql.SqlColumnSetAspect;
import org.teiid.designer.runtime.ui.DqpUiConstants;
import org.teiid.designer.ui.PluginConstants;
import org.teiid.designer.ui.UiPlugin;
import org.teiid.designer.ui.common.util.WidgetFactory;
import org.teiid.designer.ui.viewsupport.ModelUtilities;
/**
* @since 8.0
*/
public class PreviewParameterPanel extends ScrolledComposite implements DqpUiConstants, IChangeNotifier {
private static final String PREFIX = I18nUtil.getPropertyPrefix(PreviewParameterPanel.class);
private static final IStatus ERROR_STATUS;
private static final IStatus GOOD_STATUS;
static {
ERROR_STATUS = new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, UTIL.getString(PREFIX + "errorStatus"), null); //$NON-NLS-1$
GOOD_STATUS = new Status(IStatus.OK, PLUGIN_ID, IStatus.OK, UTIL.getString(PREFIX + "goodStatus"), null); //$NON-NLS-1$
}
private List<Label> images;
private List<Label> names;
private List<IChangeListener> listeners;
private IStatus overallStatus = ERROR_STATUS;
private Composite pnlMain;
private IStatus[] statuses;
private List<Text> textFields;
private PreviewParameterPanel( Composite parent ) {
super(parent, SWT.H_SCROLL | SWT.V_SCROLL);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
setLayout(gridLayout);
setLayoutData(new GridData(GridData.FILL_BOTH));
// customize scroll bars to give better scrolling behavior
ScrollBar bar = getHorizontalBar();
if (bar != null) {
bar.setIncrement(12);
bar.setPageIncrement(60);
}
bar = getVerticalBar();
if (bar != null) {
bar.setIncrement(12);
bar.setPageIncrement(60);
}
this.pnlMain = WidgetFactory.createPanel(this, SWT.NONE, GridData.FILL_BOTH);
((GridLayout)this.pnlMain.getLayout()).numColumns = 4;
setContent(this.pnlMain);
}
public PreviewParameterPanel( Composite parent,
List<EObject> parameters ) {
this(parent);
createParameterControls(this.pnlMain, parameters);
postInit();
}
public PreviewParameterPanel( Composite parent,
EObject accessPattern ) {
this(parent);
SqlColumnSetAspect aspect = (SqlColumnSetAspect)SqlAspectHelper.getSqlAspect(accessPattern);
createParameterControls(this.pnlMain, aspect.getColumns(accessPattern));
postInit();
}
/**
* @see org.teiid.core.designer.event.IChangeNotifier#addChangeListener(org.teiid.core.designer.event.IChangeListener)
* @since 5.5.3
*/
@Override
public void addChangeListener( IChangeListener listener ) {
if (this.listeners == null) {
this.listeners = new ArrayList<IChangeListener>(1);
}
this.listeners.add(listener);
}
private void createParameterControls( Composite parent,
List<EObject> parameters ) {
ILabelProvider labelProvider = ModelUtilities.getAdapterFactoryLabelProvider();
int numCols = parameters.size();
this.names = new ArrayList<Label>(numCols);
this.images = new ArrayList<Label>(numCols);
this.textFields = new ArrayList<Text>(numCols);
this.statuses = new IStatus[numCols];
for (EObject param : parameters) {
Label name = new Label(parent, SWT.NONE);
name.setText(labelProvider.getText(param));
this.names.add(name);
Label image = new Label(parent, SWT.NONE);
image.setImage(UiPlugin.getDefault().getImage(PluginConstants.Images.BLANK_ICON));
this.images.add(image);
final Text textField = WidgetFactory.createTextField(parent);
final ModifyListener modifyListener = createModifyListener(param);
textField.addModifyListener(modifyListener);
textField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
// set focus to the first textfield
if (this.textFields.isEmpty()) {
textField.setFocus();
}
this.textFields.add(textField);
// set initial validation state
Event e = new Event();
e.widget = textField;
modifyListener.modifyText(new ModifyEvent(e));
// add "make null" checkbox if value can be null
if (ParameterValueValidator.canBeNull(param)) {
final Button btn = WidgetFactory.createCheckBox(parent, UTIL.getString(PREFIX + "chkNullValue")); //$NON-NLS-1$
btn.setToolTipText(UTIL.getString(PREFIX + "chkNullValue.tip")); //$NON-NLS-1$
btn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
// enable textfield only when checkbox is not checked
textField.setEnabled(!btn.getSelection());
// put focus back in textfield when the checkbox was unselected
if (textField.isEnabled()) {
textField.setFocus();
}
// send event to update status
Event event = new Event();
event.widget = textField;
modifyListener.modifyText(new ModifyEvent(event));
}
});
} else {
// add empty panel to fill area where the checkbox would've been
WidgetFactory.createPanel(parent);
}
}
}
private ModifyListener createModifyListener( final EObject column ) {
ModifyListener modifyListener = new ModifyListener() {
@Override
public void modifyText( ModifyEvent e ) {
Text textField = (Text)e.widget;
IStatus status = ParameterValueValidator.isValidValue(column, getValue(textField));
setStatus(status, textField);
}
};
return modifyListener;
}
/**
* @see org.eclipse.swt.widgets.Widget#dispose()
* @since 5.5.3
*/
@Override
public void dispose() {
for (IChangeListener listener : this.listeners) {
removeChangeListener(listener);
}
super.dispose();
}
private void fireStateChanged() {
if (this.listeners != null) {
for (IChangeListener listener : this.listeners) {
listener.stateChanged(this);
}
}
}
/**
* @return the ordered list of parameter values
* @since 5.5.3
*/
public List<String> getColumnValues() {
List<String> values = new ArrayList<String>(this.textFields.size());
for (Text textField : this.textFields) {
// if textfield is enabled use its value else user wants to use a null value
values.add(getValue(textField));
}
return values;
}
/**
* If the checkbox is selected indicating the value should be null then the textField will be disabled.
*
* @param textField the widget being checked
* @return the text or <code>null</code> if the checkbox is selected
* @since 6.0.0
*/
String getValue( Text textField ) {
return (textField.getEnabled() ? textField.getText() : null);
}
/**
* @return the panel's validation status (never <code>null</code>)
* @since 5.5.3
*/
public IStatus getStatus() {
return this.overallStatus;
}
private void postInit() {
// need to size scroll panel
Point pt = computeSize(SWT.DEFAULT, SWT.DEFAULT);
setMinWidth(pt.x);
setMinHeight(pt.y);
setExpandHorizontal(true);
setExpandVertical(true);
}
/**
* @see org.teiid.core.designer.event.IChangeNotifier#removeChangeListener(org.teiid.core.designer.event.IChangeListener)
* @since 5.5.3
*/
@Override
public void removeChangeListener( IChangeListener listener ) {
if (this.listeners != null) {
this.listeners.remove(listener);
}
}
void setStatus( IStatus fieldStatus,
Text textField ) {
int index = this.textFields.indexOf(textField);
this.statuses[index] = fieldStatus;
Label lblName = this.names.get(index);
Label lblIcon = this.images.get(index);
Image image = null;
String toolTip = null;
if ((fieldStatus == null) || (fieldStatus.getSeverity() != IStatus.ERROR)) {
image = UiPlugin.getDefault().getImage(PluginConstants.Images.BLANK_ICON);
toolTip = CoreStringUtil.Constants.EMPTY_STRING;
} else {
image = UiPlugin.getDefault().getImage(PluginConstants.Images.ERROR_ICON);
toolTip = fieldStatus.getMessage();
}
lblName.setToolTipText(toolTip);
lblIcon.setImage(image);
lblIcon.setToolTipText(toolTip);
textField.setToolTipText(toolTip);
// calculate overall status
this.overallStatus = GOOD_STATUS;
for (IStatus status : this.statuses) {
if ((status != null) && status.getSeverity() == IStatus.ERROR) {
this.overallStatus = ERROR_STATUS;
break;
}
}
fireStateChanged();
}
}