EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.content.browser.input]

COVERAGE SUMMARY FOR SOURCE FILE [TwoFieldDatePicker.java]

nameclass, %method, %block, %line, %
TwoFieldDatePicker.java0%   (0/2)0%   (0/19)0%   (0/314)0%   (0/75)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TwoFieldDatePicker0%   (0/1)0%   (0/17)0%   (0/249)0%   (0/60)
TwoFieldDatePicker (Context, long, long): void 0%   (0/1)0%   (0/86)0%   (0/19)
access$000 (TwoFieldDatePicker): NumberPicker 0%   (0/1)0%   (0/3)0%   (0/1)
access$100 (TwoFieldDatePicker): NumberPicker 0%   (0/1)0%   (0/3)0%   (0/1)
dispatchPopulateAccessibilityEvent (AccessibilityEvent): boolean 0%   (0/1)0%   (0/5)0%   (0/2)
getCurrentDate (): Calendar 0%   (0/1)0%   (0/3)0%   (0/1)
getMaxDate (): Calendar 0%   (0/1)0%   (0/3)0%   (0/1)
getMinDate (): Calendar 0%   (0/1)0%   (0/3)0%   (0/1)
getPositionInYearSpinner (): NumberPicker 0%   (0/1)0%   (0/3)0%   (0/1)
getYear (): int 0%   (0/1)0%   (0/5)0%   (0/1)
getYearSpinner (): NumberPicker 0%   (0/1)0%   (0/3)0%   (0/1)
init (int, int, TwoFieldDatePicker$OnMonthOrWeekChangedListener): void 0%   (0/1)0%   (0/10)0%   (0/4)
isNewDate (int, int): boolean 0%   (0/1)0%   (0/12)0%   (0/1)
notifyDateChanged (): void 0%   (0/1)0%   (0/15)0%   (0/4)
onPopulateAccessibilityEvent (AccessibilityEvent): void 0%   (0/1)0%   (0/19)0%   (0/5)
setCurrentDate (Calendar): void 0%   (0/1)0%   (0/4)0%   (0/2)
updateDate (int, int): void 0%   (0/1)0%   (0/15)0%   (0/6)
updateSpinners (): void 0%   (0/1)0%   (0/57)0%   (0/10)
     
class TwoFieldDatePicker$10%   (0/1)0%   (0/2)0%   (0/65)0%   (0/16)
TwoFieldDatePicker$1 (TwoFieldDatePicker): void 0%   (0/1)0%   (0/6)0%   (0/1)
onValueChange (NumberPicker, int, int): void 0%   (0/1)0%   (0/59)0%   (0/15)

