/*
* (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.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionListener;
import org.openflexo.components.AskParametersPanel;
import org.openflexo.components.browser.BrowserElementType;
import org.openflexo.components.browser.BrowserFilter.BrowserFilterStatus;
import org.openflexo.components.browser.ProjectBrowser;
import org.openflexo.components.widget.AbstractSelectorPanel.AbstractSelectorPanelOwner;
import org.openflexo.fib.controller.FIBController;
import org.openflexo.fib.model.FIBCustom;
import org.openflexo.fib.model.FIBCustom.FIBCustomComponent;
import org.openflexo.foundation.FlexoEditor;
import org.openflexo.foundation.FlexoModelObject;
import org.openflexo.foundation.dkv.Domain;
import org.openflexo.foundation.dm.DMEntity;
import org.openflexo.foundation.dm.DMEntity.DMTypeVariable;
import org.openflexo.foundation.dm.DMModel;
import org.openflexo.foundation.dm.DMType;
import org.openflexo.foundation.dm.DMType.DMTypeStringConverter;
import org.openflexo.foundation.dm.DMType.WildcardBound;
import org.openflexo.foundation.dm.DMTypeOwner;
import org.openflexo.foundation.param.CheckboxParameter;
import org.openflexo.foundation.param.DMEntityParameter;
import org.openflexo.foundation.param.DomainParameter;
import org.openflexo.foundation.param.DynamicDropDownParameter;
import org.openflexo.foundation.param.EnumDropDownParameter;
import org.openflexo.foundation.param.IntegerParameter;
import org.openflexo.foundation.param.ParameterDefinition;
import org.openflexo.foundation.param.PropertyListParameter;
import org.openflexo.foundation.param.TextFieldParameter;
import org.openflexo.foundation.rm.FlexoProject;
import org.openflexo.icon.IconLibrary;
import org.openflexo.inspector.model.PropertyListColumn;
import org.openflexo.inspector.widget.DenaliWidget.WidgetLayout;
import org.openflexo.kvc.KVCObject;
import org.openflexo.localization.FlexoLocalization;
import org.openflexo.swing.MouseOverButton;
import org.openflexo.swing.TextFieldCustomPopup;
import com.ibm.icu.util.StringTokenizer;
/**
* Widget allowing to view and edit a DMType
*
* @author sguerin
*
*/
public class DMTypeSelector extends TextFieldCustomPopup<DMType> implements FIBCustomComponent<DMType, DMTypeSelector> {
@SuppressWarnings("hiding")
static final Logger logger = Logger.getLogger(DMTypeSelector.class.getPackage().getName());
protected static final String EMPTY_STRING = "";
protected String STRING_REPRESENTATION_WHEN_NULL = EMPTY_STRING;
protected FlexoProject _project;
protected DMTypeOwner _owner;
private DMType _revertValue;
protected AbstractDMTypeSelectorPanel _selectorPanel;
private FlexoEditor _editor;
private boolean _displayTypeAsSimplified;
private boolean _isReadOnly;
private KeyAdapter completionListKeyAdapter;
static enum EditionMode {
BASIC_TYPE, COMPLEX_TYPE;
}
EditionMode editionMode = EditionMode.BASIC_TYPE;
public DMTypeSelector(DMType editedObject) {
this(null, editedObject, true);
}
public DMTypeSelector(FlexoProject project, DMType editedObject, boolean displayTypeAsSimplified) {
super(editedObject, -1);
_project = project;
setRevertValue(editedObject != null ? editedObject.clone() : null);
_displayTypeAsSimplified = displayTypeAsSimplified;
setFocusable(true);
getTextField().setFocusable(true);
getTextField().setEditable(true);
if (editedObject != null && !editedObject.isBasicType()) {
editionMode = EditionMode.COMPLEX_TYPE;
}
completionListKeyAdapter = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (_selectorPanel != null && _selectorPanel.isUpdating()) {
return;
}
if (_selectorPanel != null) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
logger.info("Process enter");
_selectorPanel.processEnterPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_TAB) {
logger.info("Process tab");
_selectorPanel.processTabPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
logger.info("Process up");
_selectorPanel.processUpPressed();
e.consume();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
logger.info("Process down");
_selectorPanel.processDownPressed();
e.consume();
}
}
if (!e.isActionKey() && e.getKeyCode() != KeyEvent.VK_SHIFT && e.getKeyCode() != KeyEvent.VK_ENTER
&& e.getKeyCode() != KeyEvent.VK_TAB) {
getCustomPanel();
if (!popupIsShown()) {
openPopup();
}
if (editionMode == EditionMode.BASIC_TYPE) {
((BasicDMTypeSelectorPanel) _selectorPanel).textChanged();
}
/*SwingUtilities.invokeLater(new Runnable() {
public void run() {
DMEntitySelector baseEntitySelector = _selectorPanel.getBaseEntitySelector();
if (baseEntitySelector != null) {
String lookupString = getTextField().getText();
if (logger.isLoggable(Level.FINE)) logger.fine("lookup "+lookupString);
baseEntitySelector.setText(lookupString);
baseEntitySelector.addApplyCancelListener(new CustomPopup.ApplyCancelListener() {
public void fireApplyPerformed() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
apply();
}
});
}
public void fireCancelPerformed() {
}
});
}
}
});*/
}
}
};
getTextField().addKeyListener(completionListKeyAdapter);
}
@Override
public void delete() {
super.delete();
if (_selectorPanel != null) {
_selectorPanel.delete();
_selectorPanel = null;
}
if (unambigousEntities != null) {
unambigousEntities.clear();
unambigousEntities = null;
}
_owner = null;
_editor = null;
_project = null;
}
@Override
public void init(FIBCustom component, FIBController controller) {
}
@Override
public void setRevertValue(DMType oldValue) {
// WARNING: we need here to clone to keep track back of previous data !!!
if (oldValue != null) {
_revertValue = oldValue.clone();
} else {
_revertValue = null;
}
if (logger.isLoggable(Level.FINE)) {
logger.fine("Sets revert value to " + _revertValue);
}
}
@Override
public DMType getRevertValue() {
return _revertValue;
}
public FlexoProject getProject() {
return _project;
}
public void setProject(FlexoProject project) {
_project = project;
}
public DMTypeOwner getOwner() {
return _owner;
}
@CustomComponentParameter(name = "owner", type = CustomComponentParameter.Type.MANDATORY)
public void setOwner(DMTypeOwner owner) {
_owner = owner;
if (getOwner() != null && _selectorPanel != null) {
_selectorPanel.setOwner(owner);
}
}
@Override
protected AbstractDMTypeSelectorPanel createCustomPanel(DMType editedObject) {
_selectorPanel = makeCustomPanel(editedObject);
_selectorPanel.init();
return _selectorPanel;
}
public void setNullStringRepresentation(String aString) {
STRING_REPRESENTATION_WHEN_NULL = aString;
}
protected AbstractDMTypeSelectorPanel makeCustomPanel(DMType editedObject) {
// logger.info("editionMode="+editionMode);
if (editionMode == EditionMode.COMPLEX_TYPE) {
return new ComplexDMTypeSelectorPanel();
} else if (editionMode == EditionMode.BASIC_TYPE) {
return new BasicDMTypeSelectorPanel();
}
return null;
}
@Override
public void updateCustomPanel(DMType editedObject) {
if (_selectorPanel != null) {
/*if (editedObject == null) {
if (editionMode != EditionMode.BASIC_TYPE) activateBasicTypeMode();
}
else {
if (editionMode == EditionMode.BASIC_TYPE && !editedObject.isBasicType()) activateComplexTypeMode();
else if (editionMode == EditionMode.COMPLEX_TYPE && editedObject.isBasicType()) activateBasicTypeMode();
}*/
_selectorPanel.update();
}
}
@Override
public void setEditedObject(DMType editedObject) {
super.setEditedObject(editedObject);
if (editedObject == null) {
if (editionMode != EditionMode.BASIC_TYPE) {
activateBasicTypeMode();
}
} else {
if (editionMode == EditionMode.BASIC_TYPE && !editedObject.isBasicType()) {
activateComplexTypeMode();
} else if (editionMode == EditionMode.COMPLEX_TYPE && editedObject.isBasicType()) {
activateBasicTypeMode();
}
}
}
@Override
public String renderedString(DMType editedObject) {
if (editedObject != null) {
return _displayTypeAsSimplified ? editedObject.getSimplifiedStringRepresentation() : editedObject.getStringRepresentation();
} else {
return STRING_REPRESENTATION_WHEN_NULL;
}
}
public abstract class AbstractDMTypeSelectorPanel extends ResizablePanel {
abstract DMEntitySelector<DMEntity> getBaseEntitySelector();
abstract boolean isUpdating();
abstract void setOwner(DMTypeOwner owner);
abstract void init();
abstract void update();
abstract void delete();
abstract void processEnterPressed();
abstract void processTabPressed();
abstract void processUpPressed();
abstract void processDownPressed();
}
public class BasicDMTypeSelectorPanel extends AbstractDMTypeSelectorPanel implements AbstractSelectorPanelOwner<DMEntity> {
private JButton _applyButton;
private JButton _cancelButton;
private JButton _resetButton;
private JPanel _controlPanel;
private MouseOverButton complexTypeButton;
private DMEntitySelectorPanel _entitySelectorPanel;
private DMEntity editedEntity;
public BasicDMTypeSelectorPanel() {
_entitySelectorPanel = new DMEntitySelectorPanel();
_entitySelectorPanel.setRootObject(getDataModel());
_entitySelectorPanel.init();
}
@Override
void delete() {
}
@Override
DMEntitySelector<DMEntity> getBaseEntitySelector() {
return null;
}
@Override
void init() {
setLayout(new BorderLayout());
/*_controlPanel = new JPanel();
_controlPanel.setLayout(new FlowLayout());
_controlPanel.add(_applyButton = new JButton(FlexoLocalization.localizedForKey("ok")));
_controlPanel.add(_cancelButton = new JButton(FlexoLocalization.localizedForKey("cancel")));
_controlPanel.add(_resetButton = new JButton(FlexoLocalization.localizedForKey("reset")));
_applyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
apply();
}
});
_cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
cancel();
}
});
_resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
setEditedObject(null);
apply();
}
});*/
complexTypeButton = new MouseOverButton();
complexTypeButton.setBorder(BorderFactory.createEmptyBorder());
complexTypeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
activateComplexTypeMode();
}
});
JLabel complexTypeButtonLabel = new JLabel("", SwingConstants.RIGHT);
complexTypeButtonLabel.setFont(new Font("SansSerif", Font.PLAIN, 10));
complexTypeButton.setNormalIcon(IconLibrary.TOGGLE_ARROW_BOTTOM_ICON);
complexTypeButton.setMouseOverIcon(IconLibrary.TOGGLE_ARROW_BOTTOM_SELECTED_ICON);
complexTypeButton.setToolTipText(FlexoLocalization.localizedForKey("specify_complex_type"));
complexTypeButtonLabel.setText(FlexoLocalization.localizedForKey("specify_complex_type") + " ");
JPanel complexTypePanel = new JPanel();
complexTypePanel.setLayout(new BorderLayout());
complexTypePanel.add(complexTypeButtonLabel, BorderLayout.CENTER);
complexTypePanel.add(complexTypeButton, BorderLayout.EAST);
add(complexTypePanel, BorderLayout.NORTH);
// add(new JLabel("coucou"), BorderLayout.CENTER);
add(_entitySelectorPanel, BorderLayout.CENTER);
// add(_controlPanel, BorderLayout.SOUTH);
update();
}
@Override
boolean isUpdating() {
// TODO Auto-generated method stub
return false;
}
@Override
void setOwner(DMTypeOwner owner) {
// TODO Auto-generated method stub
}
@Override
void update() {
DMType currentEditedType = DMTypeSelector.this.getEditedObject();
if (currentEditedType != null && currentEditedType.isBasicType()) {
editedEntity = currentEditedType.getBaseEntity();
_entitySelectorPanel.update();
}
}
@Override
public Dimension getDefaultSize() {
return new Dimension(getDefaultWidth(), getDefaultHeight());
}
@Override
public Integer getDefaultWidth() {
return 300;
}
@Override
public Integer getDefaultHeight() {
return 300;
}
@Override
public void apply() {
DMTypeSelector.this.apply();
}
@Override
public void cancel() {
DMTypeSelector.this.cancel();
}
@Override
public KeyAdapter getCompletionListKeyAdapter() {
return completionListKeyAdapter;
}
@Override
public DMEntity getEditedObject() {
return editedEntity;
}
@Override
public void setEditedObject(DMEntity entity) {
editedEntity = entity;
if (entity == null) {
DMTypeSelector.this.setEditedObject(null);
} else {
DMTypeSelector.this.setEditedObject(DMType.makeResolvedDMType(entity));
}
}
@Override
public FlexoEditor getEditor() {
return DMTypeSelector.this.getEditor();
}
@Override
public FlexoProject getProject() {
return DMTypeSelector.this.getProject();
}
@Override
public FlexoModelObject getRootObject() {
return getDataModel();
}
@Override
public JTextField getTextField() {
return DMTypeSelector.this.getTextField();
}
@Override
public boolean isProgrammaticalySet() {
return DMTypeSelector.this.isProgrammaticalySet();
}
@Override
public boolean isSelectable(FlexoModelObject object) {
return object instanceof DMEntity;
}
@Override
public void openPopup() {
DMTypeSelector.this.openPopup();
}
@Override
public void closePopup() {
DMTypeSelector.this.closePopup();
}
@Override
public boolean popupIsShown() {
return DMTypeSelector.this.popupIsShown();
}
@Override
public String renderedString(DMEntity editedObject) {
if (editedObject != null) {
return editedObject.getLocalizedName();
}
return "";
}
@Override
public void setProgrammaticalySet(boolean aFlag) {
DMTypeSelector.this.setProgrammaticalySet(aFlag);
}
@Override
void processEnterPressed() {
if (!_entitySelectorPanel.processEnterPressed()) {
DMType newType = parseAndSelect(getTextField().getText());
if (newType.isResolved()) {
apply();
}
}
}
@Override
void processTabPressed() {
_entitySelectorPanel.processTabPressed();
}
@Override
void processUpPressed() {
_entitySelectorPanel.processUpPressed();
}
@Override
void processDownPressed() {
_entitySelectorPanel.processDownPressed();
}
protected class DMEntitySelectorPanel extends AbstractSelectorPanel<DMEntity> {
protected DMEntitySelectorPanel() {
super(BasicDMTypeSelectorPanel.this);
}
@Override
protected ProjectBrowser createBrowser(FlexoProject project) {
return new DataModelBrowser(/* project.getDataModel() */);
}
}
protected class DataModelBrowser extends ProjectBrowser {
// private DMModel _dmModel;
protected DataModelBrowser(/* DMModel dataModel */) {
super(getDataModel() != null ? getDataModel().getProject() : null, false);
init();
setDMViewMode(DMViewMode.Packages);
setRowHeight(16);
}
@Override
public void configure() {
setFilterStatus(BrowserElementType.DM_REPOSITORY_FOLDER, BrowserFilterStatus.OPTIONAL_INITIALLY_HIDDEN, true);
setFilterStatus(BrowserElementType.DM_REPOSITORY, BrowserFilterStatus.OPTIONAL_INITIALLY_HIDDEN, true);
setFilterStatus(BrowserElementType.DM_PROPERTY, BrowserFilterStatus.HIDE);
setFilterStatus(BrowserElementType.DM_EOATTRIBUTE, BrowserFilterStatus.HIDE);
setFilterStatus(BrowserElementType.DM_EORELATIONSHIP, BrowserFilterStatus.HIDE);
}
@Override
public FlexoModelObject getDefaultRootObject() {
return getDataModel();
}
}
public void textChanged() {
_entitySelectorPanel.textWasChanged();
}
}
public class ComplexDMTypeSelectorPanel extends AbstractDMTypeSelectorPanel {
private JButton _applyButton;
private JButton _cancelButton;
private JButton _resetButton;
private JPanel _controlPanel;
private MouseOverButton basicTypeButton;
AskParametersPanel _dataPanel;
EnumDropDownParameter<DMType.KindOfType> kindOfTypeParameter;
DMEntityParameter baseEntityParameter;
TextFieldParameter unresolvedTypeParameter;
IntegerParameter dimensionParameter;
CheckboxParameter hasParametersParameter;
PropertyListParameter<DMType.ParameterizedTypeVariable> parametersParam;
DomainParameter domainParam;
DynamicDropDownParameter<DMTypeVariable> typeVariableParam;
PropertyListParameter<DMType.WildcardBound> upperBoundsParam;
PropertyListParameter<DMType.WildcardBound> lowerBoundsParam;
protected ListSelectionListener listSelectionListener;
protected MouseAdapter listMouseListener;
protected WildcardActions wildcardActions;
protected ComplexDMTypeSelectorPanel() {
super();
wildcardActions = new WildcardActions();
}
@Override
public Dimension getDefaultSize() {
Dimension returned = new Dimension();
returned.width = 300;
returned.height = 300;
return returned;
}
<T> void dataChanged(ParameterDefinition<T> param, T oldValue, T newValue) {
// if (isUpdating) return;
if (oldValue == null && newValue == null) {
return;
}
if (oldValue == null && newValue != null || oldValue != null && !oldValue.equals(newValue)) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("dataChanged() for DMType old=" + oldValue + " new=" + newValue);
}
getTextField().setText(renderedString(getEditedObject()));
}
}
DMType getOrCreateEditedType() {
if (getEditedObject() != null) {
return getEditedObject();
} else {
DMType returned = DMType.makeUnresolvedDMType("");
returned.setOwner(getOwner());
setEditedObject(returned);
typeVariableParam
.setAvailableValues(getEditedObject() != null && getEditedObject().getTypeVariableContext() != null ? getEditedObject()
.getTypeVariableContext().getTypeVariables() : null);
return returned;
}
}
@Override
protected void init() {
setLayout(new BorderLayout());
kindOfTypeParameter = new EnumDropDownParameter<DMType.KindOfType>("KindOfType", "", null, DMType.KindOfType.values());
kindOfTypeParameter.setShowReset(false);
kindOfTypeParameter.setExpandHorizontally(false);
kindOfTypeParameter.setExpandVertically(false);
kindOfTypeParameter.setWidgetLayout(WidgetLayout.LABEL_ABOVE_WIDGET_LAYOUT);
kindOfTypeParameter.setDisplayLabel(false);
kindOfTypeParameter.addValueListener(new ParameterDefinition.ValueListener<DMType.KindOfType>() {
@Override
public void newValueWasSet(ParameterDefinition<DMType.KindOfType> param, DMType.KindOfType oldValue,
DMType.KindOfType newValue) {
if (isUpdating) {
return;
}
isUpdating = true;
if (newValue == DMType.KindOfType.RESOLVED) {
getOrCreateEditedType().setDimensions(0);
dimensionParameter.setValue(0);
dataChanged(param, oldValue, newValue);
} else if (newValue == DMType.KindOfType.RESOLVED_ARRAY) {
getOrCreateEditedType().setDimensions(1);
dimensionParameter.setValue(1);
dataChanged(param, oldValue, newValue);
} else if (newValue == DMType.KindOfType.DKV) {
getOrCreateEditedType().setBaseEntity(null);
getOrCreateEditedType().setTypeVariable(null);
getOrCreateEditedType().setDimensions(0);
dimensionParameter.setValue(0);
} else if (newValue == DMType.KindOfType.TYPE_VARIABLE) {
getOrCreateEditedType().setDomain(null);
getOrCreateEditedType().setBaseEntity(null);
getOrCreateEditedType().setDimensions(0);
// typeVariableParam.setAvailableValues(getEditedObject()!=null && getEditedObject().getTypeVariableContext() !=
// null?getEditedObject().getTypeVariableContext().getTypeVariables():null);
if (getOrCreateEditedType() != null && getOrCreateEditedType().getTypeVariableContext() != null) {
typeVariableParam.setAvailableValues(getOrCreateEditedType().getTypeVariableContext().getTypeVariables());
if (getOrCreateEditedType().getTypeVariableContext().getTypeVariables() != null
&& getOrCreateEditedType().getTypeVariableContext().getTypeVariables().size() > 0) {
getOrCreateEditedType().setTypeVariable(
getOrCreateEditedType().getTypeVariableContext().getTypeVariables().firstElement());
} else {
getOrCreateEditedType().setTypeVariable(null);
}
dimensionParameter.setValue(0);
typeVariableParam.setValue(getOrCreateEditedType().getTypeVariable());
} else {
typeVariableParam.setAvailableValues(null);
typeVariableParam.setValue(null);
}
dataChanged(param, oldValue, newValue);
} else if (newValue == DMType.KindOfType.WILDCARD) {
getOrCreateEditedType().setProject(getProject());
getOrCreateEditedType().setBaseEntity(null);
getOrCreateEditedType().setTypeVariable(null);
getOrCreateEditedType().setDomain(null);
dimensionParameter.setValue(0);
dataChanged(param, oldValue, newValue);
}
isUpdating = false;
}
});
unresolvedTypeParameter = new TextFieldParameter("type", "type", "");
unresolvedTypeParameter.setDepends("KindOfType");
unresolvedTypeParameter.setConditional("KindOfType=" + '"' + DMType.KindOfType.UNRESOLVED.getStringRepresentation() + '"');
unresolvedTypeParameter.addValueListener(new ParameterDefinition.ValueListener<String>() {
@Override
public void newValueWasSet(ParameterDefinition<String> param, String oldValue, String newValue) {
if (isUpdating) {
return;
}
if (newValue != null && !newValue.equals(oldValue)) {
setEditedObject(getProject().getDataModel().getDmTypeConverter()
.convertFromString(newValue, getOwner(), getProject()));
logger.info("Create type " + getEditedObject());
update();
}
dataChanged(param, oldValue, newValue);
}
});
unresolvedTypeParameter.setValidateOnReturn(true);
baseEntityParameter = new DMEntityParameter("baseType", "base_type", null);
baseEntityParameter.addValueListener(new ParameterDefinition.ValueListener<DMEntity>() {
@Override
public void newValueWasSet(ParameterDefinition<DMEntity> param, DMEntity oldValue, DMEntity newValue) {
if (isUpdating) {
return;
}
if (oldValue != newValue) {
getOrCreateEditedType().setBaseEntity(newValue);
hasParametersParameter
.setValue(getEditedObject() != null && getEditedObject().getBaseEntity() != null ? getEditedObject()
.getBaseEntity().getTypeVariables().size() > 0 : false);
parametersParam.setValue(getEditedObject() != null ? getEditedObject().getParameterizedTypeVariables() : null);
dataChanged(param, oldValue, newValue);
update();
}
}
});
baseEntityParameter.setDepends("KindOfType");
baseEntityParameter.setConditional("KindOfType=" + '"' + DMType.KindOfType.RESOLVED.getStringRepresentation() + '"' + " OR "
+ "KindOfType=" + '"' + DMType.KindOfType.RESOLVED_ARRAY.getStringRepresentation() + '"');
dimensionParameter = new IntegerParameter("dimensions", "dim", 1);
dimensionParameter.setDepends("KindOfType");
dimensionParameter.setConditional("KindOfType=" + '"' + DMType.KindOfType.RESOLVED_ARRAY.getStringRepresentation() + '"');
dimensionParameter.addValueListener(new ParameterDefinition.ValueListener<Integer>() {
@Override
public void newValueWasSet(ParameterDefinition<Integer> param, Integer oldValue, Integer newValue) {
if (isUpdating) {
return;
}
if (newValue != null && !newValue.equals(oldValue)) {
getOrCreateEditedType().setDimensions(newValue);
dataChanged(param, oldValue, newValue);
}
}
});
hasParametersParameter = new CheckboxParameter("hasParams", "", false);
hasParametersParameter.setDepends("KindOfType,baseType");
hasParametersParameter.setConditional("KindOfType=THIS_WIDGET_IS_NEVER_DISPLAYED");
parametersParam = new PropertyListParameter<DMType.ParameterizedTypeVariable>("parameters", "parameters", null, 20, 3);
parametersParam.setDisplayLabel(false);
parametersParam.setExpandVertically(true);
parametersParam.setDepends("KindOfType,baseType,hasParams");
parametersParam.setConditional("hasParams=true AND " + "(KindOfType=" + '"'
+ DMType.KindOfType.RESOLVED.getStringRepresentation() + '"' + " OR " + "KindOfType=" + '"'
+ DMType.KindOfType.RESOLVED_ARRAY.getStringRepresentation() + '"' + ")");
parametersParam.addReadOnlyTextFieldColumn("typeVariable.name", "variable", 50, true);
PropertyListColumn valueAttributeColumn = parametersParam.addCustomColumn("value", "value",
"org.openflexo.components.widget.DMTypeInspectorWidget", 200, true);
valueAttributeColumn.setValueForParameter("displayTypeAsSimplified", "false");
valueAttributeColumn.setValueForParameter("format", "simplifiedStringRepresentation");
valueAttributeColumn.setValueForParameter("project", "project");
valueAttributeColumn.setValueForParameter("owner", "owner");
domainParam = new DomainParameter("domain", "domain", null);
domainParam.addValueListener(new ParameterDefinition.ValueListener<Domain>() {
@Override
public void newValueWasSet(ParameterDefinition<Domain> param, Domain oldValue, Domain newValue) {
if (isUpdating) {
return;
}
if (oldValue != newValue) {
getOrCreateEditedType().setDomain(newValue);
dataChanged(param, oldValue, newValue);
update();
}
}
});
domainParam.setDepends("KindOfType");
domainParam.setConditional("KindOfType=" + '"' + DMType.KindOfType.DKV.getStringRepresentation() + '"');
typeVariableParam = new DynamicDropDownParameter<DMTypeVariable>("typeVariable", "variable", null, null);
typeVariableParam.setFormatter("name");
typeVariableParam.setShowReset(false);
typeVariableParam.setDepends("KindOfType");
typeVariableParam.setConditional("KindOfType=" + '"' + DMType.KindOfType.TYPE_VARIABLE.getStringRepresentation() + '"');
typeVariableParam.addValueListener(new ParameterDefinition.ValueListener<DMTypeVariable>() {
@Override
public void newValueWasSet(ParameterDefinition<DMTypeVariable> param, DMTypeVariable oldValue, DMTypeVariable newValue) {
if (isUpdating) {
return;
}
getOrCreateEditedType().setTypeVariable(newValue);
dataChanged(param, oldValue, newValue);
}
});
upperBoundsParam = new PropertyListParameter<DMType.WildcardBound>("upperBounds", "upper_bounds", null, 20, 2);
upperBoundsParam.setDisplayLabel(false);
upperBoundsParam.setExpandVertically(true);
upperBoundsParam.setDepends("KindOfType");
upperBoundsParam.setConditional("KindOfType=" + '"' + DMType.KindOfType.WILDCARD.getStringRepresentation() + '"');
upperBoundsParam.addReadOnlyTextFieldColumn("extendsLabel", "", 60, true);
PropertyListColumn upperBoundsValueAttributeColumn = upperBoundsParam.addCustomColumn("bound", "upper_bounds",
"org.openflexo.components.widget.DMTypeInspectorWidget", 200, true);
upperBoundsValueAttributeColumn.setValueForParameter("displayTypeAsSimplified", "false");
upperBoundsValueAttributeColumn.setValueForParameter("format", "simplifiedStringRepresentation");
upperBoundsValueAttributeColumn.setValueForParameter("project", "project");
upperBoundsValueAttributeColumn.setValueForParameter("owner", "owner");
upperBoundsParam.addAddAction("add", "wildcardActions.addUpperBound", "wildcardActions.addUpperBoundEnabled", null);
upperBoundsParam.addDeleteAction("remove", "wildcardActions.removeUpperBound", "wildcardActions.removeUpperBoundEnabled", null);
lowerBoundsParam = new PropertyListParameter<DMType.WildcardBound>("lowerBounds", "lower_bounds", null, 20, 2);
lowerBoundsParam.setDisplayLabel(false);
lowerBoundsParam.setExpandVertically(true);
lowerBoundsParam.setDepends("KindOfType");
lowerBoundsParam.setConditional("KindOfType=" + '"' + DMType.KindOfType.WILDCARD.getStringRepresentation() + '"');
lowerBoundsParam.addReadOnlyTextFieldColumn("superLabel", "", 60, true);
PropertyListColumn lowerBoundsValueAttributeColumn = lowerBoundsParam.addCustomColumn("bound", "lower_bounds",
"org.openflexo.components.widget.DMTypeInspectorWidget", 200, true);
lowerBoundsValueAttributeColumn.setValueForParameter("displayTypeAsSimplified", "false");
lowerBoundsValueAttributeColumn.setValueForParameter("format", "simplifiedStringRepresentation");
lowerBoundsValueAttributeColumn.setValueForParameter("project", "project");
lowerBoundsValueAttributeColumn.setValueForParameter("owner", "owner");
lowerBoundsParam.addAddAction("add", "wildcardActions.addLowerBound", "wildcardActions.addLowerBoundEnabled", null);
lowerBoundsParam.addDeleteAction("remove", "wildcardActions.removeLowerBound", "wildcardActions.removeLowerBoundEnabled", null);
_dataPanel = new AskParametersPanel(getProject(), kindOfTypeParameter, unresolvedTypeParameter, baseEntityParameter,
dimensionParameter, hasParametersParameter, parametersParam, domainParam, typeVariableParam, upperBoundsParam,
lowerBoundsParam);
_dataPanel.getParametersModel().addObjectForKey(wildcardActions, "wildcardActions");
if (getOwner() != null) {
_dataPanel.getParametersModel().addObjectForKey(getOwner(), "owner");
}
// _dataPanel.setBackground(Color.RED);
// _dataPanel.validate();
_controlPanel = new JPanel();
_controlPanel.setLayout(new FlowLayout());
_controlPanel.add(_applyButton = new JButton(FlexoLocalization.localizedForKey("ok")));
_controlPanel.add(_cancelButton = new JButton(FlexoLocalization.localizedForKey("cancel")));
_controlPanel.add(_resetButton = new JButton(FlexoLocalization.localizedForKey("reset")));
_applyButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
apply();
}
});
_cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancel();
}
});
_resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setEditedObject(null);
apply();
}
});
basicTypeButton = new MouseOverButton();
basicTypeButton.setBorder(BorderFactory.createEmptyBorder());
basicTypeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
activateBasicTypeMode();
}
});
JLabel basicTypeButtonLabel = new JLabel("", SwingConstants.RIGHT);
basicTypeButtonLabel.setFont(new Font("SansSerif", Font.PLAIN, 10));
basicTypeButton.setNormalIcon(IconLibrary.TOGGLE_ARROW_TOP_ICON);
basicTypeButton.setMouseOverIcon(IconLibrary.TOGGLE_ARROW_TOP_SELECTED_ICON);
basicTypeButton.setToolTipText(FlexoLocalization.localizedForKey("specify_basic_type"));
basicTypeButtonLabel.setText(FlexoLocalization.localizedForKey("specify_basic_type") + " ");
JPanel basicTypePanel = new JPanel();
basicTypePanel.setLayout(new BorderLayout());
basicTypePanel.add(basicTypeButtonLabel, BorderLayout.CENTER);
basicTypePanel.add(basicTypeButton, BorderLayout.EAST);
add(basicTypePanel, BorderLayout.NORTH);
// add(new JLabel("coucou"), BorderLayout.NORTH);
add(_dataPanel, BorderLayout.CENTER);
add(_controlPanel, BorderLayout.SOUTH);
update();
}
@Override
DMEntitySelector<DMEntity> getBaseEntitySelector() {
DMEntityInspectorWidget widget = (DMEntityInspectorWidget) _dataPanel.getInspectorWidgetForParameter(baseEntityParameter);
if (widget != null) {
return widget.getSelector();
}
return null;
}
public class WildcardActions extends KVCObject {
protected WildcardActions() {
super();
}
public void addUpperBound() {
DMType type = getOrCreateEditedType();
if (type.getUpperBounds() == null) {
type.setUpperBounds(new Vector<WildcardBound>());
}
DMType newObjectType = DMType.makeResolvedDMType(getProject().getDataModel().getDMEntity(Object.class));
newObjectType.setOwner(type);
newObjectType.setProject(getProject());
type.addToUpperBounds(newObjectType);
update();
}
public boolean addUpperBoundEnabled() {
return true;
}
public boolean addUpperBoundEnabled(WildcardBound type) {
return true;
}
public void addLowerBound() {
DMType type = getOrCreateEditedType();
if (type.getLowerBounds() == null) {
type.setLowerBounds(new Vector<WildcardBound>());
}
DMType newObjectType = DMType.makeResolvedDMType(getProject().getDataModel().getDMEntity(Object.class));
newObjectType.setOwner(type);
newObjectType.setProject(getProject());
type.addToLowerBounds(newObjectType);
update();
}
public boolean addLowerBoundEnabled() {
return true;
}
public boolean addLowerBoundEnabled(WildcardBound type) {
return true;
}
public void removeUpperBound(WildcardBound type) {
getEditedObject().getUpperBounds().remove(type);
update();
}
public boolean removeUpperBoundEnabled(WildcardBound type) {
return true;
}
public void removeLowerBound(WildcardBound type) {
getEditedObject().getLowerBounds().remove(type);
update();
}
public boolean removeLowerBoundEnabled(WildcardBound type) {
return true;
}
}
boolean isUpdating = false;
@Override
public boolean isUpdating() {
return isUpdating;
}
@Override
public void update() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Update with " + getEditedObject());
}
if (isUpdating) {
return;
}
isUpdating = true;
if (getEditedObject() == null || getEditedObject().getStringRepresentation() == null
|| getEditedObject().getStringRepresentation().equals("")) {
kindOfTypeParameter.setValue(DMType.KindOfType.RESOLVED);
} else {
kindOfTypeParameter.setValue(getEditedObject() != null ? getEditedObject().getKindOfType() : null);
}
unresolvedTypeParameter.setValue(getEditedObject() != null ? getEditedObject().getStringRepresentation() : null);
baseEntityParameter.setValue(getEditedObject() != null ? getEditedObject().getBaseEntity() : null);
dimensionParameter.setValue(getEditedObject() != null ? getEditedObject().getDimensions() : null);
hasParametersParameter.setValue(getEditedObject() != null && getEditedObject().getBaseEntity() != null ? getEditedObject()
.getBaseEntity().getTypeVariables().size() > 0 : false);
parametersParam.setValue(getEditedObject() != null ? getEditedObject().getParameterizedTypeVariables() : null);
domainParam.setValue(getEditedObject() != null ? getEditedObject().getDomain() : null);
typeVariableParam
.setAvailableValues(getEditedObject() != null && getEditedObject().getTypeVariableContext() != null ? getEditedObject()
.getTypeVariableContext().getTypeVariables() : null);
typeVariableParam.setValue(getEditedObject() != null ? getEditedObject().getTypeVariable() : null);
upperBoundsParam.setValue(getEditedObject() != null ? getEditedObject().getUpperBounds() : null);
lowerBoundsParam.setValue(getEditedObject() != null ? getEditedObject().getLowerBounds() : null);
_dataPanel.update();
isUpdating = false;
}
protected JPanel getControlPanel() {
return _controlPanel;
}
@Override
public void delete() {
}
@Override
public void setOwner(DMTypeOwner owner) {
_owner = owner;
if (_dataPanel != null) {
_dataPanel.getParametersModel().addObjectForKey(getOwner(), "owner");
update();
}
}
@Override
void processEnterPressed() {
DMType newType = parseAndSelect(getTextField().getText());
if (newType.isResolved()) {
apply();
}
}
@Override
void processTabPressed() {
}
@Override
void processUpPressed() {
}
@Override
void processDownPressed() {
}
}
public DMType parseAndSelect(String aTypeAsString) {
String typeToParse = "";
StringTokenizer st = new StringTokenizer(aTypeAsString, " <>,?", true);
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (" <>,?".indexOf(token) > -1) {
typeToParse += token; // this is a delimiter
} else {
DMEntity e = getAllUnambigousEntities().get(token);
if (e == null) {
e = getAllUnambigousEntities().get(token.toUpperCase());
}
if (e != null) {
typeToParse += e.getFullQualifiedName();
} else {
typeToParse += token;
}
}
}
DMTypeStringConverter converter = getDataModel().getDmTypeConverter();
DMType type = converter.convertFromString(typeToParse);
setEditedObject(type);
return type;
}
@Override
public void apply() {
setRevertValue(getEditedObject() != null ? getEditedObject().clone() : null);
closePopup();
super.apply();
}
@Override
public void cancel() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("CANCEL: revert to " + getRevertValue());
}
setEditedObject(getRevertValue());
closePopup();
super.cancel();
}
@Override
protected void openPopup() {
super.openPopup();
getTextField().requestFocusInWindow();
// This little piece of code is intented to avoid
// textfield beeing whole selected after first typing
// (at this point, popup open, text field gets focus back, select all
// and the second push on a key erase the first char)
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getTextField().select(0, 0);
getTextField().setCaretPosition(getTextField().getText().length());
}
});
}
@Override
public void closePopup() {
super.closePopup();
deletePopup();
}
@Override
protected void deletePopup() {
if (_selectorPanel != null) {
_selectorPanel.delete();
}
_selectorPanel = null;
super.deletePopup();
}
@Override
protected void pointerLeavesPopup() {
cancel();
}
public AbstractDMTypeSelectorPanel getSelectorPanel() {
return _selectorPanel;
}
public FlexoEditor getEditor() {
return _editor;
}
/**
* Sets an editor if you want FlexoAction available on browser
*
* @param editor
*/
public void setEditor(FlexoEditor editor) {
_editor = editor;
}
public boolean getDisplayTypeAsSimplified() {
return _displayTypeAsSimplified;
}
@CustomComponentParameter(name = "displayTypeAsSimplified", type = CustomComponentParameter.Type.OPTIONAL)
public void setDisplayTypeAsSimplified(boolean displayTypeAsSimplified) {
_displayTypeAsSimplified = displayTypeAsSimplified;
}
public boolean getReadOnly() {
return _isReadOnly;
}
// TODO: not implemented yet
@CustomComponentParameter(name = "readOnly", type = CustomComponentParameter.Type.OPTIONAL)
public void setReadOnly(boolean isReadOnly) {
_isReadOnly = isReadOnly;
}
public void activateBasicTypeMode() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("activateBasicTypeMode() getEditedObject()=" + getEditedObject() + " editionMode=" + editionMode
+ " popupIsShown()=" + popupIsShown() + " _selectorPanel=" + _selectorPanel);
}
if (_selectorPanel != null && editionMode != EditionMode.BASIC_TYPE) {
editionMode = EditionMode.BASIC_TYPE;
boolean showAgain = false;
if (popupIsShown()) {
showAgain = true;
closePopup(false);
}
if (getEditedObject() != null) {
if (getEditedObject().getBaseEntity() != null) {
_editedObject = DMType.makeResolvedDMType(getEditedObject().getBaseEntity());
} else {
_editedObject = null;
}
}
deleteCustomPanel();
if (showAgain) {
openPopup();
updateCustomPanel(getEditedObject());
}
}
editionMode = EditionMode.BASIC_TYPE;
}
public void activateComplexTypeMode() {
if (logger.isLoggable(Level.FINE)) {
logger.fine("activateComplexTypeMode() getEditedObject()=" + getEditedObject() + " editionMode=" + editionMode
+ " popupIsShown()=" + popupIsShown() + " _selectorPanel=" + _selectorPanel);
}
if (_selectorPanel != null && editionMode != EditionMode.COMPLEX_TYPE) {
editionMode = EditionMode.COMPLEX_TYPE;
boolean showAgain = false;
if (_editedObject == null && _selectorPanel instanceof BasicDMTypeSelectorPanel) {
FlexoModelObject currentSelectedObject = ((BasicDMTypeSelectorPanel) _selectorPanel)._entitySelectorPanel
.getSelectedObject();
// System.out.println("selected: "+currentSelectedObject);
if (currentSelectedObject instanceof DMEntity) {
_editedObject = DMType.makeResolvedDMType((DMEntity) currentSelectedObject);
}
}
if (popupIsShown()) {
showAgain = true;
closePopup(false);
}
deleteCustomPanel();
if (showAgain) {
openPopup();
updateCustomPanel(getEditedObject());
}
}
editionMode = EditionMode.COMPLEX_TYPE;
}
DMModel getDataModel() {
if (getProject() != null) {
return getProject().getDataModel();
}
return null;
}
private Hashtable<String, DMEntity> unambigousEntities = null;
private Hashtable<String, DMEntity> getAllUnambigousEntities() {
if (unambigousEntities == null) {
unambigousEntities = new Hashtable<String, DMEntity>();
Enumeration<DMEntity> en = getDataModel().getEntities().elements();
while (en.hasMoreElements()) {
DMEntity e = en.nextElement();
String fullQualifiedName = e.getFullQualifiedName();
if (unambigousEntities.get(fullQualifiedName) == null) {
unambigousEntities.put(fullQualifiedName, e);
}
String fullQualifiedNameUC = e.getFullQualifiedName().toUpperCase();
if (unambigousEntities.get(fullQualifiedNameUC) == null) {
unambigousEntities.put(fullQualifiedNameUC, e);
}
String name = e.getClassName();
if (unambigousEntities.get(name) == null) {
unambigousEntities.put(name, e);
}
String nameUC = e.getClassName().toUpperCase();
if (unambigousEntities.get(nameUC) == null) {
unambigousEntities.put(nameUC, e);
}
}
}
return unambigousEntities;
}
@Override
public DMTypeSelector getJComponent() {
return this;
}
@Override
public Class<DMType> getRepresentedType() {
return DMType.class;
}
}