Package edu.stanford.bmir.protege.web.client.ui.portlet.propertyForm

Source Code of edu.stanford.bmir.protege.web.client.ui.portlet.propertyForm.AbstractFieldWidget$RemovePropertyValueHandler

package edu.stanford.bmir.protege.web.client.ui.portlet.propertyForm;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Widget;
import com.gwtext.client.widgets.Component;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.form.Field;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.form.event.TextFieldListenerAdapter;
import com.gwtext.client.widgets.layout.AnchorLayoutData;
import com.gwtext.client.widgets.layout.ColumnLayout;
import com.gwtext.client.widgets.layout.ColumnLayoutData;
import edu.stanford.bmir.protege.web.client.Application;
import edu.stanford.bmir.protege.web.client.model.PropertyValueUtil;
import edu.stanford.bmir.protege.web.client.project.Project;
import edu.stanford.bmir.protege.web.client.rpc.AbstractAsyncHandler;
import edu.stanford.bmir.protege.web.client.rpc.data.EntityData;
import edu.stanford.bmir.protege.web.client.rpc.data.PropertyEntityData;
import edu.stanford.bmir.protege.web.client.rpc.data.ValueType;
import edu.stanford.bmir.protege.web.client.ui.portlet.AbstractPropertyWidgetWithNotes;
import edu.stanford.bmir.protege.web.client.ui.util.UIUtil;

import java.util.*;

public abstract class AbstractFieldWidget extends AbstractPropertyWidgetWithNotes {

    protected static final String LABEL_SEPARATOR = "";
    protected static final String DELETE_ICON_STYLE_STRING = "style=\"position:relative; top:4px;\"";

    private Panel wrappingPanel;
    private Field field;

    private Anchor deleteLink;
    private Anchor commentLink;

    private Collection<EntityData> values;
    protected PropertyValueUtil propertyValueUtil;
    protected List<String> allowedValueNames;

    public AbstractFieldWidget(Project project) {
        super(project);
        propertyValueUtil = new PropertyValueUtil();
    }


    @Override
    public Component createComponent() {
        wrappingPanel = new Panel();
        wrappingPanel.setPaddings(5);
        wrappingPanel.setLayout(new ColumnLayout());

        field = createField();
        deleteLink = createDeleteHyperlink();
        commentLink = createCommentHyperLink();

        FormPanel formPanel = new FormPanel();
        formPanel.add(field, new AnchorLayoutData("100%"));

        wrappingPanel.add(formPanel, new ColumnLayoutData(1));

        Collection<Widget> suffixComponents = createSuffixComponents();
        for (Widget widget : suffixComponents) {
            wrappingPanel.add(widget);
        }

        wrappingPanel.add(deleteLink);
        wrappingPanel.add(commentLink);
        return wrappingPanel;
    }

    protected AbstractFieldWidget(Project project, List<String> allowedValueNames) {
        this(project);
        //FIXME This is a temporary hack. Get rid of the second argument and the field
        this.allowedValueNames = allowedValueNames;
    }

    protected Collection<Widget> createSuffixComponents() { //TODO: might need better name
        return new ArrayList<Widget>();
    }

