/* * Copyright 2010 The Rabbit Eclipse Plug-in Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package rabbit.ui.internal; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.DateTime; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.ToolItem; import java.text.Format; import java.text.SimpleDateFormat; import java.util.Calendar; /** * A subclass of {@link Action} that is designed for {@link IToolBarManager}. * When an action of this kind is clicked, a pop up dialog containing a * {@link DateTime} widget will show up below the clicked tool item. */ public class CalendarAction extends Action { /** The string format used to format dates. */ public static final String DATE_FORMAT = "yyyy-MM-dd"; /** * Creates and adds a new action on the tool bar. * * @param toolBar The tool bar. * @param shell The parent shell. * @param calendar The calendar to bind with this action. The changes made on * this action's DateTime widget will be reflected on this calendar. * @return The created action. */ public static CalendarAction create(IToolBarManager toolBar, Shell shell, Calendar calendar) { return create(toolBar, shell, calendar, " ", " "); } /** * Creates and adds a new action on the tool bar. * * @param toolBar The tool bar. * @param shell The parent shell. * @param calendar The calendar to bind with this action. The changes made on * this action's DateTime widget will be reflected on this calendar. * @param prefix The prefix of the action's text. * @param suffix The suffix of the action's text. * @return The created action. */ public static CalendarAction create(IToolBarManager toolBar, Shell shell, Calendar calendar, String prefix, String suffix) { CalendarAction action = new CalendarAction(shell, calendar, prefix, suffix); toolBar.add(action); return action; } private final Calendar calendar; private final Format format; private final String prefix; private final String suffix; private DateTime dateTime; private Shell shell; /** * Constructor. * * @param parentShell The parent shell. * @param calendar The calendar to bind with this action. * @param prefix The prefix of this action's text. * @param suffix The suffix of this action's text. */ private CalendarAction(final Shell parentShell, Calendar calendar, String prefix, String suffix) { super("", IAction.AS_CHECK_BOX); this.calendar = calendar; this.prefix = (prefix == null) ? "" : prefix; this.suffix = (suffix == null) ? "" : suffix; this.format = new SimpleDateFormat(DATE_FORMAT); setText(getFormattedText()); parentShell.getDisplay().syncExec(new Runnable() { @Override public void run() { createCalendar(parentShell); } }); } /** * Gets the calendar binded to this action. * * @return The calendar. */ public Calendar getCalendar() { return calendar; } /** * Gets the date time widget. * * @return The widget. */ public DateTime getDateTime() { return dateTime; } public Shell getShell() { return shell; } @Override public void runWithEvent(Event event) { if (!shell.isVisible()) { open(event); } else { close(); } } /** * Closes the pop up calendar. */ private void close() { shell.setVisible(false); setChecked(false); } /** * Creates the pop up calendar. * * @param parentShell The parent shell. */ private void createCalendar(Shell parentShell) { GridLayout layout = new GridLayout(); layout.marginTop = -6; // better looking layout.marginWidth = -1; shell = new Shell(parentShell, SWT.TOOL); shell.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE)); shell.setLayout(layout); shell.addListener(SWT.Deactivate, new Listener() { @Override public void handleEvent(Event event) { close(); } }); Calendar cal = getCalendar(); dateTime = new DateTime(shell, SWT.CALENDAR); dateTime.setDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal .get(Calendar.DAY_OF_MONTH)); dateTime.addListener(SWT.MouseDoubleClick, new Listener() { @Override public void handleEvent(Event event) { ok(); } }); dateTime.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { getCalendar().set(Calendar.YEAR, dateTime.getYear()); getCalendar().set(Calendar.MONTH, dateTime.getMonth()); getCalendar().set(Calendar.DAY_OF_MONTH, dateTime.getDay()); setText(getFormattedText()); } }); Link link = new Link(shell, SWT.NONE); link.setText("<A>Today</A>"); link.setBackground(shell.getBackground()); link.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false)); link.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { RabbitView.updateDateTime(dateTime, Calendar.getInstance()); ok(); } }); shell.pack(); } /** * Formats the default calendar to a string. * * @return A formatted string. */ private String getFormattedText() { return getFormattedText(calendar); } /** * Formats the given calendar to a string. * * @param calendar The calendar. * @return A formatted string. */ private String getFormattedText(Calendar calendar) { return prefix + format.format(calendar.getTime()) + suffix; } /** * Applies the changes and closes the pop up calendar. */ private void ok() { shell.setVisible(false); calendar.set(dateTime.getYear(), dateTime.getMonth(), dateTime.getDay()); setText(getFormattedText()); setChecked(false); } /** * Opens the pop up calendar. * * @param e The event. */ private void open(Event e) { if (!(e.widget instanceof ToolItem)) { return; } RabbitView.updateDateTime(dateTime, calendar); ToolItem item = ((ToolItem) e.widget); Rectangle bounds = item.getBounds(); Point location = item.getParent().toDisplay(bounds.x, bounds.y + bounds.height); shell.setLocation(location); shell.setVisible(true); shell.setActive(); } }