0001: /*--------------------------------------------------------------------------*
0002: | Copyright (C) 2006 Christopher Kohlhaas |
0003: | |
0004: | This program is free software; you can redistribute it and/or modify |
0005: | it under the terms of the GNU General Public License as published by the |
0006: | Free Software Foundation. A copy of the license has been included with |
0007: | these distribution in the COPYING file, if not go to www.fsf.org |
0008: | |
0009: | As a special exception, you are granted the permissions to link this |
0010: | program with every library, which license fulfills the Open Source |
0011: | Definition as published by the Open Source Initiative (OSI). |
0012: *--------------------------------------------------------------------------*/
0013: package org.rapla.gui.internal.edit.reservation;
0014:
0015: import java.awt.BorderLayout;
0016: import java.awt.CardLayout;
0017: import java.awt.Color;
0018: import java.awt.Component;
0019: import java.awt.Graphics;
0020: import java.awt.Insets;
0021: import java.awt.event.ActionEvent;
0022: import java.awt.event.ActionListener;
0023: import java.awt.event.MouseAdapter;
0024: import java.awt.event.MouseEvent;
0025: import java.util.ArrayList;
0026: import java.util.Calendar;
0027: import java.util.Date;
0028: import java.util.Locale;
0029:
0030: import javax.swing.BorderFactory;
0031: import javax.swing.Box;
0032: import javax.swing.BoxLayout;
0033: import javax.swing.ButtonGroup;
0034: import javax.swing.DefaultListCellRenderer;
0035: import javax.swing.JComboBox;
0036: import javax.swing.JComponent;
0037: import javax.swing.JLabel;
0038: import javax.swing.JList;
0039: import javax.swing.JPanel;
0040: import javax.swing.JRadioButton;
0041: import javax.swing.JScrollPane;
0042: import javax.swing.SwingConstants;
0043: import javax.swing.UIManager;
0044: import javax.swing.border.Border;
0045: import javax.swing.event.ChangeEvent;
0046: import javax.swing.event.ChangeListener;
0047: import javax.swing.event.ListSelectionEvent;
0048: import javax.swing.event.ListSelectionListener;
0049:
0050: import org.apache.avalon.framework.activity.Disposable;
0051: import org.apache.avalon.framework.container.ContainerUtil;
0052: import org.rapla.components.calendar.DateChangeEvent;
0053: import org.rapla.components.calendar.DateChangeListener;
0054: import org.rapla.components.calendar.RaplaCalendar;
0055: import org.rapla.components.calendar.RaplaNumber;
0056: import org.rapla.components.calendar.RaplaTime;
0057: import org.rapla.components.layout.TableLayout;
0058: import org.rapla.components.util.DateTools;
0059: import org.rapla.entities.domain.Appointment;
0060: import org.rapla.entities.domain.Repeating;
0061: import org.rapla.entities.domain.RepeatingType;
0062: import org.rapla.entities.domain.ReservationHelper;
0063: import org.rapla.framework.RaplaContext;
0064: import org.rapla.framework.RaplaException;
0065: import org.rapla.framework.RaplaLocale;
0066: import org.rapla.gui.RaplaGUIComponent;
0067: import org.rapla.gui.internal.common.PeriodChooser;
0068: import org.rapla.gui.toolkit.DialogUI;
0069: import org.rapla.gui.toolkit.MonthChooser;
0070: import org.rapla.gui.toolkit.RaplaButton;
0071: import org.rapla.gui.toolkit.RaplaWidget;
0072: import org.rapla.gui.toolkit.WeekdayChooser;
0073:
0074: /** GUI for editing a single Appointment. */
0075: public class AppointmentController extends RaplaGUIComponent implements
0076: Disposable, RaplaWidget {
0077: JPanel panel = new JPanel();
0078:
0079: SingleEditor singleEditor = new SingleEditor();
0080:
0081: JPanel repeatingSelection = new JPanel();
0082: JPanel repeatingContainer = new JPanel();
0083: RepeatingEditor repeatingEditor = new RepeatingEditor();
0084:
0085: Appointment appointment;
0086: Repeating repeating;
0087:
0088: ArrayList listenerList = new ArrayList();
0089: JPanel repeatingType = new JPanel();
0090: JRadioButton noRepeating = new JRadioButton();
0091: JRadioButton weeklyRepeating = new JRadioButton();
0092: JRadioButton dailyRepeating = new JRadioButton();
0093: JRadioButton monthlyRepeating = new JRadioButton();
0094: JRadioButton yearlyRepeating = new JRadioButton();
0095:
0096: CardLayout repeatingCard = new CardLayout();
0097:
0098: public AppointmentController(RaplaContext sm) throws RaplaException {
0099: super (sm);
0100: panel.setLayout(new BorderLayout());
0101: panel.add(repeatingType, BorderLayout.NORTH);
0102: repeatingType.setLayout(new BoxLayout(repeatingType,
0103: BoxLayout.X_AXIS));
0104: repeatingType.add(noRepeating);
0105: repeatingType.add(weeklyRepeating);
0106: repeatingType.add(dailyRepeating);
0107: repeatingType.add(monthlyRepeating);
0108: repeatingType.add(yearlyRepeating);
0109:
0110: ButtonGroup buttonGroup = new ButtonGroup();
0111: buttonGroup.add(noRepeating);
0112: buttonGroup.add(weeklyRepeating);
0113: buttonGroup.add(dailyRepeating);
0114: buttonGroup.add(monthlyRepeating);
0115: buttonGroup.add(yearlyRepeating);
0116:
0117: panel.add(repeatingContainer, BorderLayout.CENTER);
0118:
0119: Border emptyLineBorder = new Border() {
0120: Insets insets = new Insets(1, 0, 0, 0);
0121: Color COLOR = Color.LIGHT_GRAY;
0122:
0123: public void paintBorder(Component c, Graphics g, int x,
0124: int y, int width, int height) {
0125: g.setColor(COLOR);
0126: g.drawLine(0, 0, c.getWidth(), 0);
0127:
0128: }
0129:
0130: public Insets getBorderInsets(Component c) {
0131: return insets;
0132: }
0133:
0134: public boolean isBorderOpaque() {
0135: return true;
0136: }
0137:
0138: };
0139:
0140: Border outerBorder = (BorderFactory.createCompoundBorder(
0141: BorderFactory.createEmptyBorder(0, 5, 0, 5)
0142: //,BorderFactory.createEmptyBorder()
0143: , emptyLineBorder));
0144:
0145: repeatingContainer.setBorder(BorderFactory
0146: .createCompoundBorder(outerBorder, BorderFactory
0147: .createEmptyBorder(10, 5, 10, 5)));
0148: repeatingContainer.setLayout(repeatingCard);
0149: repeatingContainer.add(singleEditor.getComponent(), "0");
0150: repeatingContainer.add(repeatingEditor.getComponent(), "1");
0151:
0152: singleEditor.initialize();
0153: repeatingEditor.initialize();
0154: ActionListener listener = new ActionListener() {
0155: public void actionPerformed(ActionEvent evt) {
0156: switchRepeatings();
0157: }
0158: };
0159: noRepeating.addActionListener(listener);
0160: weeklyRepeating.addActionListener(listener);
0161: monthlyRepeating.addActionListener(listener);
0162: dailyRepeating.addActionListener(listener);
0163: yearlyRepeating.addActionListener(listener);
0164: noRepeating.setText(getString("no_repeating"));
0165: weeklyRepeating.setText(getString("weekly"));
0166: dailyRepeating.setText(getString("daily"));
0167: monthlyRepeating.setText(getString("monthly"));
0168: yearlyRepeating.setText(getString("yearly"));
0169: }
0170:
0171: private void switchRepeatings() {
0172: if (noRepeating.isSelected()) {
0173: repeatingCard.show(repeatingContainer, "0");
0174: singleEditor.mapFromAppointment();
0175: appointment.setRepeatingEnabled(false);
0176: } else {
0177: RepeatingType repeatingType;
0178: if (monthlyRepeating.isSelected()) {
0179: repeatingType = RepeatingType.MONTHLY;
0180: } else if (yearlyRepeating.isSelected()) {
0181: repeatingType = RepeatingType.YEARLY;
0182: } else if (dailyRepeating.isSelected()) {
0183: repeatingType = RepeatingType.DAILY;
0184: } else {
0185: repeatingType = RepeatingType.WEEKLY;
0186: }
0187: ReservationHelper.makeRepeatingForPeriod(getPeriodModel(),
0188: appointment, repeatingType, 1);
0189: repeatingEditor.mapFromAppointment();
0190: repeatingCard.show(repeatingContainer, "1");
0191: }
0192: fireAppointmentChanged();
0193: }
0194:
0195: public void setAppointment(Appointment appointment) {
0196: this .appointment = appointment;
0197: this .repeating = appointment.getRepeating();
0198: if (appointment.getRepeating() != null) {
0199: repeatingEditor.mapFromAppointment();
0200: repeatingCard.show(repeatingContainer, "1");
0201: if (repeating.isWeekly())
0202: weeklyRepeating.setSelected(true);
0203: if (repeating.isDaily())
0204: dailyRepeating.setSelected(true);
0205: if (repeating.isMonthly())
0206: monthlyRepeating.setSelected(true);
0207: if (repeating.isYearly())
0208: yearlyRepeating.setSelected(true);
0209: } else {
0210: singleEditor.mapFromAppointment();
0211: repeatingCard.show(repeatingContainer, "0");
0212: noRepeating.setSelected(true);
0213: }
0214: }
0215:
0216: public Appointment getAppointment() {
0217: return appointment;
0218: }
0219:
0220: public void dispose() {
0221: ContainerUtil.dispose(singleEditor);
0222: ContainerUtil.dispose(repeatingEditor);
0223: }
0224:
0225: public JComponent getComponent() {
0226: return panel;
0227: }
0228:
0229: /** registers new ChangeListener for this component.
0230: * An ChangeEvent will be fired to every registered ChangeListener
0231: * when the appointment changes.
0232: * @see javax.swing.event.ChangeListener
0233: * @see javax.swing.event.ChangeEvent
0234: */
0235: public void addChangeListener(ChangeListener listener) {
0236: listenerList.add(listener);
0237: }
0238:
0239: /** removes a listener from this component.*/
0240: public void removeChangeListener(ChangeListener listener) {
0241: listenerList.remove(listener);
0242: }
0243:
0244: public ChangeListener[] getChangeListeners() {
0245: return (ChangeListener[]) listenerList
0246: .toArray(new ChangeListener[] {});
0247: }
0248:
0249: protected void fireAppointmentChanged() {
0250: if (listenerList.size() == 0)
0251: return;
0252: ChangeEvent evt = new ChangeEvent(this );
0253: ChangeListener[] listeners = getChangeListeners();
0254: for (int i = 0; i < listeners.length; i++) {
0255: listeners[i].stateChanged(evt);
0256: }
0257: getLogger().debug("appointment changed: " + appointment);
0258: }
0259:
0260: static double ROW_SIZE = 21;
0261:
0262: class SingleEditor implements DateChangeListener, Disposable {
0263: JPanel content = new JPanel();
0264: JLabel startLabel = new JLabel();
0265: RaplaCalendar startDate;
0266: JLabel startTimeLabel = new JLabel();
0267: RaplaTime startTime;
0268: JLabel endLabel = new JLabel();
0269: RaplaCalendar endDate;
0270: JLabel endTimeLabel = new JLabel();
0271: RaplaTime endTime;
0272: boolean listenerEnabled = true;
0273:
0274: public SingleEditor() {
0275: double pre = TableLayout.PREFERRED;
0276: double size[][] = { { pre, 5, pre, 10, pre, 5, pre }, // Columns
0277: { ROW_SIZE, 6, ROW_SIZE } }; // Rows
0278: TableLayout tableLayout = new TableLayout(size);
0279: content.setLayout(tableLayout);
0280: }
0281:
0282: public void initialize() {
0283: startDate = createRaplaCalendar();
0284: endDate = createRaplaCalendar();
0285: startTime = createRaplaTime();
0286: endTime = createRaplaTime();
0287: content.add(startLabel, "0,0,r,f");
0288: startLabel.setText(getString("start_date"));
0289: startTimeLabel.setText(getString("time_at"));
0290: endLabel.setText(getString("end_date"));
0291: endTimeLabel.setText(getString("time_at"));
0292: content.add(startDate, "2,0,f,f");
0293: content.add(startTimeLabel, "4,0,l,f");
0294: content.add(startTime, "6,0,f,f");
0295: content.add(endLabel, "0,2,l,f");
0296: content.add(endDate, "2,2,f,f");
0297: content.add(endTimeLabel, "4,2,r,f");
0298: content.add(endTime, "6,2,f,f");
0299:
0300: startDate.addDateChangeListener(this );
0301: startTime.addDateChangeListener(this );
0302: endDate.addDateChangeListener(this );
0303: endTime.addDateChangeListener(this );
0304: }
0305:
0306: public JComponent getComponent() {
0307: return content;
0308: }
0309:
0310: public void dispose() {
0311: }
0312:
0313: public void dateChanged(DateChangeEvent evt) {
0314: if (!listenerEnabled)
0315: return;
0316: try {
0317: listenerEnabled = false;
0318: RaplaLocale raplaLocale = getRaplaLocale();
0319: long duration = appointment.getEnd().getTime()
0320: - appointment.getStart().getTime();
0321:
0322: if (evt.getSource() == startDate
0323: || evt.getSource() == startTime) {
0324: Date newStart = raplaLocale.toDate(startDate
0325: .getDate(), startTime.getTime());
0326: Date newEnd = new Date(newStart.getTime()
0327: + duration);
0328: endTime.setTime(newEnd);
0329: endDate.setDate(newEnd);
0330: getLogger().debug("endtime adjusted");
0331: }
0332: if (evt.getSource() == endTime) {
0333: Date newEnd = raplaLocale.toDate(endDate.getDate(),
0334: endTime.getTime());
0335: if (appointment.getStart().after(newEnd)) {
0336: newEnd = DateTools.addDay(newEnd);
0337: endDate.setDate(newEnd);
0338: endTime.setTime(newEnd);
0339: getLogger().debug("enddate adjusted");
0340: }
0341: }
0342: if (evt.getSource() == endDate) {
0343: Date newEnd = raplaLocale.toDate(endDate.getDate(),
0344: endTime.getTime());
0345: if (appointment.getStart().after(newEnd)) {
0346: Date newStart = new Date(
0347: newEnd.getTime()
0348: - (duration % DateTools.MILLISECONDS_PER_DAY));
0349: startDate.setDate(newStart);
0350: startTime.setTime(newStart);
0351: getLogger().debug("startdate adjusted");
0352: }
0353: }
0354: } finally {
0355: listenerEnabled = true;
0356: }
0357: mapToAppointment();
0358: }
0359:
0360: private void mapFromAppointment() {
0361: listenerEnabled = false;
0362: try {
0363: startDate.setDate(appointment.getStart());
0364: endDate.setDate(appointment.getEnd());
0365: startTime.setTime(appointment.getStart());
0366: endTime.setTime(appointment.getEnd());
0367: } finally {
0368: listenerEnabled = true;
0369: }
0370: }
0371:
0372: private void mapToAppointment() {
0373: RaplaLocale raplaLocale = getRaplaLocale();
0374: Date start = raplaLocale.toDate(startDate.getDate(),
0375: startTime.getTime());
0376: Date end = raplaLocale.toDate(endDate.getDate(), endTime
0377: .getTime());
0378: appointment.move(start, end);
0379: fireAppointmentChanged();
0380: }
0381:
0382: }
0383:
0384: class RepeatingEditor implements ActionListener,
0385: DateChangeListener, ChangeListener, Disposable {
0386: JPanel content = new JPanel();
0387:
0388: JPanel intervalPanel = new JPanel();
0389: JPanel weekdayInMonthPanel = new JPanel();
0390: JPanel dayInMonthPanel = new JPanel();
0391:
0392: RaplaNumber interval = new RaplaNumber(null, RaplaNumber.ONE,
0393: null, false);
0394: RaplaNumber weekdayInMonth = new RaplaNumber(null,
0395: RaplaNumber.ONE, new Integer(5), false);
0396: RaplaNumber dayInMonth = new RaplaNumber(null, RaplaNumber.ONE,
0397: new Integer(31), false);
0398:
0399: WeekdayChooser weekdayChooser = new WeekdayChooser();
0400: JLabel dayLabel = new JLabel();
0401:
0402: JLabel startTimeLabel = new JLabel();
0403: RaplaTime startTime;
0404:
0405: JLabel endTimeLabel = new JLabel();
0406: JPanel endTimePanel = new JPanel();
0407: RaplaTime endTime;
0408: public final int SAME_DAY = 0, NEXT_DAY = 1, X_DAYS = 2;
0409: JComboBox dayChooser;
0410: RaplaNumber days = new RaplaNumber(null, new Integer(2), null,
0411: false);
0412:
0413: JLabel startDateLabel = new JLabel();
0414: RaplaCalendar startDate;
0415: PeriodChooser startDatePeriod;
0416:
0417: JComboBox endingChooser;
0418: public final int REPEAT_UNTIL = 0, REPEAT_N_TIMES = 1,
0419: REPEAT_FOREVER = 2;
0420: RaplaCalendar endDate;
0421: JPanel numberPanel = new JPanel();
0422: RaplaNumber number = new RaplaNumber(null, RaplaNumber.ONE,
0423: null, false);
0424: JPanel endDatePeriodPanel = new JPanel();
0425: PeriodChooser endDatePeriod;
0426:
0427: RaplaButton exceptionButton = new RaplaButton();
0428: ExceptionEditor exceptionEditor;
0429: DialogUI exceptionDlg;
0430: MonthChooser monthChooser = new MonthChooser();
0431:
0432: boolean listenerEnabled = true;
0433:
0434: public RepeatingEditor() throws RaplaException {
0435: startDatePeriod = new PeriodChooser(getContext(),
0436: PeriodChooser.START_ONLY);
0437: endDatePeriod = new PeriodChooser(getContext(),
0438: PeriodChooser.END_ONLY);
0439: // Create a TableLayout for the frame
0440: double pre = TableLayout.PREFERRED;
0441: double fill = TableLayout.FILL;
0442: double size[][] = {
0443: { pre, 5, pre, 5, fill }, // Columns
0444: { ROW_SIZE, 18, ROW_SIZE, 5, ROW_SIZE, 15,
0445: ROW_SIZE, 6, ROW_SIZE, 0 } }; // Rows
0446: TableLayout tableLayout = new TableLayout(size);
0447: content.setLayout(tableLayout);
0448: }
0449:
0450: public Locale getLocale() {
0451: return getI18n().getLocale();
0452: }
0453:
0454: public JComponent getComponent() {
0455: return content;
0456: }
0457:
0458: public void initialize() {
0459: // Interval / Weekday
0460: interval.setColumns(2);
0461: weekdayInMonth.setColumns(2);
0462: dayInMonth.setColumns(2);
0463: intervalPanel.setLayout(new BoxLayout(intervalPanel,
0464: BoxLayout.X_AXIS));
0465: intervalPanel.add(new JLabel(
0466: getString("repeating.interval.pre") + " "));
0467: intervalPanel.add(Box.createHorizontalStrut(3));
0468: intervalPanel.add(interval);
0469: intervalPanel.add(Box.createHorizontalStrut(3));
0470: intervalPanel.add(new JLabel(
0471: getString("repeating.interval.post")));
0472:
0473: dayInMonthPanel.setLayout(new BoxLayout(dayInMonthPanel,
0474: BoxLayout.X_AXIS));
0475: //dayInMonthPanel.add(new JLabel("Am"));
0476: dayInMonthPanel.add(Box.createHorizontalStrut(35));
0477: dayInMonthPanel.add(dayInMonth);
0478: dayInMonthPanel.add(Box.createHorizontalStrut(3));
0479: dayInMonthPanel.add(new JLabel(
0480: getString("repeating.interval.post")));
0481:
0482: weekdayInMonthPanel.setLayout(new BoxLayout(
0483: weekdayInMonthPanel, BoxLayout.X_AXIS));
0484: //weekdayInMonthPanel.add(new JLabel("Am"));
0485: weekdayInMonthPanel.add(Box.createHorizontalStrut(35));
0486: weekdayInMonthPanel.add(weekdayInMonth);
0487: weekdayInMonthPanel.add(Box.createHorizontalStrut(3));
0488: weekdayInMonthPanel.add(new JLabel(
0489: getString("repeating.interval.post")));
0490:
0491: interval.addChangeListener(this );
0492: weekdayInMonth.addChangeListener(this );
0493: dayInMonth.addChangeListener(this );
0494: weekdayChooser.setLocale(getLocale());
0495: weekdayChooser.addActionListener(this );
0496: monthChooser.setLocale(getLocale());
0497: monthChooser.addActionListener(this );
0498: dayLabel.setText(getString("day") + " ");
0499: dayLabel.setVisible(false);
0500:
0501: // StartTime
0502: startTimeLabel.setText(getString("start_time"));
0503: startTime = createRaplaTime();
0504: startTime.addDateChangeListener(this );
0505:
0506: // EndTime duration
0507: endTimeLabel.setText(getString("end_time"));
0508: endTime = createRaplaTime();
0509: endTime.addDateChangeListener(this );
0510: dayChooser = new JComboBox(new String[] {
0511: getString("appointment.same_day"),
0512: getString("appointment.next_day"),
0513: getString("appointment.day_x") });
0514: dayChooser.addActionListener(this );
0515: days.setColumns(2);
0516: endTimePanel.setLayout(new TableLayout(new double[][] {
0517: { TableLayout.PREFERRED, 5, TableLayout.PREFERRED,
0518: TableLayout.FILL }, { ROW_SIZE } }));
0519: //endTimePanel.add(endTime,"0,0,l,f");
0520: endTimePanel.add(dayChooser, "0,0");
0521: endTimePanel.add(days, "2,0");
0522: days.setVisible(false);
0523: days.addChangeListener(this );
0524:
0525: // start-date (with period-box)
0526: startDatePeriod.addActionListener(this );
0527: startDateLabel.setText(getString("repeating.start_date"));
0528: startDate = createRaplaCalendar();
0529: startDate.addDateChangeListener(this );
0530:
0531: // end-date (with period-box)/n-times/forever
0532: endDatePeriod.addActionListener(this );
0533: endDate = createRaplaCalendar();
0534: endDate.addDateChangeListener(this );
0535:
0536: endingChooser = new JComboBox(new String[] {
0537: getString("repeating.end_date"),
0538: getString("repeating.n_times"),
0539: getString("repeating.forever") });
0540: endingChooser.addActionListener(this );
0541:
0542: number.setColumns(3);
0543: number.setNumber(new Integer(1));
0544: number.addChangeListener(this );
0545: numberPanel.setLayout(new BorderLayout());
0546: numberPanel.add(number, BorderLayout.WEST);
0547: numberPanel.setVisible(false);
0548: intervalPanel.setVisible(false);
0549: weekdayInMonthPanel.setVisible(false);
0550: dayInMonthPanel.setVisible(false);
0551:
0552: // exception
0553: exceptionButton.setText(getString("appointment.exceptions")
0554: + " (0)");
0555: exceptionButton.addActionListener(this );
0556:
0557: content.add(intervalPanel, "0,0,l,f");
0558: content.add(weekdayInMonthPanel, "0,0,l,f");
0559: content.add(dayInMonthPanel, "0,0,l,f");
0560: content.add(weekdayChooser, "2,0,f,f");
0561: content.add(monthChooser, "2,0,f,f");
0562: content.add(dayLabel, "2,0,l,f");
0563:
0564: content.add(startTimeLabel, "0,2,l,f");
0565: content.add(startTime, "2,2,f,f");
0566:
0567: content.add(exceptionButton, "4,0,r,t");
0568:
0569: content.add(endTimeLabel, "0,4,l,f");
0570: content.add(endTime, "2,4,f,f");
0571: content.add(endTimePanel, "4,4,4,4,l,f");
0572:
0573: content.add(startDateLabel, "0,6,l,f");
0574: content.add(startDate, "2,6,l,f");
0575: content.add(startDatePeriod, "4,6,f,f");
0576:
0577: content.add(endingChooser, "0,8,l,f");
0578: content.add(endDate, "2,8,l,f");
0579: content.add(endDatePeriodPanel, "4,8,f,f");
0580: // We must surround the endDatePeriod with a panel to
0581: // separate visiblity of periods from visibility of the panel
0582: endDatePeriodPanel.setLayout(new BorderLayout());
0583: endDatePeriodPanel.add(endDatePeriod, BorderLayout.CENTER);
0584: content.add(numberPanel, "2,8,f,f");
0585:
0586: //content.add(exceptionLabel,"0,10,l,c");
0587: //content.add(exceptionPanel,"2,10,4,10,l,c");
0588: }
0589:
0590: public void dispose() {
0591: endDatePeriod.removeActionListener(this );
0592: startDatePeriod.removeActionListener(this );
0593: }
0594:
0595: private Date getStart() {
0596: Date start = getRaplaLocale().toDate(startDate.getDate(),
0597: startTime.getTime());
0598: /*
0599: if (repeating.isWeekly() || repeating.isMonthly()) {
0600: Calendar calendar = getRaplaLocale().createCalendar();
0601: calendar.setTime(start);
0602: calendar.set(Calendar.DAY_OF_WEEK, weekdayChooser.getSelectedWeekday() );
0603: if (calendar.getTime().before(start)) {
0604: calendar.add(Calendar.DAY_OF_WEEK,7);
0605: }
0606: start = calendar.getTime();
0607: }
0608: if (repeating.isYearly()) {
0609: Calendar calendar = getRaplaLocale().createCalendar();
0610: calendar.setTime(start);
0611: calendar.set(Calendar.MONTH, monthChooser.getSelectedMonth() );
0612: calendar.set(Calendar.DAY_OF_MONTH, dayInMonth.getNumber().intValue() );
0613: start = calendar.getTime();
0614:
0615: }
0616: */
0617: return start;
0618: }
0619:
0620: private Date getEnd() {
0621: Date end = getRaplaLocale().toDate(getStart(),
0622: endTime.getTime());
0623: if (dayChooser.getSelectedIndex() == NEXT_DAY)
0624: end = DateTools.addDay(end);
0625: if (dayChooser.getSelectedIndex() == X_DAYS)
0626: end = DateTools.addDays(end, days.getNumber()
0627: .intValue());
0628: return end;
0629: }
0630:
0631: public void actionPerformed(ActionEvent evt) {
0632: if (evt.getSource() == exceptionButton) {
0633: try {
0634: showExceptionDlg();
0635: } catch (RaplaException ex) {
0636: showException(ex, content);
0637: }
0638: return;
0639: }
0640:
0641: if (!listenerEnabled)
0642: return;
0643: try {
0644: listenerEnabled = false;
0645:
0646: if (evt.getSource() == weekdayChooser) {
0647: Calendar calendar = getRaplaLocale()
0648: .createCalendar();
0649: calendar.setTime(startDate.getDate());
0650: calendar.set(Calendar.DAY_OF_WEEK, weekdayChooser
0651: .getSelectedWeekday());
0652: startDate.setDate(calendar.getTime());
0653: }
0654:
0655: if (evt.getSource() == monthChooser) {
0656: Calendar calendar = getRaplaLocale()
0657: .createCalendar();
0658: calendar.setTime(startDate.getDate());
0659: calendar.set(Calendar.MONTH, monthChooser
0660: .getSelectedMonth());
0661: calendar.set(Calendar.DAY_OF_MONTH, dayInMonth
0662: .getNumber().intValue());
0663: startDate.setDate(calendar.getTime());
0664: }
0665:
0666: if (evt.getSource() == dayChooser) {
0667: if (dayChooser.getSelectedIndex() == SAME_DAY) {
0668: if (getEnd().before(getStart())) {
0669: endTime.setTime(getStart());
0670: getLogger().debug("endtime adjusted");
0671: }
0672: }
0673: }
0674:
0675: if (evt.getSource() == startDatePeriod
0676: && startDatePeriod.getPeriod() != null) {
0677: Calendar calendar = getRaplaLocale()
0678: .createCalendar();
0679: calendar.setTime(startDatePeriod.getPeriod()
0680: .getStart());
0681: if (repeating.isWeekly() || repeating.isMonthly()) {
0682: calendar.set(Calendar.DAY_OF_WEEK,
0683: weekdayChooser.getSelectedWeekday());
0684: if (calendar.getTime().before(
0685: startDatePeriod.getPeriod().getStart())) {
0686: calendar.add(Calendar.DAY_OF_WEEK, 7);
0687: }
0688: }
0689: getLogger().debug("startdate adjusted to period");
0690: startDate.setDate(calendar.getTime());
0691: endDatePeriod.setSelectedPeriod(startDatePeriod
0692: .getPeriod());
0693: }
0694:
0695: if (evt.getSource() == endDatePeriod
0696: && endDatePeriod.getDate() != null) {
0697: endDate.setDate(DateTools.subDay(endDatePeriod
0698: .getDate()));
0699: getLogger().debug("enddate adjusted to period");
0700: }
0701:
0702: mapToAppointment();
0703: mapFromAppointment();
0704: } finally {
0705: listenerEnabled = true;
0706: }
0707: }
0708:
0709: public void stateChanged(ChangeEvent evt) {
0710: if (!listenerEnabled)
0711: return;
0712: try {
0713: listenerEnabled = false;
0714:
0715: if (evt.getSource() == weekdayInMonth
0716: && repeating.isMonthly()) {
0717: Number weekdayOfMonthValue = weekdayInMonth
0718: .getNumber();
0719: if (weekdayOfMonthValue != null
0720: && repeating.isMonthly()) {
0721: Calendar cal = getRaplaLocale()
0722: .createCalendar();
0723: cal.setTime(appointment.getStart());
0724: cal.set(Calendar.DAY_OF_WEEK_IN_MONTH,
0725: weekdayOfMonthValue.intValue());
0726: startDate.setDate(cal.getTime());
0727: }
0728: }
0729: if (evt.getSource() == dayInMonth
0730: && repeating.isYearly()) {
0731: Number dayOfMonthValue = dayInMonth.getNumber();
0732: if (dayOfMonthValue != null && repeating.isYearly()) {
0733: Calendar cal = getRaplaLocale()
0734: .createCalendar();
0735: cal.setTime(appointment.getStart());
0736: cal.set(Calendar.DAY_OF_MONTH, dayOfMonthValue
0737: .intValue());
0738: startDate.setDate(cal.getTime());
0739: }
0740: }
0741:
0742: mapToAppointment();
0743: mapFromAppointment();
0744: } finally {
0745: listenerEnabled = true;
0746: }
0747: }
0748:
0749: public void dateChanged(DateChangeEvent evt) {
0750: if (!listenerEnabled)
0751: return;
0752: try {
0753: listenerEnabled = false;
0754:
0755: long duration = appointment.getEnd().getTime()
0756: - appointment.getStart().getTime();
0757: if (evt.getSource() == startTime) {
0758: Date newEnd = new Date(getStart().getTime()
0759: + duration);
0760: endTime.setTime(newEnd);
0761: getLogger().debug("endtime adjusted");
0762: }
0763:
0764: if (evt.getSource() == endTime) {
0765: Date newEnd = getEnd();
0766: if (getStart().after(newEnd)) {
0767: newEnd = DateTools.addDay(newEnd);
0768: endTime.setTime(newEnd);
0769: getLogger().debug("enddate adjusted");
0770: }
0771: }
0772: mapToAppointment();
0773: mapFromAppointment();
0774: } finally {
0775: listenerEnabled = true;
0776: }
0777: }
0778:
0779: private void mapToAppointment() {
0780: int index = endingChooser.getSelectedIndex();
0781: Number intervalValue = interval.getNumber();
0782: if (intervalValue != null)
0783: repeating.setInterval(intervalValue.intValue());
0784: else
0785: repeating.setInterval(1);
0786:
0787: if (index == REPEAT_UNTIL) {
0788: repeating.setEnd(DateTools.addDay(endDate.getDate()));
0789: } else if (index == REPEAT_N_TIMES) {
0790: Number numberValue = number.getNumber();
0791: if (number != null)
0792: repeating.setNumber(numberValue.intValue());
0793: else
0794: repeating.setNumber(1);
0795: } else {
0796: repeating.setEnd(null);
0797: repeating.setNumber(-1);
0798: }
0799: appointment.move(getStart(), getEnd());
0800: fireAppointmentChanged();
0801: }
0802:
0803: private void updateExceptionCount() {
0804: int count = repeating.getExceptions().length;
0805: if (count > 0) {
0806: exceptionButton.setForeground(Color.red);
0807: } else {
0808: exceptionButton.setForeground(UIManager
0809: .getColor("Label.foreground"));
0810: }
0811: String countValue = String.valueOf(count);
0812: if (count < 9) {
0813: countValue = " " + countValue + " ";
0814: }
0815: exceptionButton.setText(getString("appointment.exceptions")
0816: + " (" + countValue + ")");
0817: }
0818:
0819: private void showEnding(int index) {
0820: if (index == REPEAT_UNTIL) {
0821: endDate.setVisible(true);
0822: endDatePeriodPanel.setVisible(true);
0823: numberPanel.setVisible(false);
0824: }
0825: if (index == REPEAT_N_TIMES) {
0826: endDate.setVisible(false);
0827: endDatePeriodPanel.setVisible(false);
0828: numberPanel.setVisible(true);
0829: }
0830: if (index == REPEAT_FOREVER) {
0831: endDate.setVisible(false);
0832: endDatePeriodPanel.setVisible(false);
0833: numberPanel.setVisible(false);
0834: }
0835: }
0836:
0837: private void mapFromAppointment() {
0838: if (exceptionDlg != null && exceptionDlg.isVisible())
0839: exceptionDlg.dispose();
0840: repeating = appointment.getRepeating();
0841: if (repeating == null) {
0842: return;
0843: }
0844: listenerEnabled = false;
0845: try {
0846: updateExceptionCount();
0847: if (exceptionEditor != null)
0848: exceptionEditor.mapFromAppointment();
0849:
0850: interval
0851: .setNumber(new Integer(repeating.getInterval()));
0852:
0853: startDate.setDate(appointment.getStart());
0854: startDatePeriod.setDate(appointment.getStart());
0855: startTime.setTime(appointment.getStart());
0856: endTime.setTime(appointment.getEnd());
0857:
0858: weekdayInMonthPanel.setVisible(repeating.isMonthly());
0859: intervalPanel.setVisible(repeating.isDaily()
0860: || repeating.isWeekly());
0861: dayInMonthPanel.setVisible(repeating.isYearly());
0862:
0863: if (repeating.getEnd() != null) {
0864: endDate.setDate(DateTools
0865: .subDay(repeating.getEnd()));
0866: endDatePeriod.setDate(DateTools.cutDate(endDate
0867: .getDate()));
0868: number
0869: .setNumber(new Integer(repeating
0870: .getNumber()));
0871: if (!repeating.isFixedNumber()) {
0872: endingChooser.setSelectedIndex(REPEAT_UNTIL);
0873: showEnding(REPEAT_UNTIL);
0874: } else {
0875: endingChooser.setSelectedIndex(REPEAT_N_TIMES);
0876: showEnding(REPEAT_N_TIMES);
0877: }
0878: } else {
0879: endingChooser.setSelectedIndex(REPEAT_FOREVER);
0880: showEnding(REPEAT_FOREVER);
0881: }
0882:
0883: startDatePeriod.setVisible(repeating.isDaily()
0884: || repeating.isWeekly());
0885: endDatePeriod.setVisible(repeating.isDaily()
0886: || repeating.isWeekly());
0887: if (repeating.isWeekly() || repeating.isMonthly()) {
0888: dayLabel.setVisible(false);
0889: weekdayChooser.setVisible(true);
0890: monthChooser.setVisible(false);
0891: Calendar calendar = getRaplaLocale()
0892: .createCalendar();
0893: calendar.setTime(appointment.getStart());
0894: weekdayChooser.selectWeekday(calendar
0895: .get(Calendar.DAY_OF_WEEK));
0896: }
0897:
0898: if (repeating.isYearly()) {
0899: dayLabel.setVisible(false);
0900: weekdayChooser.setVisible(false);
0901: monthChooser.setVisible(true);
0902: Calendar cal = getRaplaLocale().createCalendar();
0903: cal.setTime(appointment.getStart());
0904: monthChooser.selectMonth(cal.get(Calendar.MONTH));
0905: int numb = cal.get(Calendar.DAY_OF_MONTH);
0906: dayInMonth.setNumber(new Integer(numb));
0907: }
0908:
0909: if (repeating.isMonthly()) {
0910: Calendar cal = getRaplaLocale().createCalendar();
0911: cal.setTime(appointment.getStart());
0912: int numb = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
0913: weekdayInMonth.setNumber(new Integer(numb));
0914: }
0915:
0916: if (repeating.isDaily()) {
0917: dayLabel.setVisible(true);
0918: weekdayChooser.setVisible(false);
0919: monthChooser.setVisible(false);
0920: }
0921:
0922: int daysBetween = (int) DateTools.countDays(appointment
0923: .getStart(), appointment.getEnd());
0924: if (daysBetween == 0) {
0925: dayChooser.setSelectedIndex(SAME_DAY);
0926: days.setVisible(false);
0927: } else if (daysBetween == 1) {
0928: dayChooser.setSelectedIndex(NEXT_DAY);
0929: days.setVisible(false);
0930: } else {
0931: dayChooser.setSelectedIndex(X_DAYS);
0932: days.setNumber(new Integer(daysBetween));
0933: days.setVisible(true);
0934: }
0935: } finally {
0936: listenerEnabled = true;
0937: }
0938: getComponent().revalidate();
0939: }
0940:
0941: private void showExceptionDlg() throws RaplaException {
0942: exceptionEditor = new ExceptionEditor();
0943: exceptionEditor.initialize();
0944: exceptionEditor.mapFromAppointment();
0945: exceptionEditor.getComponent().setBorder(
0946: BorderFactory.createEmptyBorder(5, 5, 5, 5));
0947: exceptionDlg = DialogUI.create(getContext(),
0948: getComponent(), true, exceptionEditor
0949: .getComponent(),
0950: new String[] { getString("back") });
0951: exceptionDlg.setTitle(getString("appointment.exceptions"));
0952: exceptionDlg.start();
0953: updateExceptionCount();
0954: }
0955: }
0956:
0957: class ExceptionEditor implements ActionListener,
0958: ListSelectionListener {
0959: JPanel content = new JPanel();
0960: RaplaCalendar exceptionDate;
0961: RaplaButton addButton = new RaplaButton(RaplaButton.SMALL);
0962: RaplaButton removeButton = new RaplaButton(RaplaButton.SMALL);
0963: JList specialExceptions = new JList();
0964: JList generalExceptions = new JList(new String[] { "Feiertage",
0965: "Dies academicus" });
0966:
0967: public ExceptionEditor() {
0968: // Create a TableLayout for the frame
0969: double pre = TableLayout.PREFERRED;
0970: double min = TableLayout.MINIMUM;
0971: double fill = TableLayout.FILL;
0972: double yborder = 8;
0973: double size[][] = { { pre, pre, 0.1, 50, 100, 0.9 }, // Columns
0974: { yborder, min, min, fill } }; // Rows
0975: TableLayout tableLayout = new TableLayout(size);
0976: content.setLayout(tableLayout);
0977: }
0978:
0979: public JComponent getComponent() {
0980: return content;
0981: }
0982:
0983: public void initialize() {
0984: addButton.setText(getString("add"));
0985: addButton.setIcon(getIcon("icon.arrow_right"));
0986: removeButton.setText(getString("remove"));
0987: removeButton.setIcon(getIcon("icon.arrow_left"));
0988: exceptionDate = createRaplaCalendar();
0989: /*
0990: this.add(new JLabel(getString("appointment.exception.general") + " "),"0,1");
0991: this.add(new JScrollPane(generalExceptions
0992: ,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
0993: ,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
0994: ,"1,1,1,3,t");
0995: */
0996: JLabel label = new JLabel(
0997: getString("appointment.exception.days") + " ");
0998: label.setHorizontalAlignment(SwingConstants.RIGHT);
0999: content.add(label, "3,1,4,1,r,t");
1000: content.add(exceptionDate, "5,1,l,t");
1001: content.add(addButton, "4,2,f,t");
1002: content.add(removeButton, "4,3,f,t");
1003: content.add(new JScrollPane(specialExceptions,
1004: JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
1005: JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
1006: "5,2,5,3,t");
1007: generalExceptions.setEnabled(false);
1008:
1009: addButton.addActionListener(this );
1010: removeButton.addActionListener(this );
1011: specialExceptions.addListSelectionListener(this );
1012: removeButton.setEnabled(false);
1013: specialExceptions.setFixedCellWidth(200);
1014: specialExceptions
1015: .setCellRenderer(new DefaultListCellRenderer() {
1016: private static final long serialVersionUID = 1L;
1017:
1018: public Component getListCellRendererComponent(
1019: JList list, Object value, int index,
1020: boolean isSelected, boolean cellHasFocus) {
1021: if (value instanceof Date)
1022: value = getRaplaLocale()
1023: .formatDateLong((Date) value);
1024: return super .getListCellRendererComponent(
1025: list, value, index, isSelected,
1026: cellHasFocus);
1027: }
1028: });
1029: specialExceptions.addMouseListener(new MouseAdapter() {
1030: public void mouseClicked(MouseEvent evt) {
1031: if (evt.getClickCount() > 1) {
1032: removeException();
1033: }
1034: }
1035: });
1036: }
1037:
1038: public void mapFromAppointment() {
1039: if (appointment.getRepeating() == null)
1040: specialExceptions.setListData(new Object[0]);
1041: else
1042: specialExceptions.setListData(appointment
1043: .getRepeating().getExceptions());
1044: }
1045:
1046: public void actionPerformed(ActionEvent evt) {
1047: if (evt.getSource() == addButton) {
1048: addException();
1049: }
1050: if (evt.getSource() == removeButton) {
1051: removeException();
1052: }
1053: }
1054:
1055: private void addException() {
1056: Date date = exceptionDate.getDate();
1057: if (appointment.getRepeating().isException(date.getTime())) {
1058: return;
1059: }
1060: appointment.getRepeating().addException(date);
1061: specialExceptions.setListData(appointment.getRepeating()
1062: .getExceptions());
1063: fireAppointmentChanged();
1064: }
1065:
1066: private void removeException() {
1067: if (specialExceptions.getSelectedValue() == null)
1068: return;
1069: appointment.getRepeating().removeException(
1070: (Date) specialExceptions.getSelectedValue());
1071: specialExceptions.setListData(appointment.getRepeating()
1072: .getExceptions());
1073: fireAppointmentChanged();
1074: }
1075:
1076: public void valueChanged(ListSelectionEvent e) {
1077: if (e.getSource() == specialExceptions) {
1078: removeButton.setEnabled(specialExceptions
1079: .getSelectedValue() != null);
1080: }
1081: }
1082: }
1083: }
|