/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.server.headlessclient.dataui; import javax.swing.text.Document; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.Page; import org.apache.wicket.markup.MarkupStream; import org.apache.wicket.markup.html.form.CheckBox; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.model.IComponentInheritedModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.IWrapModel; import org.apache.wicket.model.Model; import com.servoy.base.util.ITagResolver; import com.servoy.j2db.IApplication; import com.servoy.j2db.IFormUIInternal; import com.servoy.j2db.dataprocessing.FindState; import com.servoy.j2db.dataprocessing.IDisplayData; import com.servoy.j2db.dataprocessing.IEditListener; import com.servoy.j2db.dataprocessing.IRecordInternal; import com.servoy.j2db.dataprocessing.IValueList; import com.servoy.j2db.persistence.IColumnTypes; import com.servoy.j2db.server.headlessclient.MainPage; import com.servoy.j2db.ui.scripting.RuntimeCheckbox; import com.servoy.j2db.util.Utils; /** * Represents a checkbox field in the webbrowser. * * @author jcompagner */ public class WebDataCheckBox extends WebBaseSelectBox implements IResolveObject { public WebDataCheckBox(IApplication application, RuntimeCheckbox scriptable, String id, String text, IValueList list) { this(application, scriptable, id, text); onValue = list; } public WebDataCheckBox(IApplication application, RuntimeCheckbox scriptable, String id, String text) { super(application, scriptable, id, text); } public final RuntimeCheckbox getScriptObject() { return (RuntimeCheckbox)scriptable; } /* * _____________________________________________________________ Methods for model object resolve */ public Object resolveDisplayValue(Object realVal) { if (onValue != null && onValue.getSize() >= 1) { Object real = onValue.getRealElementAt(0); if (real == null) { return Boolean.valueOf(realVal == null); } return Boolean.valueOf(Utils.equalObjects(real, realVal)); // not just direct equals cause for example it could happen that one is Long(1) and the other Integer(1) and it would be false } if (realVal instanceof Boolean) return realVal; if (realVal instanceof Number) { return Boolean.valueOf(((Number)realVal).intValue() >= 1); } return Boolean.valueOf(realVal != null && "1".equals(realVal.toString())); } public Object resolveRealValue(Object displayVal) { if (onValue != null && onValue.getSize() >= 1) { return (Utils.getAsBoolean(displayVal) ? onValue.getRealElementAt(0) : null); } else { // TODO this seems not possible in web and we don't have the previousRealValue // // if value == null and still nothing selected return null (no data change) // if (previousRealValue == null && !Utils.getAsBoolean(displayVal)) // { // return null; // } return Integer.valueOf((Utils.getAsBoolean(displayVal) ? 1 : 0)); } } @Override protected FormComponent getSelector(String id) { return new MyCheckBox(id, this); } // if this check box is linked to a integer non-null table column, // we must change null to "0" by default (as the user sees the check-box // unchecked - and when he tries to save he will not have null content problems) private void changeNullTo0IfNeeded() { IModel< ? > model = getInnermostModel(); if (model instanceof RecordItemModel) { IRecordInternal record = ((RecordItemModel)model).getRecord(); if (!allowNull && record != null && !(record instanceof FindState) && record.getValue(dataProviderID) == null && getScriptObject().getComponentFormat().dpType == IColumnTypes.INTEGER && record.startEditing()) { // NOTE: when a UI converter is defined, the converter should handle this if (getScriptObject().getComponentFormat().parsedFormat.getUIConverterName() == null) { record.setValue(dataProviderID, Integer.valueOf(0)); } } } } public void setValueObject(Object value) { ((ChangesRecorder)getStylePropertyChanges()).testChanged(this, value); changeNullTo0IfNeeded(); // for record view if (getStylePropertyChanges().isChanged()) { // this component is going to update it's contents, without the user changing the // components contents; so remove invalid state if necessary setValueValid(true, null); } } @Override public String toString() { return getScriptObject().toString("value:" + getDefaultModelObject()); //$NON-NLS-1$ } private final class MyCheckBox extends CheckBox implements IDisplayData, WebBaseSelectBox.ISelector { private static final long serialVersionUID = 1L; private WebBaseSelectBox selectBox; private MyCheckBox(String id, WebBaseSelectBox selectBox) { super(id); this.selectBox = selectBox; setOutputMarkupPlaceholderTag(true); add(new AttributeModifier("disabled", true, new Model<String>() //$NON-NLS-1$ { private static final long serialVersionUID = 1L; @Override public String getObject() { return ((WebDataCheckBox.this.isEnabled() && !WebDataCheckBox.this.isReadOnly()) ? AttributeModifier.VALUELESS_ATTRIBUTE_REMOVE : AttributeModifier.VALUELESS_ATTRIBUTE_ADD); } })); add(new StyleAppendingModifier(new Model<String>() { private static final long serialVersionUID = 1L; @Override public String getObject() { return "width:14px;height:14px;"; } })); } /* * (non-Javadoc) * * @see org.apache.wicket.Component#initModel() */ @Override protected IModel< ? > initModel() { // Search parents for CompoundPropertyModel for (Component current = getParent(); current != null; current = current.getParent()) { // Get model IModel< ? > model = current.getDefaultModel(); if (model instanceof IWrapModel< ? >) { model = ((IWrapModel< ? >)model).getWrappedModel(); } if (model instanceof IComponentInheritedModel< ? >) { // we turn off versioning as we share the model with another // component that is the owner of the model (that component // has to decide whether to version or not setVersioned(false); // return the shared inherited return ((IComponentInheritedModel< ? >)model).wrapOnInheritance(WebDataCheckBox.this); } } // No model for this component! return null; } /** * @see wicket.Component#isEnabled() */ @Override public boolean isEnabled() { IFormUIInternal< ? > formui = findParent(IFormUIInternal.class); if (formui != null && formui.isDesignMode()) { return false; } return WebDataCheckBox.this.isEnabled(); } /** * @see wicket.markup.html.form.FormComponent#getInputName() */ @Override public String getInputName() { if (inputId == null) { Page page = findPage(); if (page instanceof MainPage) { inputId = ((MainPage)page).nextInputNameId(); } else { return super.getInputName(); } } return inputId; } @Override protected void onBeforeRender() { super.onBeforeRender(); changeNullTo0IfNeeded(); // for table/list view } public void setTagResolver(ITagResolver resolver) { } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#getValueObject() */ public Object getValueObject() { return WebDataCheckBox.this.getValueObject(); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#setValueObject(java.lang.Object) */ public void setValueObject(Object data) { WebDataCheckBox.this.setValueObject(data); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#needEditListener() */ public boolean needEditListener() { return WebDataCheckBox.this.needEditListener(); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#needEntireState() */ public boolean needEntireState() { return WebDataCheckBox.this.needEntireState(); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#setNeedEntireState(boolean) */ public void setNeedEntireState(boolean needEntireState) { WebDataCheckBox.this.setNeedEntireState(needEntireState); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#addEditListener(com.servoy.j2db.dataprocessing.IEditListener) */ public void addEditListener(IEditListener editListener) { WebDataCheckBox.this.addEditListener(editListener); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#getDataProviderID() */ public String getDataProviderID() { return WebDataCheckBox.this.getDataProviderID(); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#setDataProviderID(java.lang.String) */ public void setDataProviderID(String dataProviderID) { WebDataCheckBox.this.setDataProviderID(dataProviderID); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#getDocument() */ public Document getDocument() { return WebDataCheckBox.this.getDocument(); } /** * @see com.servoy.j2db.dataprocessing.IDisplayData#notifyLastNewValueWasChange(java.lang.Object, java.lang.Object) */ public void notifyLastNewValueWasChange(Object oldVal, Object newVal) { WebDataCheckBox.this.notifyLastNewValueWasChange(oldVal, newVal); } public boolean isValueValid() { return WebDataCheckBox.this.isValueValid(); } public void setValueValid(boolean valid, Object oldVal) { WebDataCheckBox.this.setValueValid(valid, oldVal); } /** * @see com.servoy.j2db.dataprocessing.IDisplay#setValidationEnabled(boolean) */ public void setValidationEnabled(boolean b) { WebDataCheckBox.this.setValidationEnabled(b); } /** * @see com.servoy.j2db.dataprocessing.IDisplay#stopUIEditing(boolean) */ public boolean stopUIEditing(boolean looseFocus) { return WebDataCheckBox.this.stopUIEditing(looseFocus); } public boolean isReadOnly() { return WebDataCheckBox.this.isReadOnly(); } @Override protected void onRender(final MarkupStream markupStream) { super.onRender(markupStream); IModel model = WebDataCheckBox.this.getInnermostModel(); if (model instanceof RecordItemModel) { ((RecordItemModel)model).updateRenderedValue(WebDataCheckBox.this); } } public WebBaseSelectBox getSelectBox() { return selectBox; } } }