Hello,

I'am using the CalendarCombo widget and I have a bug with it and I have a solution to correct this problem. (See the attached file).

The bug is the following. If I select in the calendar popup 'Today', then 'None', then 'Today', I have the following exception (I added a "try ... catch" to see this exception) :
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
   at java.lang.String.<init>(String.java:202)
   at org.eclipse.swt.internal.win32.TCHAR.toString(TCHAR.java:115)
   at org.eclipse.swt.widgets.Combo.getText(Combo.java:846)
at org.eclipse.nebula.widgets.calendarcombo.CalendarCombo.setText(CalendarCombo.java:1127) at org.eclipse.nebula.widgets.calendarcombo.CalendarCombo.updateDate(CalendarCombo.java:1566) at org.eclipse.nebula.widgets.calendarcombo.CalendarCombo.access$20(CalendarCombo.java:1565) at org.eclipse.nebula.widgets.calendarcombo.CalendarCombo$17.dateChanged(CalendarCombo.java:1461) at org.eclipse.nebula.widgets.calendarcombo.CalendarComposite.notifyListeners(CalendarComposite.java:732) at org.eclipse.nebula.widgets.calendarcombo.CalendarComposite.notifyListeners(CalendarComposite.java:745) at org.eclipse.nebula.widgets.calendarcombo.CalendarComposite.clickedTodayButton(CalendarComposite.java:214) at org.eclipse.nebula.widgets.calendarcombo.CalendarComposite.externalClick(CalendarComposite.java:770) at org.eclipse.nebula.widgets.calendarcombo.CalendarCombo$9.handleEvent(CalendarCombo.java:839)

I have this exception because in the class 'CalendarCombo' the method 'Combo.setText(String )' is used to set the text in the Combo. I think that the method 'Combo.add(...)' (like in the method 'CalendarCombosetText(...)') must be always used to set the text. In attached file, there is the CalendarCombo with a solution : add a method 'setComboText(String )' to set the text for the Combo (flat or not) and I am using only this method in the CalendarCombo class.

Jérôme

/*******************************************************************************
 * Copyright (c) Emil Crumhorn - Hexapixel.com - [email protected]
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    [email protected] - initial API and implementation
 
*******************************************************************************/

package org.eclipse.nebula.widgets.calendarcombo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.DragDetectListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Widget;

/**
 * <b>CalendarCombo - SWT Widget - 2005-2008. Version 1.0. &copy; Emil Crumhorn
 * - emil dot crumhorn at gmail dot com.</b>
 * <p>
 * <b>Website</b><br>
 * If you want more info or more documentation, please visit: <a
 * href="http://www.hexapixel.com/";>http://www.hexapixel.com</a>
 * <p>
 * <b>Description</b><br>
 * CalendarCombo is a widget that opens a calendar when dropped down. The
 * calendar is modelled after Microsoft Outlook's calendar widget and acts and
 * behaves exactly the same (and it is also theme based). The combo is not based
 * on CCombo (as many other custom implementations), but is instead attached to
 * the native Combo box.
 * <p>
 * <b>Example Creation Code</b><br>
 * <code>
 * CalendarCombo cCombo = new CalendarCombo(parentControl, SWT.READ_ONLY);<br>
 * ...<br>
 * </code>
 * <p>
 * <b>Another example using depending combos and date range selection on the
 * first combo</b><br>
 * <code>
 * CalendarCombo cComboStart = new CalendarCombo(parentControl, SWT.READ_ONLY, 
true);<br>
 * CalendarCombo cComboEnd = new CalendarCombo(parentControl, 
SWT.READ_ONLY);<br>
 * cComboStart.setDependingCombo(cComboEnd);<br>
 * </code> <br>
 * This will cause the end date for the date range selection to be populated in
 * the cComboEnd combo.
 * <p>
 * <b>Customizing</b><br>
 * There are two interfaces that are of importance for customizing, one is
 * IColorManager and the other is ISettings. Let's start with the IColorManager.
 * <p>
 * <b>IColorManager</b><br>
 * If you don't specify a color manager, the DefaultColorManager will be used.
 * The color manager's job is to return colors to the method that is painting
 * all the actual days and months etc. The colors that are returned from the
 * ColorManager will determine everything as far as looks go.
 * <p>
 * <b>ISettings</b><br>
 * To control the spacing between dates, various formats and text values, you
 * will want to implement the ISettings interface. If you don't specify one,
 * DefaultSettings will be used.
 * 
 * @author Emil Crumhorn
 * @version 1.1.2008.11.25
 * 
 */
public class CalendarCombo extends Composite {

        // the main combo box
        private Combo                                   mCombo;
        private FlatCalendarCombo               mFlatCombo;

        private Composite                               mComboControl;

        private int                                             mComboStyle     
                = SWT.NONE;

        // the shell holding the CalendarComposite
        private Shell                                   mCalendarShell;

        private Listener                                mKillListener;

        private Listener                                mFilterListenerFocusIn;

        private Composite                               mParentComposite;

        // values for determining when the last view of the mCalendarShell was.
        // this is to determine how quick clicks should behave
        private long                                    mLastShowRequest        
= 0;

        private long                                    mLastKillRequest        
= 0;

        private boolean                                 mAllowTextEntry;

        private CalendarCombo                   mDependingCombo;

        private CalendarComposite               mCalendarComposite;

        private Calendar                                mStartDate;

        private Calendar                                mEndDate;

        private IColorManager                   mColorManager;

        private ISettings                               mSettings;

        private ArrayList                               mListeners;

        private Calendar                                mDisallowBeforeDate;

        private Calendar                                mDisallowAfterDate;

        private boolean                                 isReadOnly;

        private boolean                                 isFlat;

        private int                                             
arrowButtonWidth;

        private boolean                                 mAllowDateRange;

        private Calendar                                mCarbonPrePopupDate;

        private Listener                                mKeyDownListener;

        private boolean                                 mParsingDate;

        private int                                             mLastFireTime;

        private Calendar                                mLastNotificationDate;

        private Listener                                mOobClickListener;

        protected static final boolean  OS_CARBON                       = 
"carbon".equals(SWT.getPlatform());
        protected static final boolean  OS_GTK                          = 
"gtk".equals(SWT.getPlatform());
        protected static final boolean  OS_WINDOWS                      = 
"win32".equals(SWT.getPlatform());

        /*
         * // Windows JNI Code for making a non-activated canvas, for reference 
if
         * searching MSDN int extStyle = OS.GetWindowLong(canvas.handle,
         * OS.GWL_EXSTYLE); extStyle = extStyle | 0x80000;
         * OS.SetWindowLong(canvas.handle, OS.GWL_EXSTYLE, extStyle); 
0x008000000 =
         * WS_EX_NOACTIVATE;
         */

        /**
         * Creates a new calendar combo box with the given style.
         * 
         * @param parent
         *            Parent control
         * @param style
         *            Combo style
         */
        public CalendarCombo(Composite parent, int style) {
                super(parent, checkStyle(style));
                this.mComboStyle = style;
                this.mParentComposite = parent;
                init();
        }

