Subversion Repository Public Repository

litesoft

1
// This Source Code is Copyright & Licenced as indicated below
package org.litesoft.GWT.forms.client.components.nonpublic.datepicker;
/*
 * Copyright 2007 Google Inc.
 *
 * 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.
 */

import java.util.*;

import org.litesoft.GWT.forms.client.components.nonpublic.datepicker.impl.*;

import com.google.gwt.user.client.ui.*;

/**
 * DatePicker widget displays a small Gregorian calendar dates to select
 * a date by the user.
 * <p/>
 * <p>It has following features:
 * <p/>
 * <ul>
 * <li>Fully internationalized by default locale</li>
 * <li>Optional display of dates form the adjacent dates months</li>
 * <li>Add a special formatting for a given day</li>
 * <li>Select any date as the start date and month.
 * Today's date is the default selection and the default displayed month.</li>
 * </ul>
 * </p>
 * <p>CSS hooks:
 * <table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0">
 * <tbody>
 * <tr>
 * <td style="FONT-WEIGHT:bold">
 * Style name<br/>
 * </td>
 * <td style="FONT-WEIGHT:bold">
 * Widget region affected<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker<br/>
 * </td>
 * <td>
 * Entire widget<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .grid<br/>
 * </td>
 * <td>
 * Grid in the DatePicker.
 * This includes week names and the date numbers.<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .title<br/>
 * </td>
 * <td>
 * Month and Year titles on the top<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .control<br/>
 * </td>
 * <td>
 * Month and year increment and decrement buttons<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .control-menu<br/>
 * </td>
 * <td>
 * Month and year list available by clicking on them<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .control-block<br/>
 * </td>
 * <td>
 * The block of month/year display with its
 * increment decrement controls<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .control-pane<br/>
 * </td>
 * <td>
 * Top area containing month and year controls<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .control-today<br/>
 * </td>
 * <td>
 * Clickable today button<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .weekday<br/>
 * </td>
 * <td>
 * Any date<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .week-names<br/>
 * </td>
 * <td>
 * Weekday names<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .week-numbers<br/>
 * </td>
 * <td>
 * Week of the year number<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .weekend-start<br/>
 * </td>
 * <td>
 * Weekend startdate<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .weekend-end<br/>
 * </td>
 * <td>
 * Weekend end date<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .today<br/>
 * </td>
 * <td>
 * Special formatting for today
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .selected<br/>
 * </td>
 * <td>
 * Special formatting for the selected date<br/>
 * </td>
 * </tr>
 * <tr>
 * <td>
 * .goog-date-picker .other-month
 * </td>
 * <td>
 * Opacity reducing formatting for the adjacent months<br/>
 * </td>
 * </tr>
 * </tbody>
 * </table>
 * </p>
 * <p>Following are the incomplete features.
 * Some components of these features exist.
 * However, they do not function completely.
 * <ul>
 * <li>Optional display week numbers</li>
 * </ul>
 * </p>
 * <p>Desired features
 * <ul>
 * <li>Disable calendar functions beyond an end date.
 * This is useful when document archives. Default today.</li>
 * <li>Disable calendar functions beyond an start date.
 * This is useful for reservation systems. Default today.</li>
 * <li>Disable calendar functions on a specific date.
 * This is useful for reservation systems.</li>
 * <li>Right to Left layout depending on the page layout.</li>
 * </ul>
 * </p>
 */

