Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[nebula-dev] CDateTime enhancements

All -

First, thanks for all the work on these nebula controls. I love them and have been transitioning to them when possible in our application.

I have two items of concern with the CDateTime control:

1. Using the arrow keys, hours do no transition properly around Daylight Savings Time epochs (fall back doesn't fall back thru the two 1 AMs)
2. Users are unable to alter the time zone within the control

I have solved the first problem by introducing a fieldRoll() method to use in place of the fieldSet() method when arrow keys are being used (fieldSet() is still used when a user types in a value)

I have solved the second problem by introducing a setPattern( String pattern, TimeZone[] allowedTimeZones ) method.
* This sets a field (allowedTimeZones), which is then used to make the decision (null or not null) whether to allow the user to tab into the time zone field
* The allowedTimeZones field is then used to roll thru timezones when arrow keys are used on the time zone field

I have attached a patch for those that want to take a look -- it is pretty straightforward for the most part. More importantly, I am interested in hearing if this is something that might be included so I can decide whether to branch out my own control for my work.



thanks
scott





__________ Information from ESET NOD32 Antivirus, version of virus signature database 6851 (20120202) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

### Eclipse Workspace Patch 1.0
#P org.eclipse.nebula.widgets.cdatetime
Index: src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java
===================================================================
RCS file: /cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.nebula.widgets.cdatetime/src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java,v
retrieving revision 1.33
diff -u -r1.33 CDateTime.java
--- src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java	12 Dec 2011 21:39:32 -0000	1.33
+++ src/org/eclipse/nebula/widgets/cdatetime/CDateTime.java	2 Feb 2012 23:27:11 -0000
@@ -318,6 +318,8 @@
 
 	VPanel pickerPanel;
 
+	private TimeZone[] allowedTimezones;
+
 	/**
 	 * Constructs a new instance of this class given its parent and a style value 
 	 * describing its behavior and appearance.  The current date and the system's
@@ -563,15 +565,23 @@
 		} else {
 			int cf = getCalendarField();
 			if(cf >= 0) {
-				fieldSet(cf, calendar.get(cf) + amount, WRAP);
+				fieldRoll(cf, amount, WRAP);
 			}
 		}
 	}
 
 	void fieldFirst() {
-		if(Calendar.ZONE_OFFSET == getCalendarField(field[0])) {
-			setActiveField(1);
+		// If the user has opted to have the user be able to
+		// change time zones then allow the next field to be the
+		// time zone field
+		if (this.allowedTimezones == null) {
+			if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) {
+				setActiveField(1);
+			} else {
+				setActiveField(0);
+			}
 		} else {
+			// allowed time zones have been set, so let the user edit it
 			setActiveField(0);
 		}
 	}
@@ -594,10 +604,19 @@
 				aci.setIndex(sel.x);
 				oa = aci.getAttributes().keySet().toArray();
 			}
-			if(oa.length > 0) {
-				for(int i = 0; i < field.length; i++) {
-					if(oa[0].equals(field[i])) {
-						if(Calendar.ZONE_OFFSET != getCalendarField(field[i])) {
+			if (oa.length > 0) {
+				for (int i = 0; i < field.length; i++) {
+					if (oa[0].equals(field[i])) {
+						// If the user has opted to have the user be able to
+						// change time zones then allow the next field to be the
+						// time zone field
+						if (this.allowedTimezones == null) {
+							if (Calendar.ZONE_OFFSET != getCalendarField(field[i])) {
+								setActiveField(i);
+							}
+						} else {
+							// allowed time zones have been set, so let the user
+							// edit it
 							setActiveField(i);
 						}
 						break;
@@ -609,10 +628,17 @@
 	}
 	
 	void fieldLast() {
-		if(Calendar.ZONE_OFFSET == getCalendarField(field[field.length-1])) {
-			setActiveField(field.length-2);
+		// If the user has opted to have the user be able to change
+		// time zones then allow the next field to be the time zone field
+		if (this.allowedTimezones == null) {
+			if (Calendar.ZONE_OFFSET == getCalendarField(field[field.length - 1])) {
+				setActiveField(field.length - 2);
+			} else {
+				setActiveField(field.length - 1);
+			}
 		} else {
-			setActiveField(field.length-1);
+			// allowed time zones have been set, so let the user edit it
+			setActiveField(field.length - 1);
 		}
 	}
 	
@@ -630,20 +656,34 @@
 	 * @param If true, the text update will be asynchronous (for changes to text selection)
 	 */
 	void fieldNext(boolean async) {
-		if(activeField >= 0 && activeField < field.length - 1) {
-			if(Calendar.ZONE_OFFSET == getCalendarField(field[activeField + 1])) {
-				if(activeField < field.length - 2) {
-					setActiveField(activeField + 2);
+		if (activeField >= 0 && activeField < field.length - 1) {
+			// If the user has opted to have the user be able to change
+			// time zones then allow the next field to be the time zone field
+			if (this.allowedTimezones == null) {
+				if (Calendar.ZONE_OFFSET == getCalendarField(field[activeField + 1])) {
+					if (activeField < field.length - 2) {
+						setActiveField(activeField + 2);
+					} else {
+						setActiveField(0);
+					}
 				} else {
-					setActiveField(0);
+					setActiveField(activeField + 1);
 				}
 			} else {
+				// allowed time zones have been set, so let the user edit it
 				setActiveField(activeField + 1);
 			}
 		} else {
-			if(Calendar.ZONE_OFFSET == getCalendarField(field[0])) {
-				setActiveField(1);
+			// If the user has opted to have the user be able to change
+			// time zones then allow the next field to be the time zone field
+			if (this.allowedTimezones == null) {
+				if (Calendar.ZONE_OFFSET == getCalendarField(field[0])) {
+					setActiveField(1);
+				} else {
+					setActiveField(0);
+				}
 			} else {
+				// allowed time zones have been set, so let the user edit it
 				setActiveField(0);
 			}
 		}
@@ -664,26 +704,82 @@
 	 * @param If true, the text update will be asynchronous (for changes to text selection)
 	 */
 	void fieldPrev(boolean async) {
-		if(activeField > 0 && activeField < field.length) {
-			if(Calendar.ZONE_OFFSET == getCalendarField(field[activeField - 1])) {
-				if(activeField > 1) {
-					setActiveField(activeField - 2);
+		if (activeField > 0 && activeField < field.length) {
+			// If the user has opted to have the user be able to change
+			// time zones then allow the next field to be the time zone field
+			if (this.allowedTimezones == null) {
+				if (Calendar.ZONE_OFFSET == getCalendarField(field[activeField - 1])) {
+					if (activeField > 1) {
+						setActiveField(activeField - 2);
+					} else {
+						setActiveField(field.length - 1);
+					}
 				} else {
-					setActiveField(field.length - 1);
+					setActiveField(activeField - 1);
 				}
 			} else {
+				// allowed time zones have been set, so let the user edit it
 				setActiveField(activeField - 1);
 			}
 		} else {
-			if(Calendar.ZONE_OFFSET == getCalendarField(field[field.length - 1])) {
-				setActiveField(field.length - 2);
+			// If the user has opted to have the user be able to change
+			// time zones then allow the next field to be the time zone field
+			if (this.allowedTimezones == null) {
+
+				if (Calendar.ZONE_OFFSET == getCalendarField(field[field.length - 1])) {
+					setActiveField(field.length - 2);
+				} else {
+					setActiveField(field.length - 1);
+				}
 			} else {
+				// allowed time zones have been set, so let the user edit it
 				setActiveField(field.length - 1);
 			}
 		}
 		updateText(async);
 	}
-	
+
+	private boolean fieldRoll(final int calendarField, final int rollAmount,
+			final int style) {
+		if (!getEditable()) {
+			return false;
+		}
+
+		if (calendarField == Calendar.ZONE_OFFSET && this.allowedTimezones != null ) {
+			for( int idx=0; idx<this.allowedTimezones.length; idx++ ) {
+				TimeZone activeTimeZone = this.getTimeZone();
+				if( activeTimeZone.getID() == this.allowedTimezones[idx].getID() ) {
+					if( rollAmount < 0 ) {
+						if( idx == 0 ) {
+							this.setTimeZone( this.allowedTimezones[this.allowedTimezones.length - 1] );
+						} else {
+							this.setTimeZone( this.allowedTimezones[idx-1] );
+						}
+					} else if( rollAmount > 0 ) {
+						if( idx == this.allowedTimezones.length - 1 ) {
+							this.setTimeZone( this.allowedTimezones[0] );
+						} else {
+							this.setTimeZone( this.allowedTimezones[idx+1] );
+						}
+					}
+					System.out.println("Rolling to new timezone: " + this.timezone.getID());
+					break;
+				}
+			}
+		} else {
+			calendar.roll(calendarField, rollAmount);
+		}
+
+		if (selection.length > 0) {
+			selection[0] = calendar.getTime();
+		}
+		updateText();
+		updatePicker();
+		fireSelectionChanged(calendarField);
+
+		return true;
+	}
+
 	/**
 	 * Sets the given calendar field to the given value.<br>
 	 * <b>NOTE:</b> This is NOT the active field but a field in the
@@ -988,6 +1084,8 @@
 	 * @param event the event
 	 */
 	void handleTraverse(Event event) {
+		boolean allowTimeZoneEdit = this.allowedTimezones != null;
+
 		switch (event.detail) {
 		case SWT.TRAVERSE_ARROW_NEXT:
 			if(event.keyCode == SWT.ARROW_RIGHT) {
@@ -1008,9 +1106,14 @@
 			fireSelectionChanged();
 			break;
 		case SWT.TRAVERSE_TAB_NEXT:
-			if(tabStops && hasSelection()) {
-				if(activeField == field.length - 1
-						|| (activeField == field.length - 2 && Calendar.ZONE_OFFSET == getCalendarField(field[field.length - 1]))) {
+			if (tabStops && hasSelection()) {
+				// if we are at the last field, allow the tab out of the control
+				// the last field is also considered to be the 2nd to last if
+				// the last is a time zone
+				// we now check if the control allows time zone editing
+				if (activeField == field.length - 1
+						|| ((activeField == field.length - 2)
+								&& (Calendar.ZONE_OFFSET == getCalendarField(field[field.length - 1])) && (!allowTimeZoneEdit))) {
 					event.doit = true;
 				} else {
 					event.doit = false;
@@ -1023,8 +1126,13 @@
 			}
 			break;
 		case SWT.TRAVERSE_TAB_PREVIOUS:
-			if(tabStops && hasSelection()) {
-				if(activeField == 0 || (activeField == 1 && Calendar.ZONE_OFFSET == getCalendarField(field[0]))) {
+			if (tabStops && hasSelection()) {
+				// if we are at the 1st field, allow the tab out of the control
+				// the 1st field is also considered to the the 2nd if the 1st
+				// is a time zone
+				if (activeField == 0
+						|| ((activeField == 1)
+								&& (Calendar.ZONE_OFFSET == getCalendarField(field[0])) && (!allowTimeZoneEdit))) {
 					event.doit = true;
 				} else {
 					event.doit = false;
@@ -1407,6 +1515,7 @@
 	 * @see #setFormat(int)
 	 */
 	public void setPattern(String pattern) throws IllegalArgumentException {
+		this.allowedTimezones = null;
 		if(isOpen()) {
 			setOpen(false);
 		}
@@ -1428,6 +1537,7 @@
 				case Calendar.MILLISECOND:
 				case Calendar.MINUTE:
 				case Calendar.SECOND:
+				case Calendar.ZONE_OFFSET:
 					isTime = true;
 					break;
 				case Calendar.DAY_OF_MONTH:
@@ -1773,4 +1883,16 @@
 		updateText();
 	}
 	
+	/**
+	 * @param pattern
+	 * @param allowedTimeZones
+	 * @throws IllegalArgumentException
+	 */
+	public void setPattern(final String pattern,
+			final TimeZone[] allowedTimeZones) throws IllegalArgumentException {
+		this.setPattern(pattern);
+		if (pattern.indexOf('z') != -1) {
+			this.allowedTimezones = allowedTimeZones;
+		}
+	}
 }

Back to the top