        /**
         * Creates a new calendar combo box with the given style.
         * 
         * @param parent
         *            Parent control
         * @param style
         *            Combo style
         * @param allowDateRange
         *            Whether to allow date range selection (note that if there 
is
         *            no depending CalendarCombo set you will have to deal with 
the
         *            date range event yourself).
         */
        public CalendarCombo(Composite parent, int style, boolean 
allowDateRange) {
                super(parent, checkStyle(style));
                this.mComboStyle = style;
                this.mParentComposite = parent;
                this.mAllowDateRange = allowDateRange;
                init();
        }

        /**
         * Creates a new calendar mCombo box with the given style, ISettings and
         * IColorManager implementations.
         * 
         * @param parent
         *            Parent control
         * @param style
         *            Combo style
         * @param settings
         *            ISettings implementation
         * @param colorManager
         *            IColorManager implementation
         */
        public CalendarCombo(Composite parent, int style, ISettings settings, 
IColorManager colorManager) {
                super(parent, checkStyle(style));
                this.mComboStyle = style;
                this.mParentComposite = parent;
                this.mSettings = settings;
                this.mColorManager = colorManager;
                init();
        }

        /**
         * Creates a new calendar mCombo box with the given style, ISettings and
         * IColorManager implementations.
         * 
         * @param parent
         *            Parent control
         * @param style
         *            Combo style
         * @param settings
         *            ISettings implementation
         * @param colorManager
         *            IColorManager implementation
         * @param allowDateRange
         *            Whether to allow date range selection (note that if there 
is
         *            no depending CalendarCombo set you will have to deal with 
the
         *            date range event yourself).
         */
        public CalendarCombo(Composite parent, int style, ISettings settings, 
IColorManager colorManager, boolean allowDateRange) {
                super(parent, checkStyle(style));
                this.mComboStyle = style;
                this.mParentComposite = parent;
                this.mSettings = settings;
                this.mColorManager = colorManager;
                this.mAllowDateRange = allowDateRange;
                init();
        }

        /**
         * Lets you create a depending CalendarCombo box, which, when no dates 
are
         * set on the current one will set the starting date when popped up to 
be
         * the date of the pullDateFrom CalendarCombo, should that box have a 
date
         * set in it.
         * 
         * @param parent
         * @param style
         * @param dependingCombo
         *            CalendarCombo from where start date is pulled when no 
date has
         *            been set locally.
         */
        public CalendarCombo(Composite parent, int style, CalendarCombo 
dependingCombo) {
                super(parent, checkStyle(style));
                this.mParentComposite = parent;
                this.mDependingCombo = dependingCombo;
                this.mComboStyle = style;
                init();
        }

        /**
         * Lets you create a depending CalendarCombo box, which, when no dates 
are
         * set on the current one will set the starting date when popped up to 
be
         * the date of the pullDateFrom CalendarCombo, should that box have a 
date
         * set in it.
         * 
         * When the depending combo is set and the allowDateRange flag is true, 
the
         * depending combo will be the recipient of the end date of any date 
range
         * selection.
         * 
         * @param parent
         * @param style
         * @param dependingCombo
         *            CalendarCombo from where start date is pulled when no 
date has
         *            been set locally.
         * @param allowDateRange
         *            Whether to allow date range selection
         */
        public CalendarCombo(Composite parent, int style, CalendarCombo 
dependingCombo, boolean allowDateRange) {
                super(parent, checkStyle(style));
                this.mParentComposite = parent;
                this.mDependingCombo = dependingCombo;
                this.mComboStyle = style;
                this.mAllowDateRange = allowDateRange;
                init();
        }

        /**
         * Lets you create a depending CalendarCombo box, which, when no dates 
are
         * set on the current one will set the starting date when popped up to 
be
         * the date of the pullDateFrom CalendarCombo, should that box have a 
date
         * set in it.
         * 
         * @param parent
         * @param style
         * @param dependingCombo
         *            CalendarCombo from where start date is pulled when no 
date has
         *            been set locally.
         * @param settings
         *            ISettings implementation
         * @param colorManager
         *            IColorManager implementation
         */
        public CalendarCombo(Composite parent, int style, CalendarCombo 
dependingCombo, ISettings settings, IColorManager colorManager) {
                super(parent, checkStyle(style));
                this.mParentComposite = parent;
                this.mDependingCombo = dependingCombo;
                this.mComboStyle = style;
                this.mSettings = settings;
                this.mColorManager = colorManager;
                init();
        }

        /**
         * Lets you create a depending CalendarCombo box, which, when no dates 
are
         * set on the current one will set the starting date when popped up to 
be
         * the date of the pullDateFrom CalendarCombo, should that box have a 
date
         * set in it.
         * 
         * When the depending combo is set and the allowDateRange flag is true, 
the
         * depending combo will be the recipient of the end date of any date 
range
         * selection.
         * 
         * @param parent
         * @param style
         * @param dependingCombo
         *            CalendarCombo from where start date is pulled when no 
date has
         *            been set locally.
         * @param settings
         *            ISettings implementation
         * @param colorManager
         *            IColorManager implementation
         * @param allowDateRange
         *            Whether to allow date range selection
         */
        public CalendarCombo(Composite parent, int style, CalendarCombo 
dependingCombo, ISettings settings, IColorManager colorManager, boolean 
allowDateRange) {
                super(parent, checkStyle(style));
                this.mParentComposite = parent;
                this.mDependingCombo = dependingCombo;
                this.mComboStyle = style;
                this.mSettings = settings;
                this.mColorManager = colorManager;
                init();
        }

        // remove styles we don't allow
        private static int checkStyle(int style) {
                int mask = SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.MULTI 
| SWT.NO_FOCUS | SWT.CHECK | SWT.VIRTUAL | SWT.FLAT;

                int newStyle = style & mask;
                return newStyle;
        }

