From 791d9e7caab433363a37c795253fbc4c78cacb6d Mon Sep 17 00:00:00 2001 From: tpylak <tpylak> Date: Tue, 31 Mar 2009 12:03:19 +0000 Subject: [PATCH] LMS-751 unify combobox extensions SVN: 10491 --- .../field/VocabularyTermSelectionWidget.java | 15 +- .../material/MaterialTypeSelectionWidget.java | 6 +- .../application/ui/sample/DropDownList.java | 291 +++++++++++++++++- .../ui/sample/SimpleDropDownList.java | 291 ------------------ .../ui/widget/EntityRegistrationPanel.java | 4 +- 5 files changed, 284 insertions(+), 323 deletions(-) delete mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java index da434ade147..3baa75a655b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/VocabularyTermSelectionWidget.java @@ -24,7 +24,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.VocabularyTermModel; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SimpleDropDownList; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; @@ -36,7 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKin * @author Izabela Adamczyk */ public class VocabularyTermSelectionWidget extends - SimpleDropDownList<VocabularyTermModel, VocabularyTerm> + DropDownList<VocabularyTermModel, VocabularyTerm> { private static final String CHOOSE_MSG = "Choose..."; @@ -75,7 +75,7 @@ public class VocabularyTermSelectionWidget extends IViewContext<?> viewContextOrNull) { super(idSuffix, ModelDataPropertyNames.CODE, label, CHOOSE_MSG, EMPTY_MSG, - VALUE_NOT_IN_LIST_MSG, mandatory); + VALUE_NOT_IN_LIST_MSG, mandatory, viewContextOrNull, false); this.viewContextOrNull = viewContextOrNull; this.vocabularyOrNull = vocabularyOrNull; @@ -93,15 +93,6 @@ public class VocabularyTermSelectionWidget extends getPropertyEditor().setList(store.getModels()); } - @Override - public void refreshStore() - { - if (viewContextOrNull != null) - { - refreshStore(viewContextOrNull); - } - } - @Override protected List<VocabularyTermModel> convertItems(List<VocabularyTerm> result) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java index ad50c16ed51..bfedd5476f1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java @@ -87,8 +87,8 @@ public final class MaterialTypeSelectionWidget extends /** * Returns the {@link MaterialType} currently selected. * - * @return <code>null</code> if nothing is selected yet or "none" option has been chosen (if - * it has been enabled before). + * @return <code>null</code> if nothing is selected yet or "none" option has been chosen (if it + * has been enabled before). */ public final MaterialType tryGetSelectedMaterialType() { @@ -124,7 +124,7 @@ public final class MaterialTypeSelectionWidget extends { viewContext.getService().listMaterialTypes(callback); } - + public DatabaseModificationKind[] getRelevantModifications() { return DatabaseModificationKind.any(ObjectKind.MATERIAL_TYPE); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java index b5e873fd58a..cd79740b260 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/DropDownList.java @@ -16,44 +16,305 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + import com.extjs.gxt.ui.client.data.ModelData; +import com.extjs.gxt.ui.client.store.ListStore; +import com.extjs.gxt.ui.client.store.Store; import com.extjs.gxt.ui.client.widget.form.ComboBox; import com.google.gwt.user.client.Element; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; /** - * {@link ComboBox} which loads data, allows filtering and requires selection. - * * @author Izabela Adamczyk */ -public abstract class DropDownList<M extends ModelData, E> extends SimpleDropDownList<M, E> +abstract public class DropDownList<M extends ModelData, E> extends ComboBox<M> implements + IDatabaseModificationObserver { + abstract protected void loadData(AbstractAsyncCallback<List<E>> callback); + + abstract protected List<M> convertItems(final List<E> result); + + // ---------- + + private static final int DEFAULT_WIDTH = 150; + + private static final String PREFIX = "select_"; + + public static final String ID = GenericConstants.ID_PREFIX + PREFIX; + + private final String valueNotInListMsg; + + private final String chooseMsg; + + private final String emptyMsg; + + private final boolean mandatory; - private final IViewContext<?> viewContext; + private final boolean reloadWhenRendering; + + private final IViewContext<?> viewContextOrNull; public DropDownList(final IViewContext<?> viewContext, String idSuffix, String labelDictCode, String displayField, String chooseSuffix, String nothingFoundSuffix) { - super(idSuffix, displayField, viewContext.getMessage(labelDictCode), viewContext - .getMessage(Dict.COMBO_BOX_CHOOSE, chooseSuffix), viewContext.getMessage( - Dict.COMBO_BOX_EMPTY, nothingFoundSuffix), viewContext - .getMessage(Dict.COMBO_BOX_EXPECTED_VALUE_FROM_THE_LIST), true); - this.viewContext = viewContext; + this(idSuffix, displayField, viewContext.getMessage(labelDictCode), viewContext.getMessage( + Dict.COMBO_BOX_CHOOSE, chooseSuffix), viewContext.getMessage(Dict.COMBO_BOX_EMPTY, + nothingFoundSuffix), viewContext + .getMessage(Dict.COMBO_BOX_EXPECTED_VALUE_FROM_THE_LIST), true, viewContext, true); } - @Override - protected void onRender(final Element parent, final int pos) + /** if viewContextOrNull is null the combobox is not able to refresh itself */ + public DropDownList(String idSuffix, String displayField, String label, String chooseMsg, + String emptyMsg, String valueNotInListMsg, boolean mandatory, + final IViewContext<?> viewContextOrNull, boolean reloadWhenRendering) + { + this.chooseMsg = chooseMsg; + this.emptyMsg = emptyMsg; + this.valueNotInListMsg = valueNotInListMsg; + this.mandatory = mandatory; + this.reloadWhenRendering = reloadWhenRendering; + this.viewContextOrNull = viewContextOrNull; + + setId(ID + idSuffix); + setEnabled(true); + setValidateOnBlur(true); + setAllowBlank(mandatory == false); + setWidth(DEFAULT_WIDTH); + setDisplayField(displayField); + setFieldLabel(label); + setStore(new ListStore<M>()); + } + + public DatabaseModificationAwareField<M> asDatabaseModificationAware() + { + return new DatabaseModificationAwareField<M>(this, this); + } + + public void update(Set<DatabaseModificationKind> observedModifications) { - super.onRender(parent, pos); refreshStore(); } - @Override + /** + * Refreshes the whole store of the combobox. If the previously chosen value is no longer + * present in the store, it will be changed to empty. Otherwise the previous selection will be + * preserved. + */ public void refreshStore() { - refreshStore(viewContext); + if (viewContextOrNull != null) + { + loadData(new ListItemsCallback(viewContextOrNull)); + } + } + + public class ListItemsCallback extends AbstractAsyncCallback<List<E>> + { + + protected ListItemsCallback(final IViewContext<?> viewContext) + { + super(viewContext); + } + + @Override + public void process(final List<E> result) + { + List<M> convertedItems = convertItems(result); + updateStore(convertedItems); + } + } + + protected void updateStore(final List<M> models) + { + final ListStore<M> termsStore = getStore(); + termsStore.removeAll(); + termsStore.add(models); + if (termsStore.getCount() > 0) + { + setEmptyText(chooseMsg); + setReadOnly(false); + if (getValue() != null && getSelection().size() == 0) + { + validate(); // maybe the value became a valid selection + } + restoreSelection(getSelection()); + } else + { + setEmptyText(emptyMsg); + setReadOnly(true); + } + applyEmptyText(); + } + + private void restoreSelection(List<M> previousSelection) + { + List<M> newSelection = cleanSelection(previousSelection, getStore()); + if (previousSelection.size() != newSelection.size()) + { + setSelection(newSelection); + } + } + + // removes the no longer existing items from the selection + private static <M extends ModelData> List<M> cleanSelection(List<M> previousSelection, + Store<M> newStore) + { + List<M> newSelection = new ArrayList<M>(); + for (M prevItem : previousSelection) + { + if (containsModel(newStore, prevItem)) + { + newSelection.add(prevItem); + } + } + return newSelection; + } + + private static <M extends ModelData> boolean containsModel(Store<M> store, M item) + { + for (M elem : store.getModels()) + { + if (equalsModel(elem, item)) + { + return true; + } + } + return false; } -} \ No newline at end of file + private static <M extends ModelData> boolean equalsModel(M model1, M model2) + { + Collection<String> props1 = model1.getPropertyNames(); + Collection<String> props2 = model1.getPropertyNames(); + if (props1.equals(props2) == false) + { + return false; + } + for (String propName : props1) + { + Object val1 = model1.get(propName); + Object val2 = model2.get(propName); + if (val1 == null) + { + if (val2 != null) + { + return false; + } else + { + continue; + } + } else + { + if (val1.equals(val2) == false) + { + return false; + } + } + } + return true; + } + + @Override + public String getRawValue() + { + if (mandatory && optionNoneSelected()) + { + return ""; + } + return super.getRawValue(); + } + + @Override + public M getValue() + { + final M val = super.getValue(); + if (optionNoneSelected()) + { + return null; + } + return val; + } + + private boolean optionNoneSelected() + { + return super.getRawValue() != null && super.getRawValue().equals(GWTUtils.NONE_LIST_ITEM); + } + + /** + * Assumes that M contains field OBJECT of type E. + */ + public E tryGetSelected() + { + if (optionNoneSelected()) + { + return null; + } + return GWTUtils.tryGetSingleSelected(this); + } + + /** + * @return true if anything has been selected. <br> + * Note that the result can be different from tryGetSelected() != null if there are null + * values in the model. + */ + protected boolean isAnythingSelected() + { + if (optionNoneSelected()) + { + return false; + } + return GWTUtils.tryGetSingleSelectedCode(this) != null; + } + + private void markInvalidIfNotFromList() + { + if (valueNotInTheList()) + { + forceInvalid(valueNotInListMsg); + } + } + + private boolean valueNotInTheList() + { + return getValue() == null && getRawValue() != null && getRawValue().equals("") == false + && getRawValue().equals(getEmptyText()) == false && optionNoneSelected() == false; + } + + @Override + public boolean isValid() + { + clearInvalid(); + markInvalidIfNotFromList(); + return super.isValid() && valueNotInTheList() == false; + } + + @Override + public boolean validate() + { + clearInvalid(); + markInvalidIfNotFromList(); + return super.validate() && valueNotInTheList() == false; + } + + @Override + protected void onRender(final Element parent, final int pos) + { + super.onRender(parent, pos); + if (reloadWhenRendering) + { + refreshStore(); + } + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java deleted file mode 100644 index 76f11f4f2fe..00000000000 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/sample/SimpleDropDownList.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright 2009 ETH Zuerich, CISD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import com.extjs.gxt.ui.client.data.ModelData; -import com.extjs.gxt.ui.client.store.ListStore; -import com.extjs.gxt.ui.client.store.Store; -import com.extjs.gxt.ui.client.widget.form.ComboBox; - -import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DatabaseModificationAwareField; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.GWTUtils; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; - -/** - * @author Izabela Adamczyk - */ -abstract public class SimpleDropDownList<M extends ModelData, E> extends ComboBox<M> implements - IDatabaseModificationObserver -{ - - /** - * Refreshes the whole store of the combobox. If the previously chosen value is no longer - * present in the store, it will be changed to empty. Otherwise the previous selection will be - * preserved. - */ - abstract public void refreshStore(); - - abstract protected void loadData(AbstractAsyncCallback<List<E>> callback); - - abstract protected List<M> convertItems(final List<E> result); - - // ---------- - - private static final int DEFAULT_WIDTH = 150; - - private static final String PREFIX = "select_"; - - public static final String ID = GenericConstants.ID_PREFIX + PREFIX; - - private final String valueNotInListMsg; - - private final String chooseMsg; - - private final String emptyMsg; - - private final boolean mandatory; - - public SimpleDropDownList(String idSuffix, String displayField, String label, String chooseMsg, - String emptyMsg, String valueNotInListMsg, boolean mandatory) - { - this.chooseMsg = chooseMsg; - this.emptyMsg = emptyMsg; - this.valueNotInListMsg = valueNotInListMsg; - this.mandatory = mandatory; - setId(ID + idSuffix); - setEnabled(true); - setValidateOnBlur(true); - setAllowBlank(mandatory == false); - setWidth(DEFAULT_WIDTH); - setDisplayField(displayField); - setFieldLabel(label); - setStore(new ListStore<M>()); - } - - public DatabaseModificationAwareField<M> asDatabaseModificationAware() - { - return new DatabaseModificationAwareField<M>(this, this); - } - - public void update(Set<DatabaseModificationKind> observedModifications) - { - refreshStore(); - } - - protected void refreshStore(final IViewContext<?> viewContext) - { - loadData(new ListItemsCallback(viewContext)); - } - - public class ListItemsCallback extends AbstractAsyncCallback<List<E>> - { - - protected ListItemsCallback(final IViewContext<?> viewContext) - { - super(viewContext); - } - - @Override - public void process(final List<E> result) - { - List<M> convertedItems = convertItems(result); - updateStore(convertedItems); - } - } - - protected void updateStore(final List<M> models) - { - final ListStore<M> termsStore = getStore(); - termsStore.removeAll(); - termsStore.add(models); - if (termsStore.getCount() > 0) - { - setEmptyText(chooseMsg); - setReadOnly(false); - if (getValue() != null && getSelection().size() == 0) - { - validate(); // maybe the value became a valid selection - } - restoreSelection(getSelection()); - } else - { - setEmptyText(emptyMsg); - setReadOnly(true); - } - applyEmptyText(); - } - - private void restoreSelection(List<M> previousSelection) - { - List<M> newSelection = cleanSelection(previousSelection, getStore()); - if (previousSelection.size() != newSelection.size()) - { - setSelection(newSelection); - } - } - - // removes the no longer existing items from the selection - private static <M extends ModelData> List<M> cleanSelection(List<M> previousSelection, - Store<M> newStore) - { - List<M> newSelection = new ArrayList<M>(); - for (M prevItem : previousSelection) - { - if (containsModel(newStore, prevItem)) - { - newSelection.add(prevItem); - } - } - return newSelection; - } - - private static <M extends ModelData> boolean containsModel(Store<M> store, M item) - { - for (M elem : store.getModels()) - { - if (equalsModel(elem, item)) - { - return true; - } - } - return false; - } - - private static <M extends ModelData> boolean equalsModel(M model1, M model2) - { - Collection<String> props1 = model1.getPropertyNames(); - Collection<String> props2 = model1.getPropertyNames(); - if (props1.equals(props2) == false) - { - return false; - } - for (String propName : props1) - { - Object val1 = model1.get(propName); - Object val2 = model2.get(propName); - if (val1 == null) - { - if (val2 != null) - { - return false; - } else - { - continue; - } - } else - { - if (val1.equals(val2) == false) - { - return false; - } - } - } - return true; - } - - @Override - public String getRawValue() - { - if (mandatory && optionNoneSelected()) - { - return ""; - } - return super.getRawValue(); - } - - @Override - public M getValue() - { - final M val = super.getValue(); - if (optionNoneSelected()) - { - return null; - } - return val; - } - - private boolean optionNoneSelected() - { - return super.getRawValue() != null && super.getRawValue().equals(GWTUtils.NONE_LIST_ITEM); - } - - /** - * Assumes that M contains field OBJECT of type E. - */ - public E tryGetSelected() - { - if (optionNoneSelected()) - { - return null; - } - return GWTUtils.tryGetSingleSelected(this); - } - - /** - * @return true if anything has been selected. <br> - * Note that the result can be different from tryGetSelected() != null if there are null - * values in the model. - */ - protected boolean isAnythingSelected() - { - if (optionNoneSelected()) - { - return false; - } - return GWTUtils.tryGetSingleSelectedCode(this) != null; - } - - private void markInvalidIfNotFromList() - { - if (valueNotInTheList()) - { - forceInvalid(valueNotInListMsg); - } - } - - private boolean valueNotInTheList() - { - return getValue() == null && getRawValue() != null && getRawValue().equals("") == false - && getRawValue().equals(getEmptyText()) == false && optionNoneSelected() == false; - } - - @Override - public boolean isValid() - { - clearInvalid(); - markInvalidIfNotFromList(); - return super.isValid() && valueNotInTheList() == false; - } - - @Override - public boolean validate() - { - clearInvalid(); - markInvalidIfNotFromList(); - return super.validate() && valueNotInTheList() == false; - } - -} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java index 2efee3840d4..e5b70a4310c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/EntityRegistrationPanel.java @@ -38,7 +38,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework. import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames; import ch.systemsx.cisd.openbis.generic.client.web.client.application.plugin.IClientPlugin; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SimpleDropDownList; +import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; @@ -51,7 +51,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType; * * @author Izabela Adamczyk */ -abstract public class EntityRegistrationPanel<T extends ModelData, S extends SimpleDropDownList<T, ?>> +abstract public class EntityRegistrationPanel<T extends ModelData, S extends DropDownList<T, ?>> extends ContentPanel implements IDatabaseModificationObserver { private final S entityTypeSelection; -- GitLab