From 8424cb7135c7efe79277a40def6e1b74b4747435 Mon Sep 17 00:00:00 2001 From: Nikita Petunin Date: Thu, 14 Jul 2016 13:48:41 +0400 Subject: [PATCH] PL-7471 Implement rangeStart / rangeEnd for DateField --- .../gui/components/DesktopDateField.java | 68 ++++++++++++++++-- .../haulmont/cuba/desktop/messages.properties | 4 +- .../cuba/desktop/messages_ru.properties | 3 +- .../cuba/gui/components/DateField.java | 6 ++ .../gui/src/com/haulmont/cuba/gui/window.xsd | 4 ++ .../xml/layout/loaders/DateFieldLoader.java | 46 ++++++++++++ .../cuba/web/gui/components/WebDateField.java | 72 +++++++++++++++++-- 7 files changed, 189 insertions(+), 14 deletions(-) diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopDateField.java b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopDateField.java index f861eb4930..4e810b15ee 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopDateField.java +++ b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopDateField.java @@ -25,10 +25,7 @@ import com.haulmont.chile.core.model.MetaPropertyPath; import com.haulmont.chile.core.model.utils.InstanceUtils; import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.entity.annotation.IgnoreUserTimeZone; -import com.haulmont.cuba.core.global.AppBeans; -import com.haulmont.cuba.core.global.MessageTools; -import com.haulmont.cuba.core.global.TimeZones; -import com.haulmont.cuba.core.global.UserSessionSource; +import com.haulmont.cuba.core.global.*; import com.haulmont.cuba.desktop.App; import com.haulmont.cuba.desktop.gui.executors.impl.DesktopBackgroundWorker; import com.haulmont.cuba.desktop.sys.DesktopToolTipManager; @@ -38,6 +35,7 @@ import com.haulmont.cuba.desktop.sys.vcl.DatePicker.DatePicker; import com.haulmont.cuba.desktop.sys.vcl.Flushable; import com.haulmont.cuba.desktop.sys.vcl.FocusableComponent; import com.haulmont.cuba.gui.components.DateField; +import com.haulmont.cuba.gui.components.Frame; import com.haulmont.cuba.gui.components.RequiredValueMissingException; import com.haulmont.cuba.gui.components.ValidationException; import com.haulmont.cuba.gui.data.Datasource; @@ -55,6 +53,7 @@ import java.util.*; import java.util.List; public class DesktopDateField extends DesktopAbstractField implements DateField { + protected Messages messages; protected Resolution resolution; protected Datasource datasource; protected String dateTimeFormat; @@ -77,10 +76,13 @@ public class DesktopDateField extends DesktopAbstractField implements Da protected Datasource.ItemChangeListener itemChangeListener; protected Datasource.ItemPropertyChangeListener itemPropertyChangeListener; + protected Date startDate; + protected Date endDate; public DesktopDateField() { impl = new FocusableComposition(); + messages = AppBeans.get(Messages.NAME); initComponentParts(); setResolution(Resolution.MIN); @@ -106,11 +108,19 @@ public class DesktopDateField extends DesktopAbstractField implements Da timeField = new DesktopTimeField(); timeField.addValueChangeListener(e -> { + if (!checkRange(constructDate())) { + return; + } + updateInstance(); }); datePicker.addPropertyChangeListener(evt -> { if ("date".equals(evt.getPropertyName())) { + if (!checkRange(constructDate())) { + return; + } + updateInstance(); updateMissingValueState(); } @@ -210,6 +220,54 @@ public class DesktopDateField extends DesktopAbstractField implements Da } } + @Override + public void setRangeStart(Date value) { + startDate = value; + } + + @Override + public Date getRangeStart() { + return startDate; + } + + @Override + public void setRangeEnd(Date value) { + endDate = value; + } + + @Override + public Date getRangeEnd() { + return endDate; + } + + private boolean checkRange(Date value) { + if (value != null) { + if (startDate != null && value.before(startDate)) { + if (getFrame() != null) { + getFrame().showNotification(messages.getMainMessage("dateField.dateOutOfRangeMessage"), + Frame.NotificationType.WARNING); + } + + datePicker.setDate((Date) prevValue); + timeField.setValue((Date) prevValue); + return false; + } + + if (endDate != null && value.after(endDate)) { + if (getFrame() != null) { + getFrame().showNotification(messages.getMainMessage("dateField.dateOutOfRangeMessage"), + Frame.NotificationType.WARNING); + } + + datePicker.setDate((Date) prevValue); + timeField.setValue((Date) prevValue); + return false; + } + } + + return true; + } + @Override public void requestFocus() { SwingUtilities.invokeLater(() -> { @@ -426,12 +484,10 @@ public class DesktopDateField extends DesktopAbstractField implements Da try { if (datasource != null && metaPropertyPath != null) { Date value = constructDate(); - if (ObjectUtils.equals(prevValue, value)) { valid = true; return; } - setValueToDs(value); } valid = true; diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/messages.properties b/modules/desktop/src/com/haulmont/cuba/desktop/messages.properties index 11dd2a6743..1e748408b1 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/messages.properties +++ b/modules/desktop/src/com/haulmont/cuba/desktop/messages.properties @@ -68,4 +68,6 @@ notification.title.TRAY_HTML = notification.title.HUMANIZED = Information notification.title.HUMANIZED_HTML = Information -sessionMessageDialog.caption = Message from administrator \ No newline at end of file +sessionMessageDialog.caption = Message from administrator + +dateField.dateOutOfRangeMessage = Date out of range \ No newline at end of file diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/messages_ru.properties b/modules/desktop/src/com/haulmont/cuba/desktop/messages_ru.properties index 0040fcd72c..7576f9de88 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/messages_ru.properties +++ b/modules/desktop/src/com/haulmont/cuba/desktop/messages_ru.properties @@ -67,4 +67,5 @@ notification.title.TRAY_HTML = notification.title.HUMANIZED = Информация notification.title.HUMANIZED_HTML = Информация -sessionMessageDialog.caption = Сообщение от администратора \ No newline at end of file +sessionMessageDialog.caption = Сообщение от администратора +dateField.dateOutOfRangeMessage = Выбранная дата находится за пределами допустимых значений \ No newline at end of file diff --git a/modules/gui/src/com/haulmont/cuba/gui/components/DateField.java b/modules/gui/src/com/haulmont/cuba/gui/components/DateField.java index 25a6f18696..642f56fc0c 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/components/DateField.java +++ b/modules/gui/src/com/haulmont/cuba/gui/components/DateField.java @@ -42,6 +42,12 @@ public interface DateField extends Field { TimeZone getTimeZone(); void setTimeZone(TimeZone timeZone); + void setRangeStart(Date value); + Date getRangeStart(); + + void setRangeEnd(Date value); + Date getRangeEnd(); + @SuppressWarnings("unchecked") @Override Date getValue(); diff --git a/modules/gui/src/com/haulmont/cuba/gui/window.xsd b/modules/gui/src/com/haulmont/cuba/gui/window.xsd index 5dd9e8cd42..58f0085184 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/window.xsd +++ b/modules/gui/src/com/haulmont/cuba/gui/window.xsd @@ -776,6 +776,10 @@ + + + + diff --git a/modules/gui/src/com/haulmont/cuba/gui/xml/layout/loaders/DateFieldLoader.java b/modules/gui/src/com/haulmont/cuba/gui/xml/layout/loaders/DateFieldLoader.java index c9bdc170f1..c3fc5de35d 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/xml/layout/loaders/DateFieldLoader.java +++ b/modules/gui/src/com/haulmont/cuba/gui/xml/layout/loaders/DateFieldLoader.java @@ -18,12 +18,19 @@ package com.haulmont.cuba.gui.xml.layout.loaders; import com.haulmont.chile.core.datatypes.Datatypes; import com.haulmont.chile.core.datatypes.impl.DateDatatype; +import com.haulmont.cuba.gui.GuiDevelopmentException; import com.haulmont.cuba.gui.components.DateField; import org.apache.commons.lang.StringUtils; import javax.persistence.TemporalType; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; public class DateFieldLoader extends AbstractFieldLoader { + protected static final String DATE_PATTERN_DAY = "yyyy-MM-dd"; + protected static final String DATE_PATTERN_MIN = "yyyy-MM-dd hh:mm"; + @Override public void createComponent() { resultComponent = (DateField) factory.createComponent(DateField.NAME); @@ -80,5 +87,44 @@ public class DateFieldLoader extends AbstractFieldLoader { } } resultComponent.setDateFormat(formatStr); + + loadRangeStart(); + loadRangeEnd(); + } + + protected void loadRangeStart() { + String rangeStart = element.attributeValue("rangeStart"); + if (StringUtils.isNotEmpty(rangeStart)) { + try { + resultComponent.setRangeStart(parseDateOrDateTime(rangeStart)); + } catch (ParseException e) { + throw new GuiDevelopmentException( + "'rangeStart' parsing error for date picker: " + + rangeStart, context.getFullFrameId(), "DatePicker ID", resultComponent.getId()); + } + } + } + + protected void loadRangeEnd() { + String rangeEnd = element.attributeValue("rangeEnd"); + if (StringUtils.isNotEmpty(rangeEnd)) { + try { + resultComponent.setRangeEnd(parseDateOrDateTime(rangeEnd)); + } catch (ParseException e) { + throw new GuiDevelopmentException( + "'rangeEnd' parsing error for date picker: " + + rangeEnd, context.getFullFrameId(), "DatePicker ID", resultComponent.getId()); + } + } + } + + protected Date parseDateOrDateTime(String value) throws ParseException { + SimpleDateFormat rangeDF; + if (value.length() == 10) { + rangeDF = new SimpleDateFormat(DATE_PATTERN_DAY); + } else { + rangeDF = new SimpleDateFormat(DATE_PATTERN_MIN); + } + return rangeDF.parse(value); } } \ No newline at end of file diff --git a/modules/web/src/com/haulmont/cuba/web/gui/components/WebDateField.java b/modules/web/src/com/haulmont/cuba/web/gui/components/WebDateField.java index 5fec2e7fd6..f12cf8b5e3 100644 --- a/modules/web/src/com/haulmont/cuba/web/gui/components/WebDateField.java +++ b/modules/web/src/com/haulmont/cuba/web/gui/components/WebDateField.java @@ -22,10 +22,7 @@ import com.haulmont.chile.core.model.MetaClass; import com.haulmont.chile.core.model.utils.InstanceUtils; import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.entity.annotation.IgnoreUserTimeZone; -import com.haulmont.cuba.core.global.AppBeans; -import com.haulmont.cuba.core.global.MessageTools; -import com.haulmont.cuba.core.global.TimeZones; -import com.haulmont.cuba.core.global.UserSessionSource; +import com.haulmont.cuba.core.global.*; import com.haulmont.cuba.gui.TestIdManager; import com.haulmont.cuba.gui.components.*; import com.haulmont.cuba.gui.data.Datasource; @@ -70,6 +67,8 @@ public class WebDateField extends WebAbstractField impleme protected Datasource.ItemPropertyChangeListener itemPropertyChangeListener; protected Datasource.ItemChangeListener itemChangeListener; + protected Messages messages; + public WebDateField() { innerLayout = new HorizontalLayout(); innerLayout.setSpacing(true); @@ -97,10 +96,16 @@ public class WebDateField extends WebAbstractField impleme setResolution(Resolution.MIN); component = new CubaDateFieldWrapper(this, innerLayout); + + messages = AppBeans.get(Messages.NAME); } protected Property.ValueChangeListener createDateValueChangeListener() { return e -> { + if (!checkRange(constructDate())) { + return; + } + updateInstance(); if (component != null) { @@ -111,7 +116,13 @@ public class WebDateField extends WebAbstractField impleme } protected Component.ValueChangeListener createTimeValueChangeListener() { - return event -> updateInstance(); + return event -> { + if (!checkRange(constructDate())) { + return; + } + + updateInstance(); + }; } public CubaDateField getDateField() { @@ -134,6 +145,54 @@ public class WebDateField extends WebAbstractField impleme updateLayout(); } + @Override + public void setRangeStart(Date value) { + dateField.setRangeStart(value); + } + + @Override + public Date getRangeStart() { + return dateField.getRangeStart(); + } + + @Override + public void setRangeEnd(Date value) { + dateField.setRangeEnd(value); + } + + @Override + public Date getRangeEnd() { + return dateField.getRangeEnd(); + } + + private boolean checkRange(Date value) { + if (value != null) { + if (dateField.getRangeStart() != null && value.before(dateField.getRangeStart())) { + if (getFrame() != null) { + getFrame().showNotification(messages.getMainMessage("datePicker.dateOutOfRangeMessage"), + Frame.NotificationType.WARNING); + } + + dateField.setValue((Date) prevValue); + timeField.setValue((Date) prevValue); + return false; + } + + if (dateField.getRangeEnd() != null && value.after(dateField.getRangeEnd())) { + if (getFrame() != null) { + getFrame().showNotification(messages.getMainMessage("datePicker.dateOutOfRangeMessage"), + Frame.NotificationType.WARNING); + } + + dateField.setValue((Date) prevValue); + timeField.setValue((Date) prevValue); + return false; + } + } + + return true; + } + @Override public String getDateFormat() { return dateTimeFormat; @@ -281,8 +340,9 @@ public class WebDateField extends WebAbstractField impleme updatingInstance = true; try { - Date value = constructDate(); if (datasource != null && metaPropertyPath != null) { + Date value = constructDate(); + if (datasource.getItem() != null) { InstanceUtils.setValueEx(datasource.getItem(), metaPropertyPath.getPath(), value); }