diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/filter/FiltersGenerator.java b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/FiltersGenerator.java index b22f20c..9fa347e 100644 --- a/src/main/java/org/gcube/portlets/user/tdwx/client/filter/FiltersGenerator.java +++ b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/FiltersGenerator.java @@ -3,6 +3,7 @@ package org.gcube.portlets.user.tdwx.client.filter; import java.util.ArrayList; import java.util.Date; +import org.gcube.portlets.user.tdwx.client.filter.text.TextFilter; import org.gcube.portlets.user.tdwx.client.model.grid.DataRowColumnConfig; import org.gcube.portlets.user.tdwx.shared.model.DataRow; import org.gcube.portlets.user.tdwx.shared.model.ValueType; @@ -15,7 +16,6 @@ import com.sencha.gxt.widget.core.client.grid.ColumnModel; import com.sencha.gxt.widget.core.client.grid.filters.DateFilter; import com.sencha.gxt.widget.core.client.grid.filters.Filter; import com.sencha.gxt.widget.core.client.grid.filters.NumericFilter; -import com.sencha.gxt.widget.core.client.grid.filters.StringFilter; /** @@ -79,7 +79,7 @@ public class FiltersGenerator { break; case STRING: @SuppressWarnings("unchecked") - StringFilter stringFilt = new StringFilter( + TextFilter stringFilt = new TextFilter( (ValueProvider) dataRowColConfig .getValueProvider()); filters.add(stringFilt); diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilter.java b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilter.java new file mode 100644 index 0000000..856f6b6 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilter.java @@ -0,0 +1,251 @@ +package org.gcube.portlets.user.tdwx.client.filter.text; + +import java.util.ArrayList; +import java.util.List; + +import org.gcube.portlets.user.tdwx.client.filter.text.TextMenu.TextItem; + +import com.sencha.gxt.core.client.ValueProvider; +import com.sencha.gxt.data.shared.loader.FilterConfig; +import com.sencha.gxt.messages.client.DefaultMessages; +import com.sencha.gxt.widget.core.client.grid.filters.Filter; + +/** + * + * @author giancarlo + * email: g.panichi@isti.cnr.it + * + * @param + */ +public class TextFilter extends Filter { + /** + * The default locale-sensitive messages used by this class. + */ + public class DefaultTextFilterMessages implements TextFilterMessages { + + @Override + public String emptyText() { + return DefaultMessages.getMessages().stringFilter_emptyText(); + } + + } + + /** + * The locale-sensitive messages used by this class. + */ + public interface TextFilterMessages { + String emptyText(); + } + + private List textItems = new ArrayList(); + private TextMenu textMenu; + private TextFilterMessages messages = new DefaultTextFilterMessages(); + + + /** + * Creates a text filter for the specified value provider. See + * {@link Filter#Filter(ValueProvider)} for more information. + * + * @param valueProvider + * the value provider + */ + public TextFilter(ValueProvider valueProvider) { + super(valueProvider); + + setHandler(new TextFilterHandler()); + + textItems.add(TextItem.CONTAINS); + textItems.add(TextItem.BEGINS); + textItems.add(TextItem.ENDS); + textItems.add(TextItem.SOUNDEX); + + textMenu = new TextMenu(this); + menu = textMenu; + textMenu.setTextItems(textItems); + + } + + /** + * Sets the contains value. + * + * @param value + * the value + */ + public void setContainsValue(String value) { + textMenu.ct.setValue(value); + } + + /** + * Sets the begins value. + * + * @param value + * the value + */ + public void setBeginsValue(String value) { + textMenu.bg.setValue(value); + } + + /** + * Sets the ends value. + * + * @param value + * the value + */ + public void setEndsValue(String value) { + textMenu.en.setValue(value); + } + + + /** + * Sets the soundex value. + * + * @param value + * the value + */ + public void setSoundexValue(String value) { + textMenu.sd.setValue(value); + } + + public void setValue(List values) { + textMenu.setValue(values); + } + + @SuppressWarnings("unchecked") + @Override + public List getFilterConfig() { + return (List) getValue(); + } + + /** + * Returns the locale-sensitive messages used by this class. + * + * @return the local-sensitive messages used by this class. + */ + public TextFilterMessages getMessages() { + return messages; + } + + @Override + public Object getValue() { + return textMenu.getValue(); + } + + + + @Override + public boolean isActivatable() { + if (textMenu.ct != null + && textMenu.ct.getCurrentValue() != null) { + return true; + } + if (textMenu.bg != null + && textMenu.bg.getCurrentValue() != null) { + return true; + } + if (textMenu.en != null + && textMenu.en.getCurrentValue() != null) { + return true; + } + if (textMenu.sd != null + && textMenu.sd.getCurrentValue() != null) { + return true; + } + return false; + } + + public void setMessages(TextFilterMessages messages) { + this.messages = messages; + textMenu.setEmptyText(messages.emptyText()); + } + + + + + @Override + protected Class getType() { + return String.class; + } + + @Override + protected boolean validateModel(M model) { + boolean isValid = true; + String modelValue = getValueProvider().getValue(model); + + if (textMenu.ct != null) { + String filterValue = textMenu.ct.getCurrentValue(); + String v = filterValue == null ? "" : filterValue.toString(); + if (v.length() == 0 + && (modelValue == null || modelValue.length() == 0)) { + isValid = true; + } else if (modelValue == null) { + isValid = false; + } else { + isValid = modelValue.toLowerCase().indexOf(v.toLowerCase()) > -1; + } + + } + if (textMenu.bg != null) { + String filterValue = textMenu.bg.getCurrentValue(); + String v = filterValue == null ? "" : filterValue.toString(); + if (v.length() == 0 + && (modelValue == null || modelValue.length() == 0)) { + isValid = true; + } else if (modelValue == null) { + isValid = false; + } else { + isValid = modelValue.toLowerCase().indexOf(v.toLowerCase()) > -1; + } + + } + if (textMenu.en != null) { + String filterValue = textMenu.en.getCurrentValue(); + String v = filterValue == null ? "" : filterValue.toString(); + if (v.length() == 0 + && (modelValue == null || modelValue.length() == 0)) { + isValid = true; + } else if (modelValue == null) { + isValid = false; + } else { + isValid = modelValue.toLowerCase().indexOf(v.toLowerCase()) > -1; + } + + } + + + if (textMenu.sd != null) { + String filterValue = textMenu.sd.getCurrentValue(); + String v = filterValue == null ? "" : filterValue.toString(); + if (v.length() == 0 + && (modelValue == null || modelValue.length() == 0)) { + isValid = true; + } else if (modelValue == null) { + isValid = false; + } else { + isValid = modelValue.toLowerCase().indexOf(v.toLowerCase()) > -1; + } + + } + + return isValid; + } + + @Override + public void setFilterConfig(List configs) { + boolean hasValue = false; + for (int i = 0; i < configs.size(); i++) { + FilterConfig config = configs.get(i); + if (config.getValue() != null && !"".equals(config.getValue())) { + hasValue = true; + } + } + setValue(configs); + setActive(hasValue, false); + } + + + @Override + protected void fireUpdate() { + super.fireUpdate(); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilterHandler.java b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilterHandler.java new file mode 100644 index 0000000..4aeb467 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextFilterHandler.java @@ -0,0 +1,24 @@ +package org.gcube.portlets.user.tdwx.client.filter.text; + +import com.sencha.gxt.data.shared.loader.FilterHandler; + + +/** + * + * @author giancarlo + * email: g.panichi@isti.cnr.it + * + */ +public class TextFilterHandler extends FilterHandler { + + @Override + public String convertToObject(String value) { + return value; + } + + @Override + public String convertToString(String object) { + return object; + } + +} diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextMenu.java b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextMenu.java new file mode 100644 index 0000000..e257fd5 --- /dev/null +++ b/src/main/java/org/gcube/portlets/user/tdwx/client/filter/text/TextMenu.java @@ -0,0 +1,286 @@ +package org.gcube.portlets.user.tdwx.client.filter.text; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.gcube.portlets.user.tdwx.client.resources.ResourceBundle; + +import com.google.gwt.dom.client.Style.Cursor; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.user.client.Event; +import com.sencha.gxt.core.client.resources.CommonStyles; +import com.sencha.gxt.core.client.util.DelayedTask; +import com.sencha.gxt.data.shared.loader.FilterConfig; +import com.sencha.gxt.data.shared.loader.FilterConfigBean; +import com.sencha.gxt.widget.core.client.event.BeforeHideEvent; +import com.sencha.gxt.widget.core.client.event.BeforeHideEvent.BeforeHideHandler; +import com.sencha.gxt.widget.core.client.form.TextField; +import com.sencha.gxt.widget.core.client.menu.Menu; +import com.sencha.gxt.widget.core.client.menu.MenuItem; + +/** + * + * @author giancarlo email: g.panichi@isti.cnr.it + * + * @param + */ +public class TextMenu extends Menu { + + /** + * A menu of string items for use with a {@link TextFilter}. + * + * @param + * the model type + */ + + public enum TextItem { + CONTAINS("ct"), BEGINS("bg"), ENDS("en"), SOUNDEX("sd"); + + private final String key; + + private TextItem(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + } + + protected TextField ct, bg, en, sd; + + private TextFilter filter; + private List textItems = new ArrayList(); + private DelayedTask updateTask = new DelayedTask() { + + @Override + public void onExecute() { + fireUpdate(); + } + }; + + /** + * Creates text menu for use with the specified text filter. + * + * @param filter + * the filter that uses this text menu + */ + public TextMenu(TextFilter filter) { + this.filter = filter; + + addBeforeHideHandler(new BeforeHideHandler() { + + @Override + public void onBeforeHide(BeforeHideEvent event) { + // blur the field because of empty text + if (ct != null) { + ct.getElement().selectNode("input").blur(); + } + + if (bg != null) { + bg.getElement().selectNode("input").blur(); + } + + if (en != null) { + en.getElement().selectNode("input").blur(); + } + + if (sd != null) { + sd.getElement().selectNode("input").blur(); + } + } + }); + } + + /** + * Returns the menu's text items. + * + * @return the text items + */ + public List getTextItems() { + return Collections.unmodifiableList(textItems); + } + + /** + * Returns the menu's value. + * + * @return the value + */ + public List getValue() { + List configs = new ArrayList(); + if (ct != null && ct.getCurrentValue() != null && ct.isCurrentValid()) { + FilterConfig config = new FilterConfigBean(); + config.setType("string"); + config.setComparison("contains"); + config.setValue(ct.getCurrentValue().toString()); + configs.add(config); + } + + if (bg != null && bg.getCurrentValue() != null && bg.isCurrentValid()) { + FilterConfig config = new FilterConfigBean(); + config.setType("string"); + config.setComparison("begins"); + config.setValue(bg.getCurrentValue().toString()); + configs.add(config); + } + + if (en != null && en.getCurrentValue() != null && en.isCurrentValid()) { + FilterConfig config = new FilterConfigBean(); + config.setType("string"); + config.setComparison("ends"); + config.setValue(en.getCurrentValue().toString()); + configs.add(config); + } + + if (sd != null && sd.getCurrentValue() != null && sd.isCurrentValid()) { + FilterConfig config = new FilterConfigBean(); + config.setType("string"); + config.setComparison("soundex"); + config.setValue(sd.getCurrentValue().toString()); + configs.add(config); + } + + return configs; + } + + /** + * Sets the text to display in the menu's text fields if they do not contain + * a value. + * + * @param emptyText + * the text to display if the fields are empty + */ + public void setEmptyText(String emptyText) { + if (ct != null) { + ct.setEmptyText(emptyText); + } + if (bg != null) { + bg.setEmptyText(emptyText); + } + if (en != null) { + en.setEmptyText(emptyText); + } + if (sd != null) { + sd.setEmptyText(emptyText); + } + } + + /** + * Sets the menu's text items (defaults to CONTAINS, BEGINS, ENDS, SOUNDEX). + * + * @param textItems + * the text items + */ + public void setTextItems(List textItems) { + this.textItems = textItems; + clear(); + ImageResource icon = null; + String toolTip = null; + for (TextItem item : textItems) { + TextField field = createTextField(); + field.setEmptyText(filter.getMessages().emptyText()); + + switch (item) { + case CONTAINS: + icon = ResourceBundle.INSTANCE.textContains(); + toolTip = new String("Text Contains"); + ct = field; + break; + case BEGINS: + icon = ResourceBundle.INSTANCE.textBegins(); + toolTip = new String("Text Begins"); + bg = field; + break; + case ENDS: + icon = ResourceBundle.INSTANCE.textEnds(); + toolTip = new String("Text Ends"); + en = field; + break; + case SOUNDEX: + icon = ResourceBundle.INSTANCE.textSoundex(); + toolTip = new String("Soundex Algorithm"); + sd = field; + break; + + } + + MenuItem menuItem = new MenuItem(); + menuItem.setCanActivate(false); + menuItem.setHideOnClick(false); + menuItem.setIcon(icon); + menuItem.setWidget(field); + menuItem.setToolTip(toolTip); + + menuItem.getElement().removeClassName( + CommonStyles.get().unselectable()); + menuItem.getElement().getStyle().setCursor(Cursor.DEFAULT); + + add(menuItem); + } + } + + /** + * Sets the menu's values + * + * @param values + * the values + */ + public void setValue(List values) { + for (FilterConfig config : values) { + String c = config.getComparison(); + String v = config.getValue(); + if (v == null) { + v = ""; + } + + if ("st".equals(c)) { + ct.setValue(v); + } else if ("bg".equals(c)) { + bg.setValue(v); + } else if ("en".equals(c)) { + en.setValue(v); + } else if ("sd".equals(c)) { + sd.setValue(v); + } + } + fireUpdate(); + } + + protected TextField createTextField() { + TextField field = new TextField() { + @Override + protected void onKeyUp(Event event) { + super.onKeyUp(event); + onFieldKeyUp(this, event); + } + }; + + return field; + } + + @Override + protected void onAttach() { + super.onAttach(); + updateTask.delay(filter.getUpdateBuffer()); + } + + protected void onFieldKeyUp(TextField field, Event event) { + int kc = event.getKeyCode(); + if (kc == KeyCodes.KEY_ENTER && field.isCurrentValid()) { + event.preventDefault(); + event.stopPropagation(); + hide(true); + return; + } + + updateTask.delay(filter.getUpdateBuffer()); + } + + private void fireUpdate() { + filter.fireUpdate(); + } + +} diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/ResourceBundle.java b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/ResourceBundle.java index 88284e4..8e543bc 100644 --- a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/ResourceBundle.java +++ b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/ResourceBundle.java @@ -2,6 +2,7 @@ package org.gcube.portlets.user.tdwx.client.resources; import com.google.gwt.core.client.GWT; import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.resources.client.ImageResource; /** @@ -19,4 +20,28 @@ public interface ResourceBundle extends ClientBundle { TDGridCSS tdGridCSS(); + @Source("text-contains_32.png") + ImageResource textContains32(); + + @Source("text-contains.png") + ImageResource textContains(); + + @Source("text-begins_32.png") + ImageResource textBegins32(); + + @Source("text-begins.png") + ImageResource textBegins(); + + @Source("text-ends_32.png") + ImageResource textEnds32(); + + @Source("text-ends.png") + ImageResource textEnds(); + + @Source("text-soundex_32.png") + ImageResource textSoundex32(); + + @Source("text-soundex.png") + ImageResource textSoundex(); + } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins.png new file mode 100644 index 0000000..7b8aa8b Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png new file mode 100644 index 0000000..30503ab Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains.png new file mode 100644 index 0000000..3d52490 Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png new file mode 100644 index 0000000..9108f7f Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends.png new file mode 100644 index 0000000..c083dbe Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png new file mode 100644 index 0000000..8e6d665 Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png new file mode 100644 index 0000000..d6f1648 Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png differ diff --git a/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png new file mode 100644 index 0000000..225a408 Binary files /dev/null and b/src/main/java/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins.png new file mode 100644 index 0000000..7b8aa8b Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png new file mode 100644 index 0000000..30503ab Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-begins_32.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains.png new file mode 100644 index 0000000..3d52490 Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png new file mode 100644 index 0000000..9108f7f Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-contains_32.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends.png new file mode 100644 index 0000000..c083dbe Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png new file mode 100644 index 0000000..8e6d665 Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-ends_32.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png new file mode 100644 index 0000000..d6f1648 Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex.png differ diff --git a/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png new file mode 100644 index 0000000..225a408 Binary files /dev/null and b/src/main/resources/org/gcube/portlets/user/tdwx/client/resources/text-soundex_32.png differ