        // lay out everything and add all our listeners
        private void init() {
                isReadOnly = ((mComboStyle & SWT.READ_ONLY) != 0);
                isFlat = ((mComboStyle & SWT.FLAT) != 0);

                mListeners = new ArrayList();

                // if click happens on a control that is not us, we kill
                mOobClickListener = new Listener() {
                        public void handleEvent(Event event) {
                                if (!isCalendarVisible())
                                        return;

                                if (Display.getDefault().getCursorControl() != 
mCalendarComposite) {
                                        kill(44);
                                }

                        }
                };

                if (mColorManager == null)
                        mColorManager = new DefaultColorManager();

                if (mSettings == null)
                        mSettings = new DefaultSettings();

                arrowButtonWidth = mSettings.getWindowsButtonWidth();
                if (OS_CARBON)
                        arrowButtonWidth = mSettings.getCarbonButtonWidth();
                else if (OS_GTK)
                        arrowButtonWidth = mSettings.getGTKButtonWidth();

                GridLayout gl = new GridLayout();
                gl.horizontalSpacing = 0;
                gl.verticalSpacing = 0;
                gl.marginWidth = 0;
                gl.marginHeight = 0;
                setLayout(gl);

                if (isFlat) {
                        mFlatCombo = new FlatCalendarCombo(this, this, 
mComboStyle | SWT.FLAT);
                        mFlatCombo.setVisibleItemCount(0);
                        mFlatCombo.setLayoutData(new GridData(SWT.FILL, 
SWT.BEGINNING, true, false));
                        mComboControl = mFlatCombo;
                }
                else {
                        mCombo = new Combo(this, mComboStyle);
                        mCombo.setVisibleItemCount(0);
                        mCombo.setLayoutData(new GridData(SWT.FILL, 
SWT.BEGINNING, true, false));
                        mComboControl = mCombo;
                }

                // when a user types in a date we parse it when they traverse 
away in
                // any sense or form (focus lost etc)
                if (!isReadOnly) {
                        Listener traverseListener = new Listener() {
                                public void handleEvent(Event event) {
                                        if (event.detail == 16 || event.detail 
== 8 || event.detail == 4 || event.detail == 0) {
                                                parseTextDate();
                                        }
                                }
                        };

                        // deal with traverse-away/in/return events to parse 
dates
                        mComboControl.addListener(SWT.Traverse, 
traverseListener);
                        mComboControl.addListener(SWT.FocusOut, 
traverseListener);

                        mKeyDownListener = new Listener() {
                                public void handleEvent(Event event) {
                                        // if event didn't happen on this 
combo, ignore it
                                        if (isFlat) {
                                                if (event.widget != 
mFlatCombo.getTextControl())
                                                        return;
                                        }
                                        else {
                                                if (event.widget != mCombo) {
                                                        return;
                                                }
                                        }

                                        if 
(mSettings.keyboardNavigatesCalendar()) {

                                                if (event.keyCode == 
SWT.ARROW_DOWN) {
                                                        Control ctrl = (isFlat 
? (Control) mFlatCombo.getTextControl() : mCombo);

                                                        if 
(Display.getDefault().getFocusControl() == ctrl) {
                                                                if 
(!isCalendarVisible())
                                                                        
showCalendar();
                                                                else {
                                                                        
mCalendarComposite.keyPressed(event.keyCode, event.stateMask);
                                                                        
event.doit = false;
                                                                }
                                                        }
                                                }
                                                else {
                                                        if 
(isCalendarVisible()) {
                                                                
mCalendarComposite.keyPressed(event.keyCode, event.stateMask);
                                                                // eat event or 
cursor will jump around in combo
                                                                // as well
                                                                event.doit = 
false;
                                                        }
                                                }
                                        }
                                        else {
                                                boolean acceptedEvent = 
(event.keyCode == SWT.ARROW_DOWN || event.keyCode == SWT.ARROW_UP);
                                                if (OS_CARBON) {
                                                        acceptedEvent = 
(event.character == mSettings.getCarbonArrowDownChar() || event.character == 
mSettings.getCarbonArrowUpChar());
                                                }

                                                if (acceptedEvent) {
                                                        boolean up = 
event.keyCode == SWT.ARROW_UP;
                                                        if (OS_CARBON)
                                                                up = 
event.character == mSettings.getCarbonArrowUpChar();

                                                        int cursorLoc = isFlat 
? mFlatCombo.getSelection().x : mCombo.getSelection().x;
                                                        // first, parse the 
date, we don't care if it's some
                                                        // fantastic format we 
can parse, parse it again
                                                        parseTextDate();
                                                        // once it's parsed, 
set it to the default format,
                                                        // that way we KNOW 
where certain parts of the date
                                                        // are
                                                        if (mStartDate != null) 
{
                                                                
setComboText(DateHelper.getDate(mStartDate, mSettings.getDateFormat()));

                                                                String df = 
mSettings.getDateFormat();

                                                                event.doit = 
false;
                                                                if (isFlat)
                                                                        
mFlatCombo.setSelection(new Point(cursorLoc, cursorLoc));
                                                                else
                                                                        
mCombo.setSelection(new Point(cursorLoc, cursorLoc));

                                                                // split the 
date format. we do this as a date
                                                                // format of 
M/d/yyyy for example can still have
                                                                // 2 digits as 
M or d .
                                                                String 
separatorChar = null;
                                                                char[] accepted 
= mSettings.getAcceptedDateSeparatorChars();
                                                                for (int i = 0; 
i < accepted.length; i++) {
                                                                        if 
(df.indexOf(String.valueOf(accepted[i])) > -1) {
                                                                                
separatorChar = String.valueOf(accepted[i]);
                                                                        }
                                                                }

                                                                int 
sectionStart = 0;
                                                                int sectionEnd 
= 0;

                                                                int splitCount 
= 0;

                                                                // get the 
format
                                                                String oneChar 
= "";
                                                                if 
(separatorChar != null) {
                                                                        // now 
find how many separator chars we are
                                                                        // from 
the left side of the date in the box
                                                                        // to 
where the cursor is, that will tell us
                                                                        // what 
part of
                                                                        // the 
date format we're on
                                                                        String 
comboText = isFlat ? mFlatCombo.getText() : mCombo.getText();
                                                                        for 
(int i = 0; i < comboText.length(); i++) {
                                                                                
if (i >= cursorLoc)
                                                                                
        break;

                                                                                
if (comboText.charAt(i) == separatorChar.charAt(0))
                                                                                
        splitCount++;
                                                                        }

                                                                        
StringTokenizer st = new StringTokenizer(df, separatorChar);
                                                                        int 
count = 0;
                                                                        while 
(st.hasMoreTokens()) {
                                                                                
String tok = st.nextToken();
                                                                                
if (count == splitCount) {
                                                                                
        oneChar = tok;
                                                                                
        break;
                                                                                
}
                                                                                
count++;
                                                                        }
                                                                }
                                                                else {
                                                                        oneChar 
= mSettings.getDateFormat().substring(cursorLoc, cursorLoc + 1);

                                                                        // get 
the whole part, bit tricky I suppose,
                                                                        // but
                                                                        // we 
fetch everything that matches the
                                                                        // 
format
                                                                        // at 
the position we're at, easy enough
                                                                        
StringBuffer buf = new StringBuffer();
                                                                        int 
start = cursorLoc;

                                                                        while 
(start >= 0) {
                                                                                
if (mSettings.getDateFormat().charAt(start) == oneChar.charAt(0)) {
                                                                                
        buf.append(mSettings.getDateFormat().charAt(start));
                                                                                
}
                                                                                
else {
                                                                                
        break;
                                                                                
}
                                                                                
start--;
                                                                        }
                                                                        start = 
cursorLoc + 1;
                                                                        while 
(start < mSettings.getDateFormat().length()) {
                                                                                
if (mSettings.getDateFormat().charAt(start) == oneChar.charAt(0)) {
                                                                                
        buf.append(mSettings.getDateFormat().charAt(start));
                                                                                
}
                                                                                
else {
                                                                                
        break;
                                                                                
}
                                                                                
start++;
                                                                        }

                                                                        
sectionStart = mSettings.getDateFormat().indexOf(buf.toString());
                                                                        
sectionEnd = sectionStart + buf.toString().length();
                                                                }

                                                                // now we now 
what to increase/decrease, lets do
                                                                // it
                                                                int calType = 
-1;
                                                                switch 
(oneChar.charAt(0)) {
                                                                        case 
'G':
                                                                                
calType = Calendar.ERA;
                                                                                
break;
                                                                        case 
'y':
                                                                                
calType = Calendar.YEAR;
                                                                                
break;
                                                                        case 
'M':
                                                                                
calType = Calendar.MONTH;
                                                                                
break;
                                                                        case 
'd':
                                                                                
calType = Calendar.DAY_OF_MONTH;
                                                                                
break;
                                                                        case 
'E':
                                                                                
calType = Calendar.DAY_OF_WEEK;
                                                                                
break;
                                                                        case 
'D':
                                                                                
calType = Calendar.DAY_OF_YEAR;
                                                                                
break;
                                                                        case 
'F':
                                                                                
calType = Calendar.DATE;
                                                                                
break;
                                                                        case 
'h':
                                                                                
calType = Calendar.HOUR;
                                                                                
break;
                                                                        case 
'm':
                                                                                
calType = Calendar.MINUTE;
                                                                                
break;
                                                                        case 
's':
                                                                                
calType = Calendar.SECOND;
                                                                                
break;
                                                                        case 
'S':
                                                                                
calType = Calendar.MILLISECOND;
                                                                                
break;
                                                                        case 
'w':
                                                                                
calType = Calendar.WEEK_OF_YEAR;
                                                                                
break;
                                                                        case 
'W':
                                                                                
calType = Calendar.WEEK_OF_MONTH;
                                                                                
break;
                                                                        case 
'a':
                                                                                
calType = Calendar.AM_PM;
                                                                                
break;
                                                                        case 
'k':
                                                                                
calType = Calendar.HOUR_OF_DAY;
                                                                                
break;
                                                                        case 
'K':
                                                                                
// ?
                                                                                
break;
                                                                        case 
'z':
                                                                                
calType = Calendar.ZONE_OFFSET;
                                                                                
break;
                                                                }

                                                                if (calType != 
-1) {
                                                                        
mStartDate.add(calType, up ? 1 : -1);

                                                                        String 
newDate = DateHelper.getDate(mStartDate, mSettings.getDateFormat());

                                                                        
setComboText(newDate);

                                                                        if 
(separatorChar != null) {
                                                                                
// we need to update the selection after
                                                                                
// we've set the date
                                                                                
// figure out cursor location, now we
                                                                                
// have to use the date in the box again
                                                                                
StringTokenizer st = new StringTokenizer(newDate, separatorChar);
                                                                                
int count = 0;
                                                                                
boolean stop = false;
                                                                                
while (st.hasMoreTokens()) {
                                                                                
        String tok = st.nextToken();

                                                                                
        // we found our section
                                                                                
        if (count == splitCount) {
                                                                                
                sectionEnd = sectionStart + tok.length();
                                                                                
                stop = true;
                                                                                
                break;
                                                                                
        }

                                                                                
        // if we're stopping, break out
                                                                                
        if (stop)
                                                                                
                break;

                                                                                
        // add on separator chars for each
                                                                                
        // loop iteration post 0
                                                                                
        sectionStart += 1;
                                                                                
        // and token length
                                                                                
        sectionStart += tok.length();

                                                                                
        count++;
                                                                                
}
                                                                        }

                                                                        // set 
the selection for us
                                                                        if 
(isFlat) {
                                                                                
mFlatCombo.setSelection(new Point(sectionStart, sectionEnd));
                                                                        }
                                                                        else {
                                                                                
mCombo.setSelection(new Point(sectionStart, sectionEnd));

                                                                        }

                                                                }
                                                        }
                                                }
                                        }
                                }
                        };

                        Display.getDefault().addFilter(SWT.KeyDown, 
mKeyDownListener);
                }

                if (isFlat) {
                        mComboControl.addListener(SWT.FocusOut, new Listener() {
                                public void handleEvent(Event event) {
                                        kill(98);
                                }
                        });
                }

                mComboControl.addListener(SWT.MouseDown, new Listener() {
                        public void handleEvent(Event event) {
                                // click in the text area? ignore
                                if (!isFlat) {
                                        if (isTextAreaClick(event)) {
                                                if (isCalendarVisible())
                                                        kill(16);

                                                return;
                                        }
                                }

                                // kill calendar if visible and do nothing else
                                if (isCalendarVisible()) {
                                        kill(15);
                                        return;
                                }
                                // a very small time between the close and the 
open means it was
                                // a click on the
                                // arrow down to close, and we don't open it 
again in that case.
                                // The next click will open.
                                // this is the expected behavior.
                                mLastShowRequest = 
Calendar.getInstance(mSettings.getLocale()).getTimeInMillis();

                                long diff = mLastKillRequest - mLastShowRequest;
                                if (diff > -100 && diff < 0)
                                        return;

                                showCalendar();
                        }
                });

                mKillListener = new Listener() {
                        public void handleEvent(Event event) {
                                if (event.keyCode == SWT.ESC) {
                                        kill(77);
                                        return;
                                }

                                // ignore arrow down events for killing popup
                                if (event.keyCode == SWT.ARROW_DOWN || 
event.keyCode == SWT.ARROW_UP || event.keyCode == SWT.ARROW_LEFT || 
event.keyCode == SWT.ARROW_RIGHT
                                                || event.keyCode == SWT.CR || 
event.keyCode == SWT.LF)
                                        return;

                                kill(1);
                        }
                };

                int[] comboEvents = {
                                SWT.Dispose, SWT.Move, SWT.Resize
                };
                for (int i = 0; i < comboEvents.length; i++) {
                        this.addListener(comboEvents[i], mKillListener);
                }

                int[] arrowEvents = {
                        SWT.Selection
                };
                for (int i = 0; i < arrowEvents.length; i++) {
                        mComboControl.addListener(arrowEvents[i], 
mKillListener);
                }

                mFilterListenerFocusIn = new Listener() {
                        public void handleEvent(Event event) {
                                if (OS_CARBON) {
                                        Widget widget = event.widget;
                                        if (widget instanceof CalendarComposite 
== false)
                                                kill(2);

                                        // on mac, select all text in combo if 
we are the control that gained focus
                                        if (mComboControl == 
Display.getDefault().getFocusControl()) {
                                                if (isFlat) {
                                                        
mFlatCombo.getTextControl().selectAll();
                                                }
                                                else {
                                                        mCombo.setSelection(new 
Point(0, mCombo.getText().length()));
                                                }
                                        }
                                } else {
                                        long now = 
Calendar.getInstance(mSettings.getLocale()).getTimeInMillis();
                                        long diff = now - mLastShowRequest;
                                        if (diff > 0 && diff < 100)
                                                return;

                                        if (!isCalendarVisible())
                                                return;

                                        // don't force focus, user clicked 
another control, let it grab the focus or it'll be odd behavior
                                        if (!isFlat)
                                                kill(3, true);
                                }
                        }
                };

                Shell parentShell = mParentComposite.getShell();

                if (parentShell != null) {
                        parentShell.addControlListener(new ControlListener() {
                                public void controlMoved(ControlEvent e) {
                                        kill(4);
                                }

                                public void controlResized(ControlEvent e) {
                                        kill(5);
                                }
                        });

                        parentShell.addListener(SWT.Deactivate, new Listener() {
                                public void handleEvent(Event event) {
                                        Point mouseLoc = 
Display.getDefault().getCursorLocation();

                                        // with no focus shells, buttons will 
steal focus, and cause
                                        // deactivate events when clicked
                                        // so if the deactivate came from a 
mouse being over any of
                                        // our buttons, that is the same as
                                        // if we clicked them.
                                        if (mCalendarComposite != null && 
mCalendarComposite.isDisposed() == false)
                                                
mCalendarComposite.externalClick(mouseLoc);

                                        if (!isFlat)
                                                kill(6);
                                }
                        });

                        parentShell.addFocusListener(new FocusListener() {
                                public void focusGained(FocusEvent e) {

                                }

                                public void focusLost(FocusEvent e) {
                                        kill(7);
                                }
                        });
                }

                Display.getDefault().addFilter(SWT.MouseDown, new Listener() {
                        public void handleEvent(Event event) {
                                // This may seem odd, but if the event is the 
CalendarCombo, we
                                // actually clicked outside the widget and the 
CalendarComposite
                                // area, meaning -
                                // we clicked outside our widget, so we close 
it.
                                if (event.widget instanceof CalendarCombo) {
                                        kill(8);
                                        mComboControl.setFocus();
                                }
                        }
                });

                // remove listener when mCombo is disposed
                Display.getDefault().addFilter(SWT.FocusIn, 
mFilterListenerFocusIn);
                mComboControl.addDisposeListener(new DisposeListener() {
                        public void widgetDisposed(DisposeEvent event) {
                                Display.getDefault().removeFilter(SWT.FocusIn, 
mFilterListenerFocusIn);
                                if (mKeyDownListener != null)
                                        
Display.getDefault().removeFilter(SWT.KeyDown, mKeyDownListener);

                                if (mSettings.getCarbonDrawFont() != null)
                                        mSettings.getCarbonDrawFont().dispose();

                                if (mSettings.getWindowsMonthPopupDrawFont() != 
null)
                                        
mSettings.getWindowsMonthPopupDrawFont().dispose();
                        }
                });

                // mac's editable combos behave differently
                if (OS_CARBON) {
                        // this code seems obsolete as of June 24th 2008, Allow 
text input
                        // on Mac, we parse it anyways now, which we didn't do 
prior
                        // leaving code in for a while to remind myself
                        /*
                         * mCombo.addVerifyListener(new VerifyListener() { 
public void
                         * verifyText(VerifyEvent event) { if 
(isCalendarVisible() ||
                         * mAllowTextEntry) { ; } else { event.doit = false; } 
} });
                         */

                        // this is the most messed up thing ever, but it works. 
Basically,
                        // OSX will pop up a combo of 1 item to let you pick it
                        // even when it's blantantly obvious that you can only 
pick that one
                        // item.. duh.. Anyway, the Paint event actually fires 
PRIOR to the
                        // combo
                        // opening, and our "cure" to the popup issue is to 
quickly remove
                        // the item from the combo before it does open, thus, 
it doesn't
                        // show the selector list,
                        // but our popup instead. The side effect is that the 
combo appears
                        // blank while the calendar is open. But as we reset 
the date when
                        // no selection has been made, it's all good! It ain't 
pretty, but
                        // it does the job
                        if (isReadOnly) {
                                if (isFlat) {
                                        mFlatCombo.addListener(SWT.Paint, new 
Listener() {
                                                public void handleEvent(Event 
event) {
                                                        mCarbonPrePopupDate = 
getDate();
                                                        // 
mFlatCombo.removeAll();
                                                }
                                        });
                                }
                                else {
                                        mCombo.addListener(SWT.Paint, new 
Listener() {
                                                public void handleEvent(Event 
event) {
                                                        mCarbonPrePopupDate = 
getDate();
                                                        mCombo.removeAll();

                                                }
                                        });
                                }
                        }
                }

                parentShell.addShellListener(new ShellListener() {
                        public void shellActivated(ShellEvent event) {
                        }

                        public void shellClosed(ShellEvent event) {
                                // shell killed
                                kill(9);
                        }

                        public void shellDeactivated(ShellEvent event) {
                        }

                        public void shellDeiconified(ShellEvent event) {
                        }

                        public void shellIconified(ShellEvent event) {
                                // shell no longer in focus (like.. WindowsKey 
+ M on WinXP or
                                // such)
                                kill(10);
                        }
                });

        }

