blob: 6e41f8698db8b44d26fecb2ec6adeb2e07c29db8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 BSI Business Systems Integration AG.
* 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:
* BSI Business Systems Integration AG - initial API and implementation
*******************************************************************************/
package org.eclipse.scout.rt.ui.rap.form.fields.datefield.chooser;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Date;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.lifecycle.WidgetUtil;
import org.eclipse.scout.commons.DateUtility;
import org.eclipse.scout.rt.ui.rap.ext.table.util.TableCellRolloverSupport;
import org.eclipse.scout.rt.ui.rap.util.RwtUtility;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class DateChooserDialog extends Dialog {
private static final long serialVersionUID = 1L;
private static final String NEXT_YEAR_CUSTOM_VARIANT = "datechooser-dialog-next-year";
private static final String NEXT_MONTH_CUSTOM_VARIANT = "datechooser-dialog-next-month";
private static final String LAST_MONTH_CUSTOM_VARIANT = "datechooser-dialog-last-month";
private static final String LAST_YEAR_CUSTOM_VARIANT = "datechooser-dialog-last-year";
private static final String DATECHOOSER_DIALOG_CUSTOM_VARIANT = "datechooser-dialog";
public static final int TYPE_BACK_YEAR = 1 << 0;
public static final int TYPE_BACK_MONTH = 1 << 1;
public static final int TYPE_FOREWARD_MONTH = 1 << 2;
public static final int TYPE_FOREWARD_YEAR = 1 << 3;
private static final int DATE_CELL_WIDTH = 35;
private static final int DATE_CELL_HEIGHT = SWT.DEFAULT;
private static final int CONTROL_BUTTON_WIDTH = 15;
private static final int CONTROL_BUTTON_HEIGHT = 15;
private TableViewer m_viewer;
private Label m_monthLabel;
private DatefieldTableModel m_model;
private Date m_returnDate = null;
@Override
protected int getShellStyle() {
return SWT.NONE;
}
public DateChooserDialog(Shell parentShell, Date date) {
super(parentShell);
m_model = new DatefieldTableModel(RwtUtility.getClientSessionLocale(parentShell.getDisplay()));
setDisplayDate(date);
setBlockOnOpen(false);
create();
}
private void setDisplayDate(Date date) {
m_model.setHighLightDate(date);
m_model.setNavigationDate(date);
}
public void openDateChooser(Control c) {
showDialogFor(c);
}
public Date getReturnDate() {
return m_returnDate;
}
public int showDialogFor(Control field) {
Point location = getLocation(field);
if (location != null) {
getShell().setLocation(location);
}
m_viewer.refresh();
return this.open();
}
/**
* Override this method to set a custom location.
* <p>
* As default the popup is opened right under the field.
* </p>
*/
protected Point getLocation(Control field) {
// make sure that the popup fit into the application window.
Rectangle appBounds = field.getDisplay().getBounds();
Point absPrefPos = field.toDisplay(0, field.getSize().y);
Rectangle prefBounds = new Rectangle(absPrefPos.x, absPrefPos.y, getShell().getSize().x, getShell().getSize().y);
// horizontal correction
if (prefBounds.x + prefBounds.width > appBounds.width) {
prefBounds.x = appBounds.width - prefBounds.width;
}
// vertical correction
if (prefBounds.y + prefBounds.height > appBounds.height) {
prefBounds.y = appBounds.height - prefBounds.height;
}
return new Point(prefBounds.x, prefBounds.y);
}
@Override
protected Control createContents(Composite parent) {
parent.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
Composite rootArea = new Composite(parent, SWT.NO_FOCUS);
rootArea.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
GridData gridData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
rootArea.setLayoutData(gridData);
Control navigationArea = createControlArea(rootArea);
Control calendarArea = createPickDateArea(rootArea);
// layout
rootArea.setLayout(new FormLayout());
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
navigationArea.setLayoutData(data);
data = new FormData();
data.top = new FormAttachment(navigationArea, 2);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
data.bottom = new FormAttachment(100, -5);
calendarArea.setLayoutData(data);
return rootArea;
}
protected String getDialogVariant() {
return DATECHOOSER_DIALOG_CUSTOM_VARIANT;
}
private Control createPickDateArea(Composite parent) {
final Table table = new Table(parent, SWT.SINGLE | SWT.NO_SCROLL | SWT.HIDE_SELECTION);
table.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
if (getDateCellHeight() != SWT.DEFAULT) {
table.setData(RWT.CUSTOM_ITEM_HEIGHT, getDateCellHeight());
}
table.setLinesVisible(true);
TableViewer viewer = new TableViewer(table);
new TableCellRolloverSupport(viewer);
table.setHeaderVisible(true);
table.addListener(SWT.MouseDown, new Listener() {
private static final long serialVersionUID = 1L;
@Override
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MouseDown: {
TableColumn columnAt = RwtUtility.getRwtColumnAt(table, new Point(event.x, event.y));
TableItem item = table.getItem(new Point(event.x, event.y));
if (item != null) {
item.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
if (columnAt != null) {
Date date = ((DateRow) item.getData()).getDate(table.indexOf(columnAt) - 1);
m_returnDate = date;
getShell().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
close();
}
});
}
}
break;
}
}
}
});
TableColumn dummyColumn = new TableColumn(table, SWT.RIGHT);
dummyColumn.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
dummyColumn.setWidth(0);
dummyColumn.setResizable(false);
dummyColumn.setMoveable(false);
String[] wd = new DateFormatSymbols(RwtUtility.getClientSessionLocale(parent.getDisplay())).getShortWeekdays();
// create the m_columns from monday to saturday
for (int i = 2; i < 8; i++) {
TableColumn col = new TableColumn(table, SWT.CENTER);
col.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
col.setWidth(getDateCellWidth());
col.setResizable(false);
col.setMoveable(false);
col.setText(wd[i]);
}
// sunday
TableColumn col = new TableColumn(table, SWT.CENTER);
col.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
col.setWidth(getDateCellWidth());
col.setResizable(false);
col.setMoveable(false);
col.setText(wd[Calendar.SUNDAY]);
// viewer
m_viewer = viewer;
m_viewer.setLabelProvider(m_model);
m_viewer.setContentProvider(m_model);
m_viewer.setInput(m_model);
return table;
}
protected int getDateCellWidth() {
return DATE_CELL_WIDTH;
}
protected int getDateCellHeight() {
return DATE_CELL_HEIGHT;
}
private Control createControlArea(Composite parent) {
Composite rootArea = RwtUtility.getUiEnvironment(parent.getDisplay()).getFormToolkit().createComposite(parent, SWT.NO_FOCUS);
rootArea.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
createButton(rootArea, TYPE_BACK_YEAR);
createButton(rootArea, TYPE_BACK_MONTH);
m_monthLabel = new Label(rootArea, SWT.CENTER);
m_monthLabel.setText(m_model.getMonthYearLabel());
m_monthLabel.setData(WidgetUtil.CUSTOM_VARIANT, getDialogVariant());
createButton(rootArea, TYPE_FOREWARD_MONTH);
createButton(rootArea, TYPE_FOREWARD_YEAR);
// layout
rootArea.setLayout(new GridLayout(5, false));
GridData data = new GridData();
data.grabExcessHorizontalSpace = true;
data.horizontalAlignment = GridData.FILL;
m_monthLabel.setLayoutData(data);
return rootArea;
}
private Button createButton(Composite parent, int type) {
String variant = getControlButtonVariant(type);
Button b = new Button(parent, SWT.PUSH);
b.setData(WidgetUtil.CUSTOM_VARIANT, variant);
b.addMouseListener(new P_NavigationMouseListener(type));
GridData data = new GridData(getControlButtonWidth(), getControlButtonHeight());
data.horizontalAlignment = GridData.FILL;
data.grabExcessHorizontalSpace = false;
b.setLayoutData(data);
return b;
}
/**
* Override this method to set a custom variant name for the control buttons
*/
protected String getControlButtonVariant(int type) {
switch (type) {
case TYPE_BACK_YEAR:
return LAST_YEAR_CUSTOM_VARIANT;
case TYPE_BACK_MONTH:
return LAST_MONTH_CUSTOM_VARIANT;
case TYPE_FOREWARD_MONTH:
return NEXT_MONTH_CUSTOM_VARIANT;
case TYPE_FOREWARD_YEAR:
return NEXT_YEAR_CUSTOM_VARIANT;
default:
return null;
}
}
protected int getControlButtonWidth() {
return CONTROL_BUTTON_WIDTH;
}
protected int getControlButtonHeight() {
return CONTROL_BUTTON_HEIGHT;
}
private class P_NavigationMouseListener extends MouseAdapter {
private static final long serialVersionUID = 1L;
private int m_type;
P_NavigationMouseListener(int type) {
m_type = type;
}
@Override
public void mouseDown(MouseEvent e) {
switch (m_type) {
case TYPE_BACK_YEAR:
m_model.setNavigationDate(DateUtility.addYears(m_model.getNavigationDate(), -1));
break;
case TYPE_BACK_MONTH:
m_model.setNavigationDate(DateUtility.addMonths(m_model.getNavigationDate(), -1));
break;
case TYPE_FOREWARD_MONTH:
m_model.setNavigationDate(DateUtility.addMonths(m_model.getNavigationDate(), 1));
break;
case TYPE_FOREWARD_YEAR:
m_model.setNavigationDate(DateUtility.addYears(m_model.getNavigationDate(), 1));
break;
}
m_viewer.refresh();
m_monthLabel.setText(m_model.getMonthYearLabel());
}
} // end class P_NavigationSelectionListener
}