| /******************************************************************************* |
| * Copyright (c) 2005, 2012 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.bpel.ui.properties; |
| |
| import java.text.DateFormat; |
| import java.text.FieldPosition; |
| import java.util.Date; |
| |
| import org.eclipse.bpel.common.ui.details.IDetailsAreaConstants; |
| import org.eclipse.bpel.common.ui.flatui.FlatFormAttachment; |
| import org.eclipse.bpel.common.ui.flatui.FlatFormData; |
| import org.eclipse.bpel.common.ui.flatui.FlatFormLayout; |
| import org.eclipse.bpel.ui.Messages; |
| import org.eclipse.bpel.ui.Policy; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.layout.FillLayout; |
| import org.eclipse.swt.widgets.Combo; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.TypedListener; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| |
| |
| /** |
| * Collection of widgets for choosing a specific date and time. |
| * |
| * TODO: rewrite this to be independent of serialization format. Move that code elsewhere. |
| */ |
| public class DateTimeSelector extends Composite { |
| |
| static final String ID = "id"; //$NON-NLS-1$ |
| |
| |
| public static String[] DateTimeSelector_Months = new String[] { |
| Messages.DateTimeSelector_Month_1, Messages.DateTimeSelector_Month_2, Messages.DateTimeSelector_Month_3, |
| Messages.DateTimeSelector_Month_4, Messages.DateTimeSelector_Month_5, Messages.DateTimeSelector_Month_6, |
| Messages.DateTimeSelector_Month_7, Messages.DateTimeSelector_Month_8, Messages.DateTimeSelector_Month_9, |
| Messages.DateTimeSelector_Month_10, Messages.DateTimeSelector_Month_11, Messages.DateTimeSelector_Month_12 |
| }; |
| |
| static final int YEAR = 0; |
| static final int MONTH = YEAR+1; |
| static final int DAY = YEAR+2; |
| static final int HOUR = YEAR+3; |
| static final int MINUTE = YEAR+4; |
| static final int SECOND = YEAR+5; |
| |
| static final int LAST_IDX = YEAR+6; |
| |
| |
| |
| protected Object lastChangeContext ; |
| |
| private Combo[] combo; |
| |
| private Label timeSep, timeSep2, dateSep, dateSep2; |
| private int yearMin; |
| private int yearMax; |
| |
| protected String dateSepText = "/"; //$NON-NLS-1$ |
| protected String timeSepText = ":"; //$NON-NLS-1$ |
| |
| protected static final int[] rawDaysInMonth = { |
| 31,28,31,30,31,30,31,31,30,31,30,31 |
| }; |
| |
| public static int daysInMonth(int monthMinusOne, int year) { |
| |
| // february has a leap day every 4 years, except not every 100 years (except every 400..) |
| if (monthMinusOne==1 && (year&3)==0 && ((year%100)!=0 || (year%400)==0)) return 29; |
| return rawDaysInMonth[monthMinusOne]; |
| } |
| |
| private static String[] MONTH_NAMES; |
| |
| private FormToolkit wf; |
| |
| public DateTimeSelector(FormToolkit toolkit, Composite parent, int style, int yearMin, int yearMax) { |
| super(parent, style); |
| combo = new Combo[6]; |
| this.wf = toolkit; |
| this.yearMin = yearMin; |
| this.yearMax = yearMax; |
| if (MONTH_NAMES == null) { |
| MONTH_NAMES = new String[12]; |
| for (int i = 0; i<MONTH_NAMES.length; i++) { |
| MONTH_NAMES[i] = DateTimeSelector_Months[i]; |
| } |
| } |
| setLayout(new FillLayout()); |
| createControls(this); |
| } |
| |
| private void createControls(Composite parent){ |
| FlatFormData data; |
| |
| Composite composite = wf.createComposite(parent); |
| FlatFormLayout layout = new FlatFormLayout(); |
| layout.marginWidth = layout.marginHeight = 0; |
| composite.setLayout(layout); |
| |
| FlatFormAttachment monthLeft = new FlatFormAttachment(0,0); |
| FlatFormAttachment monthRight = new FlatFormAttachment(30,0); |
| FlatFormAttachment dayLeft = new FlatFormAttachment(35,0); |
| FlatFormAttachment dayRight = new FlatFormAttachment(65,0); |
| FlatFormAttachment yearLeft = new FlatFormAttachment(70,0); |
| FlatFormAttachment yearRight = new FlatFormAttachment(100,0); |
| |
| FlatFormAttachment hourLeft = new FlatFormAttachment(0,0); |
| FlatFormAttachment hourRight = new FlatFormAttachment(30,0); |
| FlatFormAttachment minuteLeft = new FlatFormAttachment(35,0); |
| FlatFormAttachment minuteRight = new FlatFormAttachment(65,0); |
| FlatFormAttachment secondLeft = new FlatFormAttachment(70,0); |
| FlatFormAttachment secondRight = new FlatFormAttachment(100,0); |
| |
| for(int i=0; i < combo.length; i++) { |
| combo[i] = new Combo(composite,SWT.READ_ONLY); |
| combo[i].setData(ID, Integer.valueOf( i )); |
| } |
| |
| dateSep = wf.createLabel(composite, dateSepText, SWT.CENTER); |
| dateSep2 = wf.createLabel(composite, dateSepText, SWT.CENTER); |
| timeSep = wf.createLabel(composite, timeSepText, SWT.CENTER); |
| timeSep2 = wf.createLabel(composite, timeSepText, SWT.CENTER); |
| |
| data = new FlatFormData(); |
| data.left = monthLeft; |
| data.right = monthRight; |
| data.top = new FlatFormAttachment(0, 0); |
| combo[MONTH].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = dayLeft; |
| data.right = dayRight; |
| data.top = new FlatFormAttachment(0, 0); |
| combo[DAY].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = yearLeft; |
| data.right = yearRight; |
| data.top = new FlatFormAttachment(0, 0); |
| combo[YEAR].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = hourLeft; |
| data.right = hourRight; |
| data.top = new FlatFormAttachment(combo[YEAR], IDetailsAreaConstants.VSPACE); |
| combo[HOUR].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = minuteLeft; |
| data.right = minuteRight; |
| data.top = new FlatFormAttachment(combo[YEAR], IDetailsAreaConstants.VSPACE); |
| combo[MINUTE].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = secondLeft; |
| data.right = secondRight; |
| data.top = new FlatFormAttachment(combo[YEAR], IDetailsAreaConstants.VSPACE); |
| combo[SECOND].setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(combo[MONTH], 0); |
| data.right = new FlatFormAttachment(combo[DAY], 0); |
| data.top = new FlatFormAttachment(combo[MONTH], 0, SWT.CENTER); |
| dateSep.setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(combo[DAY], 0); |
| data.right = new FlatFormAttachment(combo[YEAR], 0); |
| data.top = new FlatFormAttachment(combo[MONTH], 0, SWT.CENTER); |
| dateSep2.setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(combo[HOUR], 0); |
| data.right = new FlatFormAttachment(combo[MINUTE], 0); |
| data.top = new FlatFormAttachment(combo[HOUR], 0, SWT.CENTER); |
| timeSep.setLayoutData(data); |
| |
| data = new FlatFormData(); |
| data.left = new FlatFormAttachment(combo[MINUTE], 0); |
| data.right = new FlatFormAttachment(combo[SECOND], 0); |
| data.top = new FlatFormAttachment(combo[HOUR], 0, SWT.CENTER); |
| timeSep2.setLayoutData(data); |
| |
| reorderDateWidgetsForLocale(); |
| |
| init(); |
| layout(true); |
| } |
| |
| private void reorderDateWidgetsForLocale() { |
| // swap widgets around if our default layout doesn't match locale-specific order! |
| |
| int dayPos; |
| int monthPos; |
| int yearPos; |
| |
| DateFormat dateFlatFormat = DateFormat.getDateInstance();//DateFlatFormat.DEFAULT, Locale.JAPAN); |
| Date date = new Date(); |
| StringBuffer junkBuffer = new StringBuffer(); |
| |
| FieldPosition pos = new FieldPosition(DateFormat.DATE_FIELD); |
| dateFlatFormat.format(date, junkBuffer, pos); |
| dayPos = pos.getBeginIndex(); |
| if (Policy.DEBUG) System.out.println(junkBuffer); |
| junkBuffer.setLength(0); |
| |
| pos = new FieldPosition(DateFormat.MONTH_FIELD); |
| dateFlatFormat.format(date, junkBuffer, pos); |
| monthPos = pos.getBeginIndex(); |
| junkBuffer.setLength(0); |
| |
| pos = new FieldPosition(DateFormat.YEAR_FIELD); |
| dateFlatFormat.format(date, junkBuffer, pos); |
| yearPos = pos.getBeginIndex(); |
| |
| Combo left = combo[MONTH]; |
| Combo middle = combo[DAY]; |
| Combo right = combo[YEAR]; |
| |
| // The current widget arrangement assumes MDY. |
| if (dayPos < monthPos) { |
| // it should be DMY or YDM or DYM. |
| if (monthPos < yearPos) { |
| // D<M<Y |
| combo[DAY]=left; combo[MONTH]=middle; combo[YEAR]=right; // DMY |
| } else if (dayPos < yearPos) { |
| // D<M Y<M D<Y |
| combo[DAY]=left; combo[YEAR]=middle; combo[MONTH]=right; // DYM |
| } else { |
| // Y<D<M Y<M |
| combo[YEAR]=left; combo[DAY]=middle; combo[MONTH]=right; // YDM |
| } |
| } else { |
| if (dayPos < yearPos) { |
| // M<D<Y |
| combo[MONTH]=left; combo[DAY]=middle; combo[YEAR]=right; // MDY |
| } else if (monthPos < yearPos) { |
| // M<D Y<D M<Y |
| combo[MONTH]=left; combo[YEAR]=middle; combo[DAY]=right; // MYD |
| } else { |
| // Y<D Y<M<D |
| combo[YEAR]=left; combo[MONTH]=middle; combo[DAY]=right; // YMD |
| } |
| } |
| |
| } |
| |
| private void init(){ |
| populateCombos(); |
| setInitialSelections(); |
| addListeners(); |
| } |
| |
| private void populateComboWithInts(Combo combo, int start, int length) { |
| combo.removeAll(); |
| for (int i = start; i<start+length; i++) { |
| combo.add(((i<10)?"0":"")+String.valueOf(i)); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private void updateDaysCombo(){ |
| int sel = combo[DAY].getSelectionIndex(); |
| int days = daysInMonth(combo[MONTH].getSelectionIndex(), |
| Integer.parseInt(combo[YEAR].getText())); |
| populateComboWithInts(combo[DAY], 1, days); |
| combo[DAY].select(Math.min(sel, days-1)); |
| } |
| |
| private void populateCombos() { |
| |
| populateComboWithInts(combo[YEAR], yearMin, Math.max(0, yearMax-yearMin)); |
| combo[MONTH].setItems(MONTH_NAMES); |
| populateComboWithInts(combo[DAY], 1, 31); |
| populateComboWithInts(combo[HOUR], 0, 24); |
| populateComboWithInts(combo[MINUTE], 0, 60); |
| populateComboWithInts(combo[SECOND], 0, 60); |
| } |
| |
| private void setInitialSelections(){ |
| combo[YEAR].select(0); |
| combo[MONTH].select(0); |
| updateDaysCombo(); |
| combo[DAY].select(0); |
| combo[HOUR].select(12); |
| combo[MINUTE].select(0); |
| combo[SECOND].select(0); |
| } |
| |
| private void addListeners() { |
| |
| SelectionListener commonListener = new SelectionListener() { |
| public void widgetSelected(SelectionEvent e) { |
| Combo cw = (Combo) e.widget; |
| lastChangeContext = cw.getData(ID); |
| |
| if (cw == combo[YEAR] || cw == combo[MONTH]) { |
| updateDaysCombo(); |
| } |
| selectionChanged(); |
| } |
| public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } |
| }; |
| |
| for (int i = 0; i<6; i++) { |
| combo[i].addSelectionListener(commonListener); |
| } |
| } |
| |
| /** |
| * Returns an array of six values for year,month,day,hour,minute,second. |
| */ |
| public int[] getValues() { |
| int[] v = new int[6]; |
| v[YEAR] = combo[YEAR].getSelectionIndex()+yearMin; |
| v[MONTH] = combo[MONTH].getSelectionIndex()+1; |
| v[DAY] = combo[DAY].getSelectionIndex()+1; |
| v[HOUR] = combo[HOUR].getSelectionIndex(); |
| v[MINUTE] = combo[MINUTE].getSelectionIndex(); |
| v[SECOND] = combo[SECOND].getSelectionIndex(); |
| |
| return v; |
| } |
| |
| /** |
| * Expects an array of six values for year,month,day,hour,minute,second. |
| */ |
| public boolean setValues(int[] v) { |
| if (!checkValues(v)) return false; |
| // these values are within the valid ranges for the combos. |
| combo[YEAR].select(v[YEAR]-yearMin); |
| combo[MONTH].select(v[MONTH]-1); |
| updateDaysCombo(); |
| combo[DAY].select(v[DAY]-1); |
| combo[HOUR].select(v[HOUR]); |
| combo[MINUTE].select(v[MINUTE]); |
| combo[SECOND].select(v[SECOND]); |
| return true; |
| } |
| |
| protected boolean checkValues(int[] v) { |
| if (v == null) return false; |
| if (v[YEAR] < yearMin || v[YEAR] > yearMax) return false; |
| if (v[MONTH] < 1 || v[MONTH] > 12) return false; |
| if (v[DAY] < 1 || v[DAY] > daysInMonth(v[MONTH]-1, v[YEAR])) return false; |
| if (v[HOUR] < 0 || v[HOUR] > 23) return false; |
| if (v[MINUTE] < 0 || v[MINUTE] > 59) return false; |
| if (v[SECOND] < 0 || v[SECOND] > 59) return false; |
| return true; |
| } |
| |
| void selectionChanged() { |
| Event e = new Event(); |
| e.type = SWT.Selection; |
| e.widget = this; |
| e.widget.notifyListeners(e.type, e); |
| } |
| |
| public void addSelectionListener(SelectionListener listener){ |
| TypedListener typedListener = new TypedListener (listener); |
| addListener (SWT.Selection,typedListener); |
| // addListener (SWT.DefaultSelection,typedListener); |
| } |
| |
| public Object getUserContext() { |
| return lastChangeContext; |
| } |
| |
| public void restoreUserContext(Object userContext) { |
| int i = ((Integer)userContext).intValue(); |
| switch (i) { |
| case YEAR: case MONTH: case DAY: |
| case HOUR: case MINUTE: case SECOND: |
| combo[i].setFocus(); |
| return; |
| } |
| } |
| |
| @Override |
| public void setEnabled (boolean enabled) { |
| super.setEnabled(enabled); |
| for (int i = 0; i < combo.length; i++) { |
| combo[i].setEnabled(enabled); |
| } |
| } |
| } |