        // parses the date, and really tries
        private void parseTextDate() {
                // listeners by users can cause infinite loops as we notify, 
they set on
                // notify, etc, so don't allow parsing if we haven't finished 
yet
                if (mParsingDate)
                        return;

                try {
                        mParsingDate = true;

                        String comboText = (isFlat ? mFlatCombo.getText() : 
mCombo.getText());
                        if (comboText.length() == 0) {
                                mStartDate = null;
                                setText("");
                                notifyDateChanged();
                                return;
                        }

                        try {
                                mStartDate = DateHelper.getDate(comboText, 
mSettings.getDateFormat(), mSettings.getLocale());
                                updateDate();
                                notifyDateChanged();
                                // System.err.println("Got here 1 - Settings 
parse");
                        }
                        catch (Exception err) {
                                // try the locale
                                try {
                                        mStartDate = 
DateHelper.parseDate(comboText, mSettings.getLocale());
                                        updateDate();
                                        notifyDateChanged();
                                        // System.err.println("Got here 2 - 
Locale parse");
                                }
                                catch (Exception deeper) {
                                        try {
                                                mStartDate = 
DateHelper.parseDateHard(comboText, mSettings.getLocale());
                                                updateDate();
                                                notifyDateChanged();
                                                // System.err.println("Got here 
3 - Hard parse");
                                        }
                                        catch (Exception deepest) {
                                                // System.err.println("Got here 
4 - Failed parse");
                                                List otherFormats = 
mSettings.getAdditionalDateFormats();
                                                if (otherFormats != null) {
                                                        try {
                                                                for (int i = 0; 
i < otherFormats.size(); i++) {
                                                                        try {
                                                                                
String format = (String) otherFormats.get(i);
                                                                                
Date date = DateHelper.getDate(comboText, format);
                                                                                
// success
                                                                                
setDate(date);
                                                                                
updateDate();
                                                                                
notifyDateChanged();
                                                                                
return;
                                                                        }
                                                                        catch 
(Exception failed) {
                                                                                
// keep trying
                                                                        }
                                                                }
                                                        }
                                                        catch (Exception err2) {
                                                                // don't care
                                                        }
                                                }

                                                // unparseable date, set the 
last used date if any,
                                                // otherwise set nodateset text
                                                if (mStartDate != null)
                                                        setDate(mStartDate);
                                                else {
                                                        
setComboText(mSettings.getNoDateSetText());
                                                }
                                        }
                                }
                        }
                }
                catch (Exception err) {
                        err.printStackTrace();
                }
                finally {
                        mParsingDate = false;
                }
        }

