blob: f0e53c33bac98fc1cb18bbcf77ce35cf996aab4b [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}