/******************************************************************************
* Product: Posterita Ajax UI *
* Copyright (C) 2007 Posterita Ltd. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* Posterita Ltd., 3, Draper Avenue, Quatre Bornes, Mauritius *
* or via info@posterita.org or http://www.posterita.org/ *
*****************************************************************************/
package org.adempiere.webui.editor;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import org.adempiere.webui.component.Bandbox;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Datebox;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.event.ValueChangeEvent;
import org.adempiere.webui.event.ValueChangeListener;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.util.DisplayType;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Image;
/**
*
* @author <a href="mailto:agramdass@gmail.com">Ashley G Ramdass</a>
* @date Mar 11, 2007
* @version $Revision: 0.10 $
*/
public abstract class WEditor implements EventListener, PropertyChangeListener
{
private static final String[] lISTENER_EVENTS = {};
public static final int MAX_DISPLAY_LENGTH = 35;
protected GridField gridField;
protected GridTab gridTab;
protected Label label;
protected Component component;
protected boolean mandatory;
protected ArrayList<ValueChangeListener> listeners = new ArrayList<ValueChangeListener>();
private String strLabel;
private String description;
private boolean readOnly;
private boolean updateable;
private String columnName;
protected boolean hasFocus;
/**
*
* @param comp
* @param gridField
*/
public WEditor(Component comp, GridField gridField)
{
if (comp == null)
{
throw new IllegalArgumentException("Component cannot be null");
}
if (gridField == null)
{
throw new IllegalArgumentException("Grid field cannot be null");
}
this.setComponent(comp);
comp.setAttribute("zk_component_prefix", "Field_" + gridField.getColumnName() + "_" + gridField.getAD_Tab_ID() + "_" + gridField.getWindowNo() + "_");
this.gridField = gridField;
this.setMandatory(gridField.isMandatory(false));
this.readOnly = gridField.isReadOnly();
this.description = gridField.getDescription();
this.updateable = gridField.isUpdateable();
this.columnName = gridField.getColumnName();
this.strLabel = gridField.getHeader();
init();
}
/**
* Method is used to distinguish between 2 similar WSearchEditors
*
*/
public String getDescription()
{
return description;
}
/**
* Constructor for use if a grid field is unavailable
*
* @param comp The editor's component
* @param label column name (not displayed)
* @param description description of component
* @param mandatory whether a selection must be made
* @param readonly whether or not the editor is read only
* @param updateable whether the editor contents can be changed
*/
public WEditor(Component comp, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
{
if (comp == null)
{
throw new IllegalArgumentException("Component cannot be null");
}
this.setComponent(comp);
this.setMandatory(mandatory);
this.readOnly = readonly;
this.description = description;
this.updateable = updateable;
this.strLabel = label;
init();
}
/**
* Constructor for use if a grid field is unavailable
*
* @param comp The editor's component
* @param label column name (not displayed)
* @param description description of component
* @param mandatory whether a selection must be made
* @param readonly whether or not the editor is read only
* @param updateable whether the editor contents can be changed
*/
public WEditor(Component comp, String columnName, String label, String description, boolean mandatory, boolean readonly, boolean updateable)
{
if (comp == null)
{
throw new IllegalArgumentException("Component cannot be null");
}
this.setComponent(comp);
this.setMandatory(mandatory);
this.readOnly = readonly;
this.description = description;
this.updateable = updateable;
this.strLabel = label;
this.columnName = columnName;
init();
}
/**
* Set the editor component.
* @param comp the editor component
*/
protected void setComponent(Component comp)
{
this.component = comp;
}
private void init()
{
label = new Label("");
label.setValue(strLabel);
label.setTooltiptext(description);
this.setMandatory (mandatory);
if (readOnly || !updateable)
{
this.setReadWrite(false);
}
else
{
this.setReadWrite(true);
}
((HtmlBasedComponent)component).setTooltiptext(description);
label.setTooltiptext(description);
//init listeners
for (String event : this.getEvents())
{
component.addEventListener(event, this);
}
component.addEventListener(Events.ON_FOCUS, new EventListener() {
public void onEvent(Event event) throws Exception {
hasFocus = true;
}
});
component.addEventListener(Events.ON_BLUR, new EventListener() {
public void onEvent(Event event) throws Exception {
hasFocus = false;
}
});
}
/**
*
* @return grid field for this editor ( can be null )
*/
public GridField getGridField()
{
return gridField;
}
/**
*
* @return columnNames
*/
public String getColumnName()
{
return columnName;
}
/**
* Remove the table qualifier from the supplied column name.
*
* The column name may be prefixed with the table name
* i.e. <code>[table name].[column name]</code>.
* The function returns
*
* @param originalColumnName The column name to clean
* @return the column name with any table qualifier removed
* i.e. <code>[column name]</code>
*/
protected String cleanColumnName(String originalColumnName)
{
String cleanColumnName;
/*
* The regular expression to use to find the table qualifier.
* Matches "<table name>."
*/
final String regexTablePrefix = ".*\\.";
cleanColumnName = originalColumnName.replaceAll(regexTablePrefix, "");
return cleanColumnName;
}
protected void setColumnName(String columnName)
{
String cleanColumnName = cleanColumnName(columnName);
this.columnName = cleanColumnName;
}
/**
*
* @return Component
*/
public Component getComponent()
{
return component;
}
/**
* @param gridTab
*/
public void setGridTab(GridTab gridTab)
{
this.gridTab = gridTab;
}
/**
*
* @return popup menu instance ( if available )
*/
public WEditorPopupMenu getPopupMenu()
{
return null;
}
/**
* @param evt
*/
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals(org.compiere.model.GridField.PROPERTY))
{
setValue((evt.getNewValue()));
}
}
/**
* @param listener
*/
public void addValueChangeListener(ValueChangeListener listener)
{
if (listener == null)
{
return;
}
if (!listeners.contains(listener))
listeners.add(listener);
}
public boolean removeValuechangeListener(ValueChangeListener listener)
{
return listeners.remove(listener);
}
protected void fireValueChange(ValueChangeEvent event)
{
//copy to array to avoid concurrent modification exception
ValueChangeListener[] vcl = new ValueChangeListener[listeners.size()];
listeners.toArray(vcl);
for (ValueChangeListener listener : vcl)
{
listener.valueChange(event);
}
}
/**
*
* @return Label
*/
public Label getLabel()
{
return label;
}
/**
*
* @param readWrite
*/
public abstract void setReadWrite(boolean readWrite);
/**
*
* @return editable
*/
public abstract boolean isReadWrite();
/**
*
* @param visible
*/
public void setVisible(boolean visible)
{
label.setVisible(visible);
component.setVisible(visible);
}
/**
*
* @return is visible
*/
public boolean isVisible()
{
return component.isVisible();
}
public void setBackground(boolean error)
{
}
public void setBackground(Color color)
{
}
public String toString()
{
StringBuffer sb = new StringBuffer(30);
sb.append(this.getClass().getName());
sb.append("[").append(this.getColumnName());
sb.append("=");
sb.append(this.getValue()).append("]");
return sb.toString();
}
/**
*
* @param value
*/
abstract public void setValue(Object value);
/**
*
* @return Object
*/
abstract public Object getValue();
/**
*
* @return display text
*/
abstract public String getDisplay();
/**
*
* @return list of events
*/
public String[] getEvents()
{
return WEditor.lISTENER_EVENTS;
}
/**
* Set whether the editor represents a mandatory field.
* @param mandatory whether the field is mandatory
*/
public void setMandatory (boolean mandatory)
{
this.mandatory = mandatory;
if (label != null)
label.setMandatory(mandatory);
}
/**
*
* @return boolean
*/
public boolean isMandatory()
{
return this.mandatory;
}
/**
* allow subclass to perform dynamic loading of data
*/
public void dynamicDisplay()
{
}
/**
* Stretch editor component to fill container
*/
public void fillHorizontal() {
//streach component to fill grid cell
if (getComponent() instanceof HtmlBasedComponent) {
//can't stretch bandbox & datebox
if (!(getComponent() instanceof Bandbox) &&
!(getComponent() instanceof Datebox)) {
String width = "100%";
if (getComponent() instanceof Button) {
Button btn = (Button) getComponent();
String zclass = btn.getZclass();
if (gridField.getDisplayType() == DisplayType.Image) {
if (!zclass.contains("image-button-field ")) {
btn.setZclass("image-button-field " + zclass);
}
} else if (!zclass.contains("form-button ")) {
btn.setZclass("form-button " + zclass);
}
} else if (getComponent() instanceof Image) {
Image image = (Image) getComponent();
image.setWidth("48px");
image.setHeight("48px");
} else {
((HtmlBasedComponent)getComponent()).setWidth(width);
}
}
}
}
public boolean isHasFocus() {
return hasFocus;
}
public void setHasFocus(boolean b) {
hasFocus = b;
}
}