        private void notifyDateChanged() {
                // don't notify on same dates
                if (mLastNotificationDate == null && mStartDate == null)
                        return;

                if (mLastNotificationDate != null && mStartDate != null) {
                        if (DateHelper.sameDate(mLastNotificationDate, 
mStartDate))
                                return;
                }

                for (int i = 0; i < mListeners.size(); i++) {
                        try {
                                ((ICalendarListener) 
mListeners.get(i)).dateChanged(mStartDate);
                        }
                        catch (Exception err) {
                                err.printStackTrace();
                        }
                }
        }

        // checks whether a click was actually in the text area of a combo and 
not
        // on the arrow button. This is a hack by all means,
        // as there is (currently) no way to get the actual button from a combo.
        private boolean isTextAreaClick(Event event) {
                // read-only combos open on click anywhere
                if (isReadOnly)
                        return false;

                Point size = isFlat ? mFlatCombo.getSize() : mCombo.getSize();
                Rectangle rect = null;

                rect = new Rectangle(0, 0, size.x - arrowButtonWidth, size.y);
                if (isInside(event.x, event.y, rect))
                        return true;

                return false;
        }

        // check whether a pixel value is inside a rectangle
        private boolean isInside(int x, int y, Rectangle rect) {
                if (rect == null)
                        return false;

                return x >= rect.x && y >= rect.y && x <= (rect.x + rect.width) 
&& y <= (rect.y + rect.height);
        }

