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;
+               }
+       }
 }
_______________________________________________
nebula-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/nebula-dev

Reply via email to