@Deprecated
public class DatePicker extends DialogBox implements ClickListener,
                                                     ChangeListener,
                                                     SourcesChangeEvents
{

    private static final String STYLE_DATE_PICKER = "goog-date-picker";
    private static final String STYLE_GRID = "grid";

    private static final String STYLE_CONTROL = "control";
    private static final String STYLE_CONTROL_BLOCK = "control-block";
    private static final String STYLE_CONTROL_PANE = "control-pane";
    private static final String STYLE_CONTROL_MENU = "control-menu";
    private static final String STYLE_CONTROL_TODAY = "control-today";
    private static final String STYLE_TITLE = "title";

    private static final String STYLE_WEEK_NAMES = "week-names";
    private static final String STYLE_WEEK_NUMBERS = "numbers";

    private static final String STYLE_WEEKDAY = "weekday";
    private static final String STYLE_WEEKEND_START = "weekend-start";
    private static final String STYLE_WEEKEND_END = "weekend-end";
    private static final String STYLE_OTHER_MONTHS = "other-month";

    private static final String STYLE_TODAY = "today";
    private static final String STYLE_SELECTED = "selected";

    // Unique numbers representing various actions available in the controls.
    private static final int ACTION_PREV_MONTH = 0;
    private static final int ACTION_SET_MONTH = 1;
    private static final int ACTION_NEXT_MONTH = 2;
    private static final int ACTION_PREV_YEAR = 3;
    private static final int ACTION_SET_YEAR = 4;
    private static final int ACTION_NEXT_YEAR = 5;
    private static final int ACTION_TODAY = 6;
    private static final int ACTION_CLOSE = 7;

    // Unique numbers representing formating actions.
    private static final int FORMAT_ACTION_REMOVE = 0;
    private static final int FORMAT_ACTION_ADD = 1;

    private LocaleCalendarUtils dateTable;

    private ChangeListenerCollection changeListeners = new ChangeListenerCollection();

    private HorizontalPanel control = new HorizontalPanel();
    private FlexTable grid;

    // menu based action

    private int weekOfYearOffset = 0;
    private boolean showYearMonthListing = true;
    private boolean showTodayButton = false;
    private int monthAction;
    private int yearAction;

    private DatePickerCell today;
    private final VerticalPanel panel = new VerticalPanel();

    private int prevMonthSize;
    private int prevMonthDays;
    private int currMonthSize;
    private int nextMonthDays;
    private int gridStart;

    /**
     * Constructor of the DatePicker class.
     */
    public DatePicker()
    {

        super( true ); // hide dialogue box when clicked outside

        dateTable = new LocaleCalendarUtils( false );
        dateTable.specialDate( LocaleCalendarUtils.TODAY ).setTag( STYLE_TODAY );
        dateTable.specialDate( LocaleCalendarUtils.SELECTED ).setTag( STYLE_SELECTED );

        grid = new FlexTable();
        grid.setWidth( "100%" );
        grid.setStyleName( STYLE_GRID );

        panel.addStyleName( STYLE_DATE_PICKER );
        panel.setHorizontalAlignment( VerticalPanel.ALIGN_CENTER );

        drawControlPane();
        panel.add( control );

        // grid operations
        addDaysOfWeek();
        initialGrid();
        gridUpdate();

        panel.add( grid );

        // today label
        today = dateTable.todayCell();
        today.setValue( ACTION_TODAY );
        today.addStyleName( STYLE_CONTROL_TODAY );
        today.addClickListener( this );
        enableTodayButton();

        super.setWidget( panel );
    }

    /**
     * Public method complete ClickListner interface. This adds a listener to the
     * listeners for Change events. Namely, a date clicked by the user.
     *
     * @param listener - listener for events
     */
    public void addChangeListener( ChangeListener listener )
    {
        changeListeners.add( listener );
    }

    /**
     * Public method onChange which is fired when user clicks on the
     * list menu in the widget.
     *
     * @param sender - widget on which user clicked.
     */
    public void onChange( Widget sender )
    {

        if ( sender instanceof ListBox )
        {

            ListBox list = (ListBox) sender;
            String val = list.getValue( list.getSelectedIndex() );
            int ival = Integer.valueOf( val ).intValue();

            if ( list == dateTable.monthNames() )
            {
                action( monthAction, ival );
            }
            else
            {
                action( yearAction, ival );
            }

            changeListeners.fireChange( this );
        }
    }

    /**
     * Public method onClick which is fired when user clicks on the widget.
     *
     * @param sender - widget on which user clicked.
     */
    public void onClick( Widget sender )
    {

        if ( sender instanceof DatePickerCell )
        {

            DatePickerCell cell = (DatePickerCell) sender;
            int type = cell.type();
            int value = cell.value();

            if ( type == LocaleCalendarUtils.TYPE_CONTROL )
            {
                action( value );
            }
            else
            {
                formatSpecialDates( FORMAT_ACTION_REMOVE );

                dateTable.selectedDate( type, value );

                if ( type == LocaleCalendarUtils.TYPE_CURR_MONTH )
                {
                    formatSpecialDates( FORMAT_ACTION_ADD );
                }
                else
                {
                    gridUpdate();
                }
            }
            changeListeners.fireChange( this );
        }
    }

    /**
     * Public method removeChangeListener() removes a element from the list of
     * listeners which will get fired on an widget change event. Example for
     * listener change event is user click on a date.
     *
     * @param listener - listener for widget change events
     */
    public void removeChangeListener( ChangeListener listener )
    {
        changeListeners.remove( listener );
    }

    /**
     * Public method to get the value of the user selected date for the
     * DatePicker object.
     *
     * @return Date - value of the selected date
     */
    public Date selectedDate()
    {
        return dateTable;
    }

    /**
     * Public method to set the default day and date of the widget.
     * Date picker for the given month and year will be displayed.
     * The given date will be marked as the selected date.
     *
     * @param date - Java Date value to be set
     */
    public void setFullDate( Date date )
    {
        formatSpecialDates( FORMAT_ACTION_REMOVE );
        dateTable.setFullDate( date );
        gridUpdate();
    }

    /**
     * Public method to set a given special formatting for the given date.
     *
     * @param date  - Date to be formatted specially
     * @param style - CSS style to be used
     */
    public void setSpecialDate( Date date, String style )
    {
        DatePickerDate specialDay = dateTable.addSpecialDay( date );
        specialDay.setTag( style );
        formatSpecialDates( FORMAT_ACTION_ADD );
    }

    /**
     * Public method to enable or disable displaying the trailing
     * and leading dates from previous and next months.
     *
     * @param show - A boolean indicating whether to show or not
     */
    public void showAdjacentMonths( boolean show )
    {
        dateTable.enableAdjacentMonths( show );
        gridUpdate();
    }

    /**
     * Public method to display the listing of adjacent months and years by
     * clicking on the month or year in the title.
     *
     * @param show - A boolean indicating whether to show or not
     */
    public void showTodayButton( boolean show )
    {
        this.showTodayButton = show;

        enableTodayButton();
    }

    /**
     * Public method to enable or disable displaying the week number of the year.
     * (implementation not completed)
     *
     * @param show - A boolean indicating whether to show or not
     */
    public void showWeekOfYear( boolean show )
    {
        this.weekOfYearOffset = show ? 1 : 0;
        gridUpdate();
    }

    /**
     * Public method to display the listing of adjacent months and years by
     * clicking on the month or year in the title.
     *
     * @param show - A boolean indicating whether to show or not
     */
    public void showYearMonthListing( boolean show )
    {
        this.showYearMonthListing = show;
        drawControlPane();
    }

    private void action( int actionNum, int arg )
    {
        formatSpecialDates( FORMAT_ACTION_REMOVE );
        switch ( actionNum )
        {
            case ACTION_SET_MONTH:
                dateTable.setMonth( arg );
                break;
            case ACTION_SET_YEAR:
                dateTable.setYear( arg );
                break;
        }
        gridUpdate();
    }

    private void action( int actionNum )
    {

        if ( actionNum == ACTION_CLOSE )
        {
            this.hide();
        }
        else
        {
            formatSpecialDates( FORMAT_ACTION_REMOVE );
            switch ( actionNum )
            {
                case ACTION_PREV_MONTH:
                    dateTable.addMonths( -1 );
                    break;
                case ACTION_NEXT_MONTH:
                    dateTable.addMonths( 1 );
                    break;
                case ACTION_PREV_YEAR:
                    dateTable.addMonths( -12 );
                    break;
                case ACTION_NEXT_YEAR:
                    dateTable.addMonths( 12 );
                    break;
                case ACTION_TODAY:
                    dateTable.setToday();
                    break;
            }
            gridUpdate();
        }
    }

    private void addDaysOfWeek()
    {

        String[] dayOfWeekNames = LocaleCalendarUtils.dayOfWeekNames();

        for ( int col = 0; col < 7; col++ )
        {
            int dayOfWeek = (col + dateTable.weekStart()) % 7;
            grid.setText( 0, col + weekOfYearOffset, dayOfWeekNames[dayOfWeek] );
            grid.getCellFormatter().setStyleName( 0, col + weekOfYearOffset, STYLE_WEEK_NAMES );
        }
    }

    private void addWeekOfYear()
    {

        String[] weekOfYear = dateTable.weekOfYear();

        for ( int row = 0; row < 7; row++ )
        {
            grid.setText( row + 1, 0, weekOfYear[row] );
            grid.getCellFormatter().addStyleName( row + 1, 0, STYLE_WEEK_NUMBERS );
        }
    }

    private void colFormat( int tableRow, int tableCol, int weekendStart, int weekendEnd, DatePickerCell w )
    {
        String style;

        if ( tableCol == (weekendStart + weekOfYearOffset) )
        {
            style = STYLE_WEEKEND_START;
        }
        else if ( tableCol == (weekendEnd + weekOfYearOffset) )
        {
            style = STYLE_WEEKEND_END;
        }
        else
        {
            style = STYLE_WEEKDAY;
        }
        w.setStyleName( style );
        grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
    }

    private void dateFormat( int diffFromMonthStart, String style, int action )
    {

        if ( diffFromMonthStart < -prevMonthDays || diffFromMonthStart >= currMonthSize + nextMonthDays )
        {
            return;
        }

        int i = diffFromMonthStart + prevMonthDays + gridStart;

        int row = i / 7;
        int col = i % 7;
        int tableRow = row + 1;
        int tableCol = col + weekOfYearOffset;

        switch ( action )
        {
            case FORMAT_ACTION_REMOVE:
                grid.getCellFormatter().removeStyleName( tableRow, tableCol, style );
                grid.getWidget( tableRow, tableCol ).removeStyleName( style );
                break;
            case FORMAT_ACTION_ADD:
                grid.getCellFormatter().addStyleName( tableRow, tableCol, style );
                grid.getWidget( tableRow, tableCol ).addStyleName( style );
                break;
        }
    }

    private void drawControlPane()
    {
        control.clear();
        control.setWidth( "100%" );
        control.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
        control.addStyleName( STYLE_CONTROL_PANE );

        Widget yearControl = drawControls( dateTable.yearNames(), dateTable.yearName(), ACTION_PREV_YEAR, ACTION_NEXT_YEAR, ACTION_SET_YEAR );
        Widget monthControl = drawControls( dateTable.monthNames(), dateTable.monthName(), ACTION_PREV_MONTH, ACTION_NEXT_MONTH, ACTION_SET_MONTH );

        if ( dateTable.isYearBeforeMonth() )
        {
            control.add( yearControl );
            control.add( monthControl );
        }
        else
        {
            control.add( monthControl );
            control.add( yearControl );
        }
    }

    private Widget drawControls( ListBox names, Label name, int prev, int next, int set )
    {

        HorizontalPanel hp = new HorizontalPanel();
        hp.setHorizontalAlignment( HorizontalPanel.ALIGN_CENTER );
        hp.addStyleName( STYLE_CONTROL_BLOCK );

        if ( names == dateTable.monthNames() )
        {
            monthAction = set;
        }
        else
        {
            yearAction = set;
        }

        // move left
        if ( !showYearMonthListing || set == ACTION_SET_MONTH )
        {
            DatePickerCell left = new DatePickerCell( "\u00ab" ); // \u00ab is <<
            left.setType( LocaleCalendarUtils.TYPE_CONTROL );
            left.setValue( prev );
            left.addStyleName( STYLE_CONTROL );
            left.addClickListener( this );
            hp.add( left );
        }

        // Need list box or not
        if ( showYearMonthListing )
        {

            names.setVisibleItemCount( 1 );
            names.addStyleName( STYLE_CONTROL_MENU );
            names.addChangeListener( this );

            hp.add( names );
        }
        else
        {

            name.addStyleName( STYLE_TITLE );
            hp.add( name );
        }

        // move right
        if ( !showYearMonthListing || set == ACTION_SET_MONTH )
        {
            DatePickerCell right = new DatePickerCell( "\u00bb" ); // \u00ab is >>
            right.setType( LocaleCalendarUtils.TYPE_CONTROL );
            right.setValue( next );
            right.addStyleName( STYLE_CONTROL );
            right.addClickListener( this );
            hp.add( right );
        }

        return hp;
    }

    private void enableTodayButton()
    {
        if ( showTodayButton )
        {
            panel.add( today );
        }
        else
        {
            panel.remove( today );
        }
    }

    private void formatSpecialDates( int action )
    {
        int numSpecialDays = dateTable.numSpecialDays();

        for ( int i = 0; i < numSpecialDays; i++ )
        {
            DatePickerDate date = dateTable.specialDate( i );
            dateFormat( date.dayDiff(), date.tag(), action );
        }
    }

    private void gridUpdate()
    {

        DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();
        DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
        DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();

        prevMonthSize = dateTable.prevMonthSize();
        prevMonthDays = dateTable.prevMonthDays();
        currMonthSize = dateTable.currMonthSize();
        nextMonthDays = dateTable.nextMonthDays();
        gridStart = dateTable.gridStart();
        int weekendStart = dateTable.weekendStart();
        int weekendEnd = dateTable.weekendEnd();

        if ( weekOfYearOffset > 0 )
        {
            addWeekOfYear();
        }

        int rowCount = grid.getRowCount();
        for ( int i = rowCount - 1; i > 0; i-- )
        { // 0th row is the week names
            grid.removeRow( i );
        }

        for ( int i = 0; i < prevMonthDays; i++ )
        {
            int row = i / 7;
            int col = i % 7;
            int tableRow = row + 1;
            int tableCol = col + weekOfYearOffset;
            int dayOfMonth = prevMonthSize - prevMonthDays + i; // 0 based

            colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesPrev[dayOfMonth] );
            grid.setWidget( tableRow, tableCol, dayOfMonthNamesPrev[dayOfMonth] );
            grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
        }

        for ( int i = 0; i < currMonthSize; i++ )
        {
            int row = (gridStart + prevMonthDays + i) / 7;
            int col = (gridStart + prevMonthDays + i) % 7;
            int tableRow = row + 1;
            int tableCol = col + weekOfYearOffset;

            colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNames[i] );
            grid.setWidget( tableRow, tableCol, dayOfMonthNames[i] );
        }

        for ( int i = 0; i < nextMonthDays; i++ )
        {
            int row = (currMonthSize + prevMonthDays + i) / 7;
            int col = (currMonthSize + prevMonthDays + i) % 7;
            int tableRow = row + 1;
            int tableCol = col + weekOfYearOffset;

            colFormat( tableRow, tableCol, weekendStart, weekendEnd, dayOfMonthNamesNext[i] );
            grid.setWidget( tableRow, tableCol, dayOfMonthNamesNext[i] );
            grid.getCellFormatter().addStyleName( tableRow, tableCol, STYLE_OTHER_MONTHS );
        }
        formatSpecialDates( FORMAT_ACTION_ADD );
    }

    private void initialGrid()
    {

        DatePickerCell[] dayOfMonthNamesPrev = dateTable.dayOfMonthNamesPrev();
        DatePickerCell[] dayOfMonthNamesNext = dateTable.dayOfMonthNamesNext();
        DatePickerCell[] dayOfMonthNames = dateTable.dayOfMonthNames();

        for ( int i = 0; i < 31; i++ )
        {
            dayOfMonthNamesPrev[i].addClickListener( this );
            dayOfMonthNamesNext[i].addClickListener( this );
            dayOfMonthNames[i].addClickListener( this );
        }
    }
}

Commits for litesoft/trunk/Java/GWT/Client/src/org/litesoft/GWT/forms/client/components/nonpublic/datepicker/DatePicker.java

Diff revisions: vs.
Revision Author Commited Message
151 Diff Diff GeorgeS picture GeorgeS Thu 17 Mar, 2011 04:16:22 +0000
49 Diff Diff GeorgeS picture GeorgeS Mon 12 Apr, 2010 02:59:10 +0000

License Text

2 GeorgeS picture GeorgeS Sun 07 Feb, 2010 12:50:58 +0000