        /**
         * Sets the current date. Date will be automatically displayed in the 
text
         * area of the combo according to the defined date format (in settings).
         * 
         * @param date
         *            Date to set
         */
        public synchronized void setDate(Date date) {
                checkWidget();
                Calendar cal = Calendar.getInstance(mSettings.getLocale());
                cal.setTime(date);
                setDate(cal);
        }

        /**
         * Sets the current date. Date will be automatically displayed in the 
text
         * area of the combo according to the defined date format (in settings).
         * 
         * @param cal
         *            Calendar to set
         */
        public synchronized void setDate(Calendar cal) {
                checkWidget();
                setText(DateHelper.getDate(cal, mSettings.getDateFormat()));
                this.mStartDate = cal;
        }

        /**
         * Sets the text in the combo area to the given value. Do note that if 
you
         * set a text that is a non-pareseable date string according to the
         * currently set date format, that string will be replaced or removed 
when
         * the user opens the popup. This is mainly for disabled combos or 
combos
         * where you need to add additional control to what's displayed in the 
text
         * area.
         * 
         * @param text
         *            Text to display
         */
        public synchronized void setText(final String text) {
                checkWidget();

                String txt = isFlat ? mFlatCombo.getText() : mCombo.getText();

                if (txt.equals(text))
                        return;

                mAllowTextEntry = true;
                setComboText(text);
                mAllowTextEntry = false;
        }

        private void setComboText(String text) {

                if (isFlat) {
                        mFlatCombo.setText(text);
                }
                else {
                        mCombo.removeAll();
                        mCombo.add(text);
                        mCombo.select(0);
                }
        }

        private synchronized void kill(int debug) {
                kill(debug, false);
        }

