/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo 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 OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.components.widget; import java.awt.Color; import java.awt.event.FocusEvent; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JComponent; import org.openflexo.components.widget.binding.BindingSelector; import org.openflexo.foundation.bindings.AbstractBinding; import org.openflexo.foundation.bindings.Bindable; import org.openflexo.foundation.bindings.BindingDefinition; import org.openflexo.foundation.bindings.BindingValue; import org.openflexo.foundation.bindings.BindingVariable; import org.openflexo.foundation.bindings.WidgetBindingDefinition; import org.openflexo.foundation.dm.ComponentDMEntity; import org.openflexo.foundation.dm.DMEntity; import org.openflexo.foundation.dm.DMProperty; import org.openflexo.foundation.dm.DMPropertyImplementationType; import org.openflexo.foundation.dm.DMType; import org.openflexo.inspector.AbstractController; import org.openflexo.inspector.InspectableModification; import org.openflexo.inspector.InspectableObject; import org.openflexo.inspector.model.PropertyModel; import org.openflexo.inspector.widget.WidgetFocusListener; /** * Please comment this class * * @author sguerin * */ public class BindingSelectorInspectorWidget extends CustomInspectorWidget<AbstractBinding> { static final Logger logger = Logger.getLogger(BindingSelectorInspectorWidget.class.getPackage().getName()); protected BindingSelector _selector; boolean isUpdatingEditedBinding = false; public BindingSelectorInspectorWidget(final PropertyModel model, AbstractController controller) { super(model, controller); _selector = new BindingSelector(null) { @Override public String toString() { return "BindingSelector[" + model.name + "]"; } @Override public void apply() { try { BindingSelectorInspectorWidget.this.isUpdatingEditedBinding = true; super.apply(); updateModelFromWidget(); } finally { BindingSelectorInspectorWidget.this.isUpdatingEditedBinding = false; } } @Override public void cancel() { super.cancel(); updateModelFromWidget(); } @Override public DMProperty createsNewEntry(String newPropertyName, DMType newPropertyType, DMPropertyImplementationType implementationType, DMEntity parentEntity) { return parentEntity.createDMProperty(newPropertyName, newPropertyType, implementationType); /*if(parentEntity==null)parentEntity = getComponentEntity(); if(getEditedObject()==null)setEditedObject(makeBindingValue()); getEditedObject().setBindingVariable(bv); DMProperty newProperty = parentEntity.createsBindingVariable(newPropertyName, newPropertyType, implementationType); if(getBindingDefinition() instanceof WidgetBindingDefinition && newProperty.getEntity() instanceof ComponentDMEntity){ ((ComponentDMEntity)newProperty.getEntity()).setBindable(newProperty, false); } if(newProperty!=null) getEditedObject().addBindingPathElement(newProperty); apply(); updateWidgetFromModel(); return newProperty; */ } }; getDynamicComponent().addFocusListener(new WidgetFocusListener(this) { @Override public void focusGained(FocusEvent arg0) { if (logger.isLoggable(Level.FINE)) { logger.fine("Focus gained in " + getClass().getName()); } super.focusGained(arg0); _selector.getTextField().requestFocusInWindow(); _selector.getTextField().selectAll(); } @Override public void focusLost(FocusEvent arg0) { if (logger.isLoggable(Level.FINE)) { logger.fine("Focus lost in " + getClass().getName()); } super.focusLost(arg0); } }); } @Override public Class getDefaultType() { return BindingValue.class; } @Override public synchronized void updateWidgetFromModel() { if (logger.isLoggable(Level.FINE)) { logger.fine("BindingSelectorInspectorWidget, updateWidgetFromModel() for " + getObjectValue() + " isUpdatingModel=" + isUpdatingEditedBinding + " _selector.getIsUpdatingModel()=" + _selector.getIsUpdatingModel()); } if (isUpdatingEditedBinding) { return; } if (!_selector.getIsUpdatingModel()) { _selector.setEditedObjectAndUpdateBDAndOwner(getObjectValue()); _selector.setRevertValue(getObjectValue()); } /*BindingValue currentValue = (BindingValue)getObjectValue(); if (currentValue != null) { currentValue.setBindingDefinition(_selector.getBindingDefinition()); }*/ } /** * Update the model given the actual state of the widget */ @Override public synchronized void updateModelFromWidget() { isUpdatingEditedBinding = true; try { setObjectValue(_selector.getEditedObject()); } finally { isUpdatingEditedBinding = false; } super.updateModelFromWidget(); } @Override public JComponent getDynamicComponent() { return _selector; } public static final String ALLOWS_COMPOUND_BINDINGS = "allows_compound_bindings"; public static final String ACTIVATE_COMPOUND_BINDINGS = "activate_compound_bindings"; public static final String ALLOWS_STATIC_VALUES = "allows_static_values"; public static final String ALLOWS_EXPRESSIONS = "allows_expressions"; public static final String ALLOWS_TRANSTYPERS = "allows_transtypers"; @Override protected void performModelUpdating(InspectableObject value) { super.performModelUpdating(value); _selector.setEditedObject(getObjectValue()); _selector.setRevertValue(getObjectValue()); if (logger.isLoggable(Level.FINE)) { logger.fine("BindingSelectorInspectorWidget, performModelUpdating for " + getObjectValue()); } if (hasValueForParameter(ACTIVATE_COMPOUND_BINDINGS)) { String boolValue = getValueForParameter(ACTIVATE_COMPOUND_BINDINGS); if (boolValue.equalsIgnoreCase("true") || boolValue.equalsIgnoreCase("yes")) { _selector.activateCompoundBindingMode(); } else { _selector.activateNormalBindingMode(); } } /*else { if (getObjectValue() == null || !(getObjectValue() instanceof BindingValue && ((BindingValue)getObjectValue()).isCompoundBinding())) _selector.activateNormalBindingMode(); }*/ if (value instanceof Bindable) { _selector.setBindable((Bindable) value); } else if (value != null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("BindingSelectorInspectorWidget declared for a non-bindable inspectable object"); } } if (hasValueForParameter("binding_definition")) { BindingDefinition newBindingDefinition = (BindingDefinition) getDynamicValueForParameter("binding_definition", value); _selector.setBindingDefinition(newBindingDefinition); } if (hasValueForParameter("creates_entry")) { _selector.setAllowsEntryCreation(true); } else { _selector.setAllowsEntryCreation(false); } if (hasValueForParameter(ALLOWS_COMPOUND_BINDINGS)) { String boolValue = getValueForParameter(ALLOWS_COMPOUND_BINDINGS); if (boolValue.equalsIgnoreCase("true") || boolValue.equalsIgnoreCase("yes")) { _selector.setAllowsCompoundBindings(true); } else { _selector.setAllowsCompoundBindings(false); } } if (hasValueForParameter(ALLOWS_STATIC_VALUES)) { String boolValue = getValueForParameter(ALLOWS_STATIC_VALUES); if (boolValue.equalsIgnoreCase("true") || boolValue.equalsIgnoreCase("yes")) { _selector.setAllowsStaticValues(true); } else { _selector.setAllowsStaticValues(false); } } if (hasValueForParameter(ALLOWS_EXPRESSIONS)) { String boolValue = getValueForParameter(ALLOWS_EXPRESSIONS); if (boolValue.equalsIgnoreCase("true") || boolValue.equalsIgnoreCase("yes")) { _selector.setAllowsBindingExpressions(true); } else { _selector.setAllowsBindingExpressions(false); } } if (hasValueForParameter(ALLOWS_TRANSTYPERS)) { String boolValue = getValueForParameter(ALLOWS_TRANSTYPERS); if (boolValue.equalsIgnoreCase("true") || boolValue.equalsIgnoreCase("yes")) { _selector.setAllowsTranstypers(true); } else { _selector.setAllowsTranstypers(false); } } } private Method _createsEntryMethod; private Method getCreatesEntryMethod() { if (_createsEntryMethod == null) { String methodName = PropertyModel.getLastAccessor(getValueForParameter("creates_entry")); if (getModel() != null) { Class targetClass = PropertyModel.getTargetObject(getModel(), getValueForParameter("creates_entry")).getClass(); Class[] methodClassParams = new Class[3]; methodClassParams[0] = String.class; methodClassParams[1] = DMType.class; methodClassParams[2] = DMPropertyImplementationType.class; try { _createsEntryMethod = targetClass.getMethod(methodName, methodClassParams); } catch (SecurityException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("SecurityException raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); } catch (NoSuchMethodException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("NoSuchMethodException raised: unable to find method " + methodName + " for class " + targetClass); } e.printStackTrace(); } } } return _createsEntryMethod; } BindingVariable performCreatesEntry(String name, DMType type, DMPropertyImplementationType implementationType, DMEntity newEntryEntity, BindingValue editedObject) { if (getCreatesEntryMethod() != null) { Object[] params = new Object[3]; params[0] = name; params[1] = type; params[2] = implementationType; // DMEntity whishedEntity = getEditedValue().getAccessedType(); // System.err.println("whishedEntity:"+whishedEntity.getName()); try { if (newEntryEntity == null) { Object targetObject = PropertyModel.getTargetObject(getModel(), getValueForParameter("creates_entry")); if (logger.isLoggable(Level.INFO)) { logger.info("invoking " + getCreatesEntryMethod() + " on object" + targetObject); } return (BindingVariable) getCreatesEntryMethod().invoke(targetObject, params); } else { DMProperty newProperty = newEntryEntity.createDMProperty(name, type, implementationType); if (editedObject.getBindingDefinition() instanceof WidgetBindingDefinition && newProperty.getEntity() instanceof ComponentDMEntity) { ((ComponentDMEntity) newProperty.getEntity()).setBindable(newProperty, false); } if (newProperty != null) { editedObject.addBindingPathElement(newProperty); } return editedObject.getBindingVariable(); } } catch (IllegalArgumentException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); } catch (IllegalAccessException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); } catch (InvocationTargetException e) { // Warns about the exception if (logger.isLoggable(Level.WARNING)) { logger.warning("Exception raised: " + e.getClass().getName() + ". See console for details."); } e.printStackTrace(); } } return null; } /*private String getLastAccessor(String listAccessor) { int lastDotPosition = listAccessor.lastIndexOf("."); if (lastDotPosition < 0) return listAccessor; return listAccessor.substring(lastDotPosition + 1, listAccessor.length()); } private KeyValueCoding getTargetObject(KeyValueCoding sourceObject, String listAccessor) { StringTokenizer strTok = new StringTokenizer(listAccessor, "."); String accessor; Object currentObject = sourceObject; while (strTok.hasMoreTokens() && (currentObject != null) && (currentObject instanceof KeyValueCoding)) { accessor = strTok.nextToken(); if (strTok.hasMoreTokens()) { if (currentObject != null) { currentObject = ((KeyValueCoding) currentObject).objectForKey(accessor); } } } if (currentObject instanceof KeyValueCoding) { return (KeyValueCoding) currentObject; } else { if (logger.isLoggable(Level.WARNING)) logger.warning("Could not find target object : must be a non null KeyValueCoding object !"); return null; } }*/ public Color getColorForObject(BindingValue value) { return value.isBindingValid() ? Color.BLACK : Color.RED; } @Override public void update(InspectableObject inspectable, InspectableModification modification) { if ("wOComponent".equals(modification.propertyName())) { _selector.refreshBindingModel(); } super.update(inspectable, modification); } @Override public void fireEditingCanceled() { if (_selector != null) { _selector.closePopup(); } } @Override public void fireEditingStopped() { if (_selector != null) { _selector.closePopup(); } } @Override public boolean disableTerminateEditOnFocusLost() { return true; } }