1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4 
5package org.chromium.content.browser.input;
6 
7import android.content.Context;
8import android.view.LayoutInflater;
9import android.widget.NumberPicker;
10import android.widget.NumberPicker.OnValueChangeListener;
11import android.text.format.DateUtils;
12import android.view.accessibility.AccessibilityEvent;
13import android.widget.FrameLayout;
14import android.widget.NumberPicker;
15 
16import java.util.Calendar;
17 
18import org.chromium.content.R;
19 
20// This class is heavily based on android.widget.DatePicker.
21public abstract class TwoFieldDatePicker extends FrameLayout {
22 
23    private NumberPicker mPositionInYearSpinner;
24 
25    private NumberPicker mYearSpinner;
26 
27    private OnMonthOrWeekChangedListener mMonthOrWeekChangedListener;
28 
29    // It'd be nice to use android.text.Time like in other Dialogs but
30    // it suffers from the 2038 effect so it would prevent us from
31    // having dates over 2038.
32    private Calendar mMinDate;
33 
34    private Calendar mMaxDate;
35 
36    private Calendar mCurrentDate;
37 
38    /**
39     * The callback used to indicate the user changes\d the date.
40     */
41    public interface OnMonthOrWeekChangedListener {
42 
43        /**
44         * Called upon a date change.
45         *
46         * @param view The view associated with this listener.
47         * @param year The year that was set.
48         * @param positionInYear The month or week in year.
49         */
50        void onMonthOrWeekChanged(TwoFieldDatePicker view, int year, int positionInYear);
51    }
52 
53    public TwoFieldDatePicker(Context context, long minValue, long maxValue) {
54        super(context, null, android.R.attr.datePickerStyle);
55 
56        LayoutInflater inflater = (LayoutInflater) context
57                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
58        inflater.inflate(R.layout.two_field_date_picker, this, true);
59 
60        OnValueChangeListener onChangeListener = new OnValueChangeListener() {
61            @Override
62            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
63                int year = getYear();
64                int positionInYear = getPositionInYear();
65                // take care of wrapping of days and months to update greater fields
66                if (picker == mPositionInYearSpinner) {
67                    positionInYear = newVal;
68                    if (oldVal == picker.getMaxValue() && newVal == picker.getMinValue()) {
69                        year += 1;
70                    } else if (oldVal == picker.getMinValue() && newVal == picker.getMaxValue()) {
71                        year -=1;
72                    }
73                } else if (picker == mYearSpinner) {
74                    year = newVal;
75                 } else {
76                    throw new IllegalArgumentException();
77                }
78 
79                // now set the date to the adjusted one
80                setCurrentDate(year, positionInYear);
81                updateSpinners();
82                notifyDateChanged();
83            }
84        };
85 
86        mCurrentDate = Calendar.getInstance();
87        if (minValue >= maxValue) {
88            mMinDate = Calendar.getInstance();
89            mMinDate.set(0, 0, 1);
90            mMaxDate = Calendar.getInstance();
91            mMaxDate.set(9999, 0, 1);
92        } else {
93            mMinDate = createDateFromValue(minValue);
94            mMaxDate = createDateFromValue(maxValue);
95        }
96 
97        // month
98        mPositionInYearSpinner = (NumberPicker) findViewById(R.id.position_in_year);
99        mPositionInYearSpinner.setOnLongPressUpdateInterval(200);
100        mPositionInYearSpinner.setOnValueChangedListener(onChangeListener);
101 
102        // year
103        mYearSpinner = (NumberPicker) findViewById(R.id.year);
104        mYearSpinner.setOnLongPressUpdateInterval(100);
105        mYearSpinner.setOnValueChangedListener(onChangeListener);
106    }
107 
108    /**
109     * Initialize the state. If the provided values designate an inconsistent
110     * date the values are normalized before updating the spinners.
111     *
112     * @param year The initial year.
113     * @param positionInYear The initial month <strong>starting from zero</strong> or week in year.
114     * @param onMonthChangedListener How user is notified date is changed by
115     *            user, can be null.
116     */
117    public void init(int year, int positionInYear,
118            OnMonthOrWeekChangedListener onMonthOrWeekChangedListener) {
119        setCurrentDate(year, positionInYear);
120        updateSpinners();
121        mMonthOrWeekChangedListener = onMonthOrWeekChangedListener;
122    }
123 
124    public boolean isNewDate(int year, int positionInYear) {
125        return (getYear() != year || getPositionInYear() != positionInYear);
126    }
127 
128    /**
129     * Subclasses know the semantics of @value, and need to return
130     * a Calendar corresponding to it.
131     */
132    protected abstract Calendar createDateFromValue(long value);
133 
134    /**
135     * Updates the current date.
136     *
137     * @param year The year.
138     * @param positionInYear The month or week in year.
139     */
140    public void updateDate(int year, int positionInYear) {
141        if (!isNewDate(year, positionInYear)) {
142            return;
143        }
144        setCurrentDate(year, positionInYear);
145        updateSpinners();
146        notifyDateChanged();
147    }
148 
149    /**
150     * Subclasses know the semantics of @positionInYear, and need to update @mCurrentDate to the
151     * appropriate date.
152     */
153    protected abstract void setCurrentDate(int year, int positionInYear);
154 
155    protected void setCurrentDate(Calendar date) {
156        mCurrentDate = date;
157    }
158 
159    @Override
160    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
161        onPopulateAccessibilityEvent(event);
162        return true;
163    }
164 
165    @Override
166    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
167        super.onPopulateAccessibilityEvent(event);
168 
169        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
170        String selectedDateUtterance = DateUtils.formatDateTime(getContext(),
171                mCurrentDate.getTimeInMillis(), flags);
172        event.getText().add(selectedDateUtterance);
173    }
174 
175    /**
176     * @return The selected year.
177     */
178    public int getYear() {
179        return mCurrentDate.get(Calendar.YEAR);
180    }
181 
182    /**
183     * @return The selected month or week.
184     */
185    public abstract int getPositionInYear();
186 
187    protected abstract int getMaxYear();
188 
189    protected abstract int getMinYear();
190 
191    protected abstract int getMaxPositionInYear();
192 
193    protected abstract int getMinPositionInYear();
194 
195    protected Calendar getMaxDate() {
196        return mMaxDate;
197    }
198 
199    protected Calendar getMinDate() {
200        return mMinDate;
201    }
202 
203    protected Calendar getCurrentDate() {
204        return mCurrentDate;
205    }
206 
207    protected NumberPicker getPositionInYearSpinner() {
208        return mPositionInYearSpinner;
209    }
210 
211    protected NumberPicker getYearSpinner() {
212        return mYearSpinner;
213    }
214 
215    /**
216     * This method should be subclassed to update the spinners based on mCurrentDate.
217     */
218    protected void updateSpinners() {
219        mPositionInYearSpinner.setDisplayedValues(null);
220 
221        // set the spinner ranges respecting the min and max dates
222        mPositionInYearSpinner.setMinValue(getMinPositionInYear());
223        mPositionInYearSpinner.setMaxValue(getMaxPositionInYear());
224        mPositionInYearSpinner.setWrapSelectorWheel(
225                !mCurrentDate.equals(mMinDate) && !mCurrentDate.equals(mMaxDate));
226 
227        // year spinner range does not change based on the current date
228        mYearSpinner.setMinValue(getMinYear());
229        mYearSpinner.setMaxValue(getMaxYear());
230        mYearSpinner.setWrapSelectorWheel(false);
231 
232        // set the spinner values
233        mYearSpinner.setValue(getYear());
234        mPositionInYearSpinner.setValue(getPositionInYear());
235    }
236 
237    /**
238     * Notifies the listener, if such, for a change in the selected date.
239     */
240    protected void notifyDateChanged() {
241        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
242        if (mMonthOrWeekChangedListener != null) {
243            mMonthOrWeekChangedListener.onMonthOrWeekChanged(this, getYear(), getPositionInYear());
244        }
245    }
246}

[all classes][org.chromium.content.browser.input]
EMMA 2.0.5312 (C) Vladimir Roubtsov