    protected Anchor createDeleteHyperlink() {
        deleteLink = new Anchor("&nbsp<img src=\"images/delete.png\" " + AbstractFieldWidget.DELETE_ICON_STYLE_STRING + "></img>", true);
        deleteLink.setWidth("22px");
        deleteLink.setHeight("22px");
        deleteLink.setTitle("Delete this value");
        deleteLink.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
              //we have to check the read-only status at the time of the mouse click,
              //because at the time of the widget creation (and initialization) we don't
              //know the value of the read_only property (it will be set only later in the setup method)
              if (isReadOnly() || isDisabled()) {
                deleteLink.setTitle("Delete operation is not allowed!");
                return;
              }
                if (isWriteOperationAllowed()) {
                    MessageBox.confirm("Confirm", "Are you sure you want to delete this value?",
                        new MessageBox.ConfirmCallback() {
                            public void execute(String btnID) {
                                if (btnID.equals("yes")) {
                                    deletePropertyValue(getSubject(), getProperty().getName(),
                                            getProperty().getValueType(), UIUtil.getFirstItem(values),
                                            field.getRawValue(), getDeleteValueOperationDescription());
                                }
                            }
                        });
                }
            }
        });
        return deleteLink;
    }

  @Override
    public void refresh() {
      //TODO activate this and test it after the server side will provide the local annotation count for all instance values
      //commentLink = createCommentHyperLink();
    wrappingPanel.doLayout();
  }


    //TODO - check if this is ICD specific
    protected String getDeleteValueOperationDescription() {
        String deletedValueDesc = new String("(");
        for (EntityData value : values) {
            String valueStr = UIUtil.getDisplayText(value);
            deletedValueDesc = deletedValueDesc + (field == null ? "empty" : valueStr) + ", ";
        }
        deletedValueDesc = deletedValueDesc.substring(0, deletedValueDesc.length() - 2);
        deletedValueDesc = deletedValueDesc + ")";

        return UIUtil.getAppliedToTransactionString("Deleted " + UIUtil.getShortName(getProperty().getBrowserText())
                + " from " + getSubject().getBrowserText() + ". Deleted value: "
                + (values == null || values.toString().length() == 0 ? "(empty)" : deletedValueDesc), getSubject()
                .getName());
    }

    protected Field createField() {
        field = createFieldComponent();
        attachFieldChangeListener();
        return field;
    }

    protected void attachFieldChangeListener() {
        field.addListener(new TextFieldListenerAdapter() {
            @Override
            public void onChange(Field field, Object newVal, Object oldVal) {
                onChangeValue(getSubject(), oldVal, newVal);
            }
        });
    }

    protected void onChangeValue(EntityData subj, Object oldVal, Object newVal) {
        if (!isWriteOperationAllowed()) {
            displayValues();
            return;
        }
        GWT.log("on change before invoke " + field.getFieldLabel(), null);

        //fix oldVal if it was the display text of a collection of more than 1 values
        //      (i.e. if it contained '{' or other special characters)
        if (values != null && values.size() > 1 &&
                UIUtil.getDisplayText(values).equals(oldVal)) {
            oldVal = UIUtil.getFirstItem(values);
        }

        if (UIUtil.getDisplayText(oldVal).length() == 0) {
            if (UIUtil.getDisplayText(newVal).length() > 0) {
                EntityData newValEntityData = convertToEntityData(newVal);
                addPropertyValue(subj, getProperty().getName(), getProperty().getValueType(),
                        newValEntityData, oldVal, getAddValueOperationDescription(subj, newValEntityData));
            }
        }
        else if (UIUtil.getDisplayText(newVal).length() == 0) {
            EntityData oldValEntityData = convertToEntityData(oldVal);
            deletePropertyValue(subj, getProperty().getName(), getProperty().getValueType(),
                    oldValEntityData, oldVal, getDeleteValueOperationDescription());
        }
        else {
            EntityData oldValEntityData = convertToEntityData(oldVal);
            EntityData newValEntityData = convertToEntityData(newVal);

            replacePropertyValue(subj, getProperty().getName(), getProperty().getValueType(),
                    oldValEntityData, newValEntityData, oldVal,
                    getReplaceValueOperationDescription(subj,
                            oldValEntityData, newValEntityData));
        }
    }


    protected EntityData convertToEntityData(Object fieldValue) {
        if (fieldValue instanceof EntityData) {
            return (EntityData) fieldValue;
        }

        if (fieldValue instanceof Collection<?>) {
            Collection<?> collectionFieldValue = (Collection<?>)fieldValue;
            if (collectionFieldValue.isEmpty()) {
                return convertToEntityData(null);
            }
            else {
                return convertToEntityData(collectionFieldValue.iterator().next());
            }
        }

        return new EntityData(UIUtil.getDisplayText(fieldValue));
    }


    //TODO - check if this is ICD specific
    protected String getAddValueOperationDescription(EntityData subject, EntityData newVal) {
        return UIUtil.getAppliedToTransactionString("Added a new "
                + UIUtil.getDisplayText(getProperty()) + " to " + UIUtil.getDisplayText(subject+
                ". Added value: " + UIUtil.getDisplayText(newVal),
                subject.getName());
    }

    //TODO - check if this is ICD specific
    protected String getReplaceValueOperationDescription(EntityData subject, Object oldValue, Object newValue) {
        return UIUtil.getAppliedToTransactionString("Replaced " + UIUtil.getDisplayText(getProperty())
                + " of " + UIUtil.getDisplayText(subject) + ". Old value: "
                + (oldValue == null || oldValue.toString().length() == 0 ? "(empty)" : UIUtil.getDisplayText(oldValue)) + " "
                + ". New value: " + (newValue == null || newValue.toString().length() == 0 ? "(empty)" : UIUtil.getDisplayText(newValue)),
                subject.getName());
    }

    protected Anchor createCommentHyperLink() {
        String text = "<img src=\"images/comment.gif\" title=\""
                + "Add a comment on this value\" " + AbstractPropertyWidgetWithNotes.COMMENT_ICON_STYLE_STRING + "></img>";
        EntityData value = UIUtil.getFirstItem(values);
        int annotationsCount = (value == null ? 0 : value.getLocalAnnotationsCount());
        if (annotationsCount > 0) {
            text = "<img src=\"images/comment.gif\" title=\""
                    + UIUtil.getNiceNoteCountText(annotationsCount)
                    + " on this value. \nClick on the icon to see existing or to add new note(s).\" " + AbstractPropertyWidgetWithNotes.COMMENT_ICON_STYLE_STRING + "></img>"
                    + "<span style=\"vertical-align:super;font-size:95%;color:#15428B;font-weight:bold;\">"
                    + "&nbsp;" + annotationsCount + "</span>";
        }
        commentLink = new Anchor(text, true);
        commentLink.setWidth("40px");
        commentLink.setHeight("22px");
        commentLink.addClickHandler(new ClickHandler() {
        double timeOfLastClick = 0;

            public void onClick(ClickEvent event) {
        double eventTime = new Date().getTime(); //take current time since there is no way to get time from a ClickEvent
        if (eventTime - timeOfLastClick > 500) { //not the second click in a double click
          onCellClickOrDblClick(event);
            };

            //Set new value for timeOfLastClick the time the last click was handled.
            //We use the current time (and not eventTime), because some time may have passed since eventTime
            //while executing the onCellClickOrDblClick method.
            timeOfLastClick = new Date().getTime();
          }

            private void onCellClickOrDblClick(ClickEvent event) {
                if (UIUtil.confirmIsLoggedIn()) {
                    onEditNotes();
                }
            }
        });
        return commentLink;
    }

    protected void onEditNotes() {
//        // TODO Auto-generated method stub
//        super.onEditNotes(value);
        String annotEntityName = null;
        PropertyEntityData property = getProperty();
        if (property.getValueType() == ValueType.Instance) {
            //FIXME This solution will not work when multiple property values are specified:
            //  it will add the comment always to the first instance.
            //  This method should be generalized OR overwritten in subclasses that can deal
            //  with multiple property values.
            EntityData firstValue = UIUtil.getFirstItem(getValues());
            if (firstValue != null) {
                annotEntityName = firstValue.getName();
            }
            onEditNotes(annotEntityName);
        }
        else {
            //TODO this is a hack. Fix it when the Changes API will provide
            // ways to add notes to property values
            // Until then we add the notes to the selected class itself
            annotEntityName = getSubject().getName();
            onEditNotes(annotEntityName, "[" + AbstractFieldWidget.this.getProperty().getBrowserText() + "] ", "");
        }
    }

    protected Field createFieldComponent() {
        TextField textField = new TextField();
        return textField;
    }

    public void setLabel(String label, String helpURL, String tooltip) {
       //FIXME: workarounfd! Field should never be null!!
        if (field != null) {
            field.setLabel(getLabelHtml(label, helpURL, tooltip));
            field.setLabelSeparator(AbstractFieldWidget.LABEL_SEPARATOR);
        }

    }

    @Override
    public void setup(Map<String, Object> widgetConfiguration, PropertyEntityData propertyEntityData) {
        super.setup(widgetConfiguration, propertyEntityData);
        String tooltip = getTooltipText();
    getField().setTitle(tooltip);

        String label = UIUtil.getStringConfigurationProperty(widgetConfiguration, FormConstants.LABEL, "");
        setLabel(label != null ? label : (propertyEntityData != null ? propertyEntityData.getBrowserText() : ""), getHelpURL(), tooltip );

        //If the property does not have a browserText, use the label of the field. This is experimental to see if it has the desirable behavior.
        getProperty().setBrowserText(label);

        String width = UIUtil.getStringConfigurationProperty(widgetConfiguration, FormConstants.WIDTH, null);
        if (width != null) {
          field.setWidth(width);
        }
        String height = UIUtil.getStringConfigurationProperty(widgetConfiguration, FormConstants.HEIGHT, null);
        if (height != null) {
          field.setHeight(height);
        }

        boolean readOnly = isReadOnly();
        getField().setReadOnly(readOnly);
        boolean disabled = isDisabled();
        getField().setDisabled(disabled);

        if (readOnly || disabled) {
            deleteLink.setHTML("&nbsp<img src=\"images/delete_grey.png\" " + AbstractFieldWidget.DELETE_ICON_STYLE_STRING + "></img>");
            deleteLink.setTitle("Delete value is not allowed");
        }
    }

    @Override
    public Collection<EntityData> getValues() {
        return values;
    }

    @Override
    public void setValues(Collection<EntityData> values) {
        this.values = values != null ? values : new ArrayList<EntityData>();
        displayValues();
    }

    protected void displayValues() {
        displayValues(values);
    }

    protected void displayValues(Collection<EntityData> values) {
        if (values == null || values.size() == 0) {
            field.setValue("");
        } else {
            if (values.size() == 1) {
                EntityData value = values.iterator().next();
                String displayText = UIUtil.getDisplayText(value);
                field.setValue(displayText);
            } else {
                field.setValue(UIUtil.prettyPrintList(values));
            }
        }
    }

    public Field getField() {
        return field;
    }

    @Override
    public Component getComponent() {
        return getWrappingPanel();
    }

    public Panel getWrappingPanel() {
        return wrappingPanel;
    }

    protected void deletePropertyValue(EntityData subject, String propName, ValueType propValueType,
            EntityData oldEntityData, Object oldDisplayedValue, String operationDescription) {
        propertyValueUtil.deletePropertyValue(getProjectId(), subject.getName(), propName, propValueType,
                oldEntityData.getName(), Application.get().getUserId(), operationDescription,
                new RemovePropertyValueHandler(subject, oldEntityData, values));
    }

    protected void replacePropertyValue(EntityData subject, String propName, ValueType propValueType,
            EntityData oldEntityData, EntityData newEntityData, Object oldDisplayedValue, String operationDescription) {
        propertyValueUtil.replacePropertyValue(getProjectId(), subject.getName(), propName, propValueType,
                oldEntityData.getName(), newEntityData.getName(), Application.get().getUserId(),
                operationDescription, new ReplacePropertyValueHandler(subject, oldEntityData, newEntityData, values));
    }

    //TODO: assume value value type is the same as the property value type, fix later
    protected void addPropertyValue(EntityData subject, String propName, ValueType propValueType,
            EntityData newEntityData, Object oldDisplayedValue, String operationDescription) {
        propertyValueUtil.addPropertyValue(getProjectId(), subject.getName(), propName, propValueType,
                newEntityData.getName(), Application.get().getUserId(), operationDescription,
                new AddPropertyValueHandler(subject, newEntityData, values));
    }

    /*
     * Remote calls
     */
    class RemovePropertyValueHandler extends AbstractAsyncHandler<Void> {

        protected EntityData subject;
        protected EntityData oldEntityData;
        protected Collection<EntityData> oldValues;

        public RemovePropertyValueHandler(EntityData subject, EntityData oldEntityData, Collection<EntityData> oldValues) {
            this.subject = subject;
            this.oldEntityData = oldEntityData;
            this.oldValues = oldValues;
        }

        @Override
        public void handleFailure(Throwable caught) {
            GWT.log("Error at removing value for " + getProperty().getBrowserText() + " and "
                    + subject.getBrowserText(), caught);
            Window.alert("There was an error at removing the property value for " + getProperty().getBrowserText()
                    + " and " + subject.getBrowserText() + ".");
            if (subject.equals(getSubject())) {
                setValues(oldValues);
            }
        }

        @Override
        public void handleSuccess(Void result) {
            if (subject.equals(getSubject())) {
                Collection<EntityData> newValues;
                if (oldValues != null && oldValues.contains(oldEntityData)) {
                    newValues = oldValues;
                    newValues.remove(oldEntityData);
                }
                else {
                    newValues = null;
                }
                setValues(newValues);
            }
        }

    }

    protected class ReplacePropertyValueHandler extends AbstractAsyncHandler<Void> {

        protected EntityData subject;
        protected EntityData oldEntityData;
        protected EntityData newEntityData;
        protected Collection<EntityData> oldValues;

        public ReplacePropertyValueHandler(EntityData subject,
                EntityData oldEntityData, EntityData newEntityData, Collection<EntityData> oldValues) {
            this.subject = subject;
            this.oldEntityData = oldEntityData;
            this.newEntityData = newEntityData;
            this.oldValues = oldValues;
        }

        @Override
        public void handleFailure(Throwable caught) {
            GWT.log("Error at replace property for " + getProperty().getBrowserText() + " and "
                    + subject.getBrowserText(), caught);
            Window.alert("There was an error at setting the property value for " + subject.getBrowserText() + ".");
            if (subject.equals(getSubject())) {
                setValues(oldValues);
            }
        }

        @Override
        public void handleSuccess(Void result) {
            //FIXME: we need a reload method
            if (subject.equals(getSubject())) {
                Collection<EntityData> newValues;
                if (oldValues != null && oldValues.contains(oldEntityData)) {
                    newValues = oldValues;
                    newValues.remove(oldEntityData);
                    newValues.add(newEntityData);
                }
                else {
                    newValues = new ArrayList<EntityData>();
                    newValues.add(newEntityData);
                }
                setValues(newValues);
            }
        }
    }

    class AddPropertyValueHandler extends AbstractAsyncHandler<Void> {

        protected EntityData subject;
        protected EntityData newEntityData;
        protected Collection<EntityData> oldValues;

        public AddPropertyValueHandler(EntityData subject,
                EntityData newEntityData, Collection<EntityData> oldValues) {
            this.subject = subject;
            this.newEntityData = newEntityData;
            this.oldValues = oldValues;
        }

        @Override
        public void handleFailure(Throwable caught) {
            GWT.log("Error at add property for " + getProperty().getBrowserText() + " and "
                    + subject.getBrowserText(), caught);
            Window.alert("There was an error at adding the property value for " + subject.getBrowserText() + ".");
            if (subject.equals(getSubject())) {
                setValues(oldValues);
            }
        }

        @Override
        public void handleSuccess(Void result) {
            //FIXME: we need a reload method
            if (subject.equals(getSubject())) {
                Collection<EntityData> newValues;
                if (oldValues != null && !oldValues.isEmpty()) {
                    newValues = oldValues;
                    newValues.add(newEntityData);
                }
                else {
                    newValues = new ArrayList<EntityData>();
                    newValues.add(newEntityData);
                }
                setValues(newValues);
            }
        }
    }

}
TOP

Related Classes of edu.stanford.bmir.protege.web.client.ui.portlet.propertyForm.AbstractFieldWidget$RemovePropertyValueHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.