        // kills the popup area and unhooks various listeners, takes an integer 
so
        // that we can debug where the close comes from easier
        private synchronized void kill(int debug, boolean skipFocus) {
                if (mCalendarComposite == null)
                        return;
                if (mCalendarComposite.isDisposed())
                        return;

                if (mCalendarComposite != null && 
mCalendarComposite.isMonthPopupActive())
                        return;

                // System.err.println(debug);

                if (mCalendarShell != null && !mCalendarShell.isDisposed()) {
                        mLastKillRequest = 
Calendar.getInstance(mSettings.getLocale()).getTimeInMillis();
                        mCalendarShell.setVisible(false);
                        mCalendarShell.dispose();
                }

                Display.getDefault().removeFilter(SWT.KeyDown, mKillListener);
                Display.getDefault().removeFilter(SWT.MouseDown, 
mOobClickListener);

                if (mComboControl != null && !mComboControl.isDisposed()) {
                        mComboControl.setCapture(false);
                        // have to traverse escape key after the fake popup is 
closed or the
                        // "0 length" popup will have focus
                        // traversing forces it to close
                        mComboControl.traverse(SWT.TRAVERSE_ESCAPE);
                        // if (getDate().length() != 0)
                        // 
setText(DateHelper.getFormattedDate(DateHelper.getDate(getDate(),
                        // mDateFormat), mDateFormat));
                }

                if (OS_CARBON) {
                        if (mCarbonPrePopupDate != null)
                                setDate(mCarbonPrePopupDate);
                }

                if (!skipFocus) {
                        if (isFlat) {
                                mFlatCombo.getTextControl().setFocus();
                        }
                        else {
                                mCombo.setFocus();
                        }
                }
        }

        private boolean isCalendarVisible() {
                if (mCalendarShell != null && !mCalendarShell.isDisposed())
                        return true;

                return false;
        }

        /**
         * Pops open the calendar popup.
         */
        public void openCalendar() {
                checkWidget();
                if (isCalendarVisible())
                        return;

                showCalendar();
        }

        /**
         * Closes the calendar popup.
         */
        public void closeCalendar() {
                checkWidget();
                if (!isCalendarVisible())
                        return;

                kill(99);
        }

        /**
         * Returns the set date as the raw String representation that is 
currently
         * displayed in the combo.
         * 
         * @return String date
         */
        public String getDateAsString() {
                checkWidget();
                String text = isFlat ? mFlatCombo.getText() : mCombo.getText();
                if (text.equals(""))
                        return "";

                return text;
        }

        /**
         * Returns the currently set date.
         * 
         * @return Calendar of date selection or null.
         */
        public Calendar getDate() {
                checkWidget();
                if (!isReadOnly)
                        parseTextDate();

                return mStartDate;
        }

        /*
         * private void setDateBasedOnComboText() { try { Date d =
         * DateHelper.getDate(isFlat ? mFlatCombo.getText() : mCombo.getText(),
         * mSettings.getDateFormat()); setDate(d); } catch (Exception err) { // 
we
         * don't care } }
         */

        // shows the calendar area
        public synchronized void showCalendar() {
                try {
                        // this is part of the OSX issue where the popup for a 
combo is
                        // shown even if there is only 1 item to select (dumb).
                        // as we remove the date just prior to the popup 
opening, here, we
                        // add it again, so it doesn't look like anything 
happened to the
                        // user
                        // when in fact we removed and added something in the 
blink of an
                        // eye, just so that the combo would not open its own 
popup. This
                        // seems to work
                        // without a hitch -- fix: June 21, 2008
                        if (OS_CARBON && isReadOnly && mCarbonPrePopupDate != 
null)
                                setDate(mCarbonPrePopupDate);

                        // bug fix: Apr 18, 2008 - if we do various operations 
prior to
                        // actually fetching any newly entered text into the
                        // (non-read only) combo, we'll lose that edit, so 
fetch the combo
                        // text now so that we can check it later down in the 
code
                        // reported by: B. Haje
                        parseTextDate();

                        String comboText = isFlat ? mFlatCombo.getText() : 
mCombo.getText();

                        mComboControl.setCapture(true);
                        // some weird bug with opening, selecting, closing, 
then opening
                        // again, which blanks out the mCombo the first time 
around..
                        if (!isFlat)
                                mCombo.select(0);

                        // kill any old
                        if (isCalendarVisible()) {
                                // bug fix part #2, apr 23. Repeated klicking 
open/close will
                                // get here, so we need to do the same bug fix 
as before but
                                // somewhat differently
                                // as we need to update the date object as 
well. This is
                                // basically only for non-read-only combos, but 
the fix is
                                // universally applicable.
                                setComboText(comboText);
                                parseTextDate();
                                kill(11);
                                return;
                        }

                        mComboControl.setFocus();

                        // bug fix: Apr 18, 2008 (see above)
                        // the (necessary) setFocus call above for some reason 
screws up any
                        // text entered by the user, so we actually have to set 
the text
                        // back onto the combo, despite the fact we pulled the 
data just a
                        // few lines ago.
                        setComboText(comboText);

                        Display.getDefault().addFilter(SWT.KeyDown, 
mKillListener);
                        Display.getDefault().addFilter(SWT.MouseDown, 
mOobClickListener);

                        mCalendarShell = new 
Shell(Display.getDefault().getActiveShell(), SWT.ON_TOP | SWT.NO_TRIM | 
SWT.NO_FOCUS);
                        mCalendarShell.setLayout(new FillLayout());
                        if (OS_CARBON)
                                
mCalendarShell.setSize(mSettings.getCalendarWidthMacintosh(), 
mSettings.getCalendarHeightMacintosh());
                        else
                                
mCalendarShell.setSize(mSettings.getCalendarWidth(), 
mSettings.getCalendarHeight());

                        mCalendarShell.addShellListener(new ShellListener() {
                                public void shellActivated(ShellEvent event) {
                                }

                                public void shellClosed(ShellEvent event) {
                                        // shell killed
                                        kill(12);
                                }

                                public void shellDeactivated(ShellEvent event) {
                                }

                                public void shellDeiconified(ShellEvent event) {
                                }

                                public void shellIconified(ShellEvent event) {
                                        // shell no longer in focus (like.. 
WindowsKey + M on WinXP
                                        // or such)
                                        kill(13);
                                }
                        });

                        // if no date has been set, and we have another 
calendar widget to
                        // pull from, grab that date.
                        // if we do have a date set, load it as an object we 
can actually
                        // use.
                        Calendar pre = null;

                        if (comboText != null && comboText.length() > 1) {
                                try {
                                        Date dat = 
DateHelper.getDate(comboText, mSettings.getDateFormat());
                                        if (dat != null) {
                                                pre = 
Calendar.getInstance(mSettings.getLocale());
                                                pre.setTime(dat);
                                        }
                                }
                                catch (Exception err) {
                                        List otherFormats = 
mSettings.getAdditionalDateFormats();
                                        if (otherFormats != null) {
                                                boolean dateSet = false;
                                                try {
                                                        for (int i = 0; i < 
otherFormats.size(); i++) {
                                                                String format = 
(String) otherFormats.get(i);
                                                                Date date = 
DateHelper.getDate(comboText, format);
                                                                // success
                                                                setDate(date);
                                                                Calendar cal = 
Calendar.getInstance(mSettings.getLocale());
                                                                
cal.setTime(date);
                                                                pre = cal;
                                                                dateSet = true;
                                                                break;
                                                        }
                                                }
                                                catch (Exception err2) {
                                                        // don't care
                                                        // 
err2.printStackTrace();
                                                }

                                                if (!dateSet) {
                                                        // unparseable date, 
set the last used date if any,
                                                        // otherwise set 
nodateset text
                                                        if (mStartDate != null)
                                                                
setDate(mStartDate);
                                                        else {
                                                                
setComboText(mSettings.getNoDateSetText());
                                                        }
                                                }
                                        }
                                        else {
                                                // unparseable date, set the 
last used date if any,
                                                // otherwise set nodateset text
                                                if (mStartDate != null)
                                                        setDate(mStartDate);
                                                else {
                                                        
setComboText(mSettings.getNoDateSetText());
                                                }
                                        }
                                }

                        }
                        else {
                                if (mDependingCombo != null) {
                                        // we need to pull the date from the 
depending combo's text
                                        // area as it may be non-read-only, so 
we can't rely on the
                                        // date
                                        Calendar date = null;
                                        try {
                                                Date d = 
DateHelper.getDate(mDependingCombo.getCombo().getText(), 
mSettings.getDateFormat());
                                                date = 
Calendar.getInstance(mSettings.getLocale());
                                                date.setTime(d);
                                        }
                                        catch (Exception err) {
                                                date = 
mDependingCombo.getDate();
                                        }

                                        if (date != null) {
                                                pre = 
Calendar.getInstance(mSettings.getLocale());
                                                pre.setTime(date.getTime());
                                        }
                                }
                        }

                        // create the calendar composite
                        mCalendarComposite = new 
CalendarComposite(mCalendarShell, pre, mDisallowBeforeDate, mDisallowAfterDate, 
mColorManager, mSettings, mAllowDateRange, mStartDate,
                                        mEndDate);
                        for (int i = 0; i < mListeners.size(); i++) {
                                ICalendarListener listener = 
(ICalendarListener) mListeners.get(i);
                                
mCalendarComposite.addCalendarListener(listener);
                        }

                        mCalendarComposite.addMainCalendarListener(new 
ICalendarListener() {
                                public void dateChanged(Calendar date) {
                                        mAllowTextEntry = true;
                                        if (!isFlat)
                                                mCombo.removeAll();

                                        if (OS_CARBON)
                                                mCarbonPrePopupDate = date;

                                        mStartDate = date;
                                        if (date == null) {
                                                setText("");
                                        }
                                        else {
                                                updateDate();
                                        }

                                        mAllowTextEntry = false;
                                }

                                public void dateRangeChanged(Calendar start, 
Calendar end) {
                                        mAllowTextEntry = true;
                                        if (!isFlat)
                                                mCombo.removeAll();

                                        mStartDate = start;

                                        if (OS_CARBON)
                                                mCarbonPrePopupDate = start;

                                        mEndDate = end;
                                        if (start == null) {
                                                setText("");
                                        }
                                        else {
                                                updateDate();
                                        }

                                        mAllowTextEntry = false;

                                        if (mDependingCombo != null) {
                                                if (end != null)
                                                        
mDependingCombo.setDate(end);
                                                else
                                                        
mDependingCombo.setText("");
                                        }
                                }

                                public void popupClosed() {
                                        kill(14);
                                }
                        });

                        // figure out where to put the calendar composite shell
                        Point calLoc = mComboControl.getLocation();
                        Point size = mComboControl.getSize();

                        Point loc = null;
                        if (mSettings.showCalendarInRightCorner())
                                loc = new Point(calLoc.x + size.x - 
mCalendarShell.getSize().x, calLoc.y + size.y);
                        else
                                loc = new Point(calLoc.x, calLoc.y + size.y);

                        loc = toDisplay(loc);

                        mCalendarShell.setLocation(loc);
                        mCalendarShell.setVisible(true);

                }
                catch (Exception e) {
                        mComboControl.setCapture(false);
                        e.printStackTrace();
                        // don't really care
                }
        }

        /**
         * Adds a calendar listener.
         * 
         * @param listener
         *            Listener
         */
        public void addCalendarListener(ICalendarListener listener) {
                checkWidget();
                if (!mListeners.contains(listener))
                        mListeners.add(listener);
        }

        /**
         * Removes a calendar listener.
         * 
         * @param listener
         *            Listener
         */
        public void removeCalendarListener(ICalendarListener listener) {
                checkWidget();
                mListeners.remove(listener);
        }

        /**
         * Returns the combo box widget.
         * <p>
         * <font color="red"><b>NOTE:</b> The Combo box has a lot of listeners 
on
         * it, please be "careful" when using it as you may cause unplanned-for
         * things to happen.</font>
         * 
         * @return Combo widget
         */
        public Combo getCombo() {
                checkWidget();
                return mCombo;
        }

        public FlatCalendarCombo getCCombo() {
                checkWidget();
                return mFlatCombo;
        }

        private void updateDate() {
                setText(DateHelper.getDate(mStartDate, 
mSettings.getDateFormat()));
        }

        /**
         * Puts focus on the combo box.
         * 
         * @deprecated please use {...@link #setFocus()}
         */
        public void grabFocus() {
                checkWidget();
                if (isFlat)
                        mFlatCombo.setFocus();
                else
                        mCombo.setFocus();
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Composite#setFocus()
         */
        public boolean setFocus() {
                checkWidget();
                if (this.isFlat) {
                        return this.getCCombo().getTextControl().setFocus();
                }
                else {
                        return this.mCombo.setFocus();
                }
        }

        /*
         * (non-Javadoc)
         * 
         * @see org.eclipse.swt.widgets.Control#forceFocus()
         */
        public boolean forceFocus() {
                checkWidget();
                if (this.isFlat) {
                        return this.getCCombo().getTextControl().forceFocus();
                }
                else {
                        return this.mCombo.forceFocus();
                }
        }

        public void setEnabled(boolean enabled) {
                checkWidget();
                if (isFlat)
                        mFlatCombo.setEnabled(enabled);
                else
                        mCombo.setEnabled(enabled);
        }

        public boolean isEnabled() {
                checkWidget();
                return isFlat ? mFlatCombo.getEnabled() : mCombo.getEnabled();
        }

        /**
         * Adds a modification listener to the combo box.
         * 
         * @param ml
         *            ModifyListener
         */
        public void addModifyListener(ModifyListener ml) {
                checkWidget();
                if (isFlat)
                        mFlatCombo.addModifyListener(ml);
                else
                        mCombo.addModifyListener(ml);
        }

        /**
         * Removes a modification listener from the combo box.
         * 
         * @param ml
         *            ModifyListener
         */
        public void removeModifyListener(ModifyListener ml) {
                checkWidget();
                if (isFlat)
                        mFlatCombo.removeModifyListener(ml);
                else
                        mCombo.removeModifyListener(ml);
        }

        /**
         * The date prior to which selection is not allowed.
         * 
         * @return Date
         */
        public Calendar getDisallowBeforeDate() {
                return mDisallowBeforeDate;
        }

        /**
         * Sets the date prior to which selection is not allowed.
         * 
         * @param disallowBeforeDate
         *            Date
         */
        public void setDisallowBeforeDate(Calendar disallowBeforeDate) {
                mDisallowBeforeDate = disallowBeforeDate;
        }

        /**
         * Sets the date prior to which selection is not allowed.
         * 
         * @param disallowBeforeDate
         *            Date
         */
        public void setDisallowBeforeDate(Date disallowBeforeDate) {
                Calendar cal = Calendar.getInstance(mSettings.getLocale());
                cal.setTime(disallowBeforeDate);
                mDisallowBeforeDate = cal;
        }

        /**
         * The date after which selection is not allowed.
         * 
         * @return Date
         */
        public Calendar getDisallowAfterDate() {
                return mDisallowAfterDate;
        }

        /**
         * Sets the date after which selection is not allowed.
         * 
         * @param disallowAfterDate
         *            Date
         */
        public void setDisallowAfterDate(Calendar disallowAfterDate) {
                mDisallowAfterDate = disallowAfterDate;
        }

        /**
         * Sets the date after which selection is not allowed.
         * 
         * @param disallowAfterDate
         */
        public void setDisallowAfterDate(Date disallowAfterDate) {
                Calendar cal = Calendar.getInstance(mSettings.getLocale());
                cal.setTime(disallowAfterDate);
                mDisallowAfterDate = cal;
        }

        /**
         * Sets the CalendarCombo that will be the recipient of (end date) date
         * range changes as well as date start date that will be used.
         * 
         * @param combo
         *            CalendarCombo
         */
        public void setDependingCombo(CalendarCombo combo) {
                mDependingCombo = combo;
        }

        /**
         * Returns the CalendarCombo that is the recipient of (end date) date 
range
         * changes as well as date start date that will be used.
         * 
         * @return CalendarCombo
         */
        public CalendarCombo getDependingCombo() {
                return mDependingCombo;
        }

        public void addControlListener(ControlListener listener) {
                mComboControl.addControlListener(listener);
        }

        public void addDragDetectListener(DragDetectListener listener) {
                mComboControl.addDragDetectListener(listener);
        }

        public void addFocusListener(FocusListener listener) {
                mComboControl.addFocusListener(listener);
        }

        public void addHelpListener(HelpListener listener) {
                mComboControl.addHelpListener(listener);
        }

        public void addKeyListener(KeyListener listener) {
                mComboControl.addKeyListener(listener);
        }

        public void addMenuDetectListener(MenuDetectListener listener) {
                mComboControl.addMenuDetectListener(listener);
        }

        public void addMouseListener(MouseListener listener) {
                mComboControl.addMouseListener(listener);
        }

        public void addMouseMoveListener(MouseMoveListener listener) {
                mComboControl.addMouseMoveListener(listener);
        }

        public void addMouseTrackListener(MouseTrackListener listener) {
                mComboControl.addMouseTrackListener(listener);
        }

        public void addMouseWheelListener(MouseWheelListener listener) {
                mComboControl.addMouseWheelListener(listener);
        }

        public void addPaintListener(PaintListener listener) {
                mComboControl.addPaintListener(listener);
        }

        public void addTraverseListener(TraverseListener listener) {
                mComboControl.addTraverseListener(listener);
        }

        public void addDisposeListener(DisposeListener listener) {
                mComboControl.addDisposeListener(listener);
        }

        public void addListener(int eventType, Listener listener) {
                mComboControl.addListener(eventType, listener);
        }

        public void removeControlListener(ControlListener listener) {
                mComboControl.removeControlListener(listener);
        }

        public void removeDragDetectListener(DragDetectListener listener) {
                mComboControl.removeDragDetectListener(listener);
        }

        public void removeFocusListener(FocusListener listener) {
                mComboControl.removeFocusListener(listener);
        }

        public void removeHelpListener(HelpListener listener) {
                mComboControl.removeHelpListener(listener);
        }

        public void removeKeyListener(KeyListener listener) {
                mComboControl.removeKeyListener(listener);
        }

        public void removeMenuDetectListener(MenuDetectListener listener) {
                mComboControl.removeMenuDetectListener(listener);
        }

        public void removeMouseListener(MouseListener listener) {
                mComboControl.removeMouseListener(listener);
        }

        public void removeMouseMoveListener(MouseMoveListener listener) {
                mComboControl.removeMouseMoveListener(listener);
        }

        public void removeMouseTrackListener(MouseTrackListener listener) {
                mComboControl.removeMouseTrackListener(listener);
        }

        public void removeMouseWheelListener(MouseWheelListener listener) {
                mComboControl.removeMouseWheelListener(listener);
        }

        public void removePaintListener(PaintListener listener) {
                mComboControl.removePaintListener(listener);
        }

        public void removeTraverseListener(TraverseListener listener) {
                mComboControl.removeTraverseListener(listener);
        }

        public void notifyListeners(int eventType, Event event) {
                mComboControl.notifyListeners(eventType, event);
        }

        public void removeDisposeListener(DisposeListener listener) {
                mComboControl.removeDisposeListener(listener);
        }

        public void removeListener(int eventType, Listener listener) {
                mComboControl.removeListener(eventType, listener);
        }

        public Composite getActiveComboControl() {
                return mComboControl;
        }
}

_______________________________________________
nebula-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/nebula-dev

Reply via email to