1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.contacts.datepicker;
18 
19 // This is a fork of the standard Android DatePicker that additionally allows toggling the year
20 // on/off.
21 
22 import android.app.AlertDialog;
23 import android.content.Context;
24 import android.content.DialogInterface;
25 import android.content.DialogInterface.OnClickListener;
26 import android.os.Bundle;
27 import android.view.LayoutInflater;
28 import android.view.View;
29 
30 import com.android.contacts.R;
31 import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
32 import com.android.contacts.util.DateUtils;
33 
34 import java.text.DateFormat;
35 import java.util.Calendar;
36 
37 /**
38  * A simple dialog containing an {@link DatePicker}.
39  *
40  * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker
41  * tutorial</a>.</p>
42  */
43 public class DatePickerDialog extends AlertDialog implements OnClickListener,
44         OnDateChangedListener {
45 
46     /** Magic year that represents "no year" */
47     public static int NO_YEAR = DatePicker.NO_YEAR;
48 
49     private static final String YEAR = "year";
50     private static final String MONTH = "month";
51     private static final String DAY = "day";
52     private static final String YEAR_OPTIONAL = "year_optional";
53 
54     private final DatePicker mDatePicker;
55     private final OnDateSetListener mCallBack;
56     private final DateFormat mTitleDateFormat;
57     private final DateFormat mTitleNoYearDateFormat;
58 
59     private int mInitialYear;
60     private int mInitialMonth;
61     private int mInitialDay;
62 
63     /**
64      * The callback used to indicate the user is done filling in the date.
65      */
66     public interface OnDateSetListener {
67         /**
68          * @param view The view associated with this listener.
69          * @param year The year that was set or {@link DatePickerDialog#NO_YEAR} if the user has
70          *  not specified a year
71          * @param monthOfYear The month that was set (0-11) for compatibility
72          *  with {@link java.util.Calendar}.
73          * @param dayOfMonth The day of the month that was set.
74          */
onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)75         void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth);
76     }
77 
78     /**
79      * @param context The context the dialog is to run in.
80      * @param callBack How the parent is notified that the date is set.
81      * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no year
82      *  has been specified
83      * @param monthOfYear The initial month of the dialog.
84      * @param dayOfMonth The initial day of the dialog.
85      * @param yearOptional Whether the year can be toggled by the user
86      */
DatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)87     public DatePickerDialog(Context context,
88             OnDateSetListener callBack,
89             int year,
90             int monthOfYear,
91             int dayOfMonth,
92             boolean yearOptional) {
93         // Don't pass a theme id. Instead use the default alert dialog theme.
94         this(context, /* themeId = */ 0, callBack, year, monthOfYear, dayOfMonth,
95                 yearOptional);
96     }
97 
98     /**
99      * @param context The context the dialog is to run in.
100      * @param theme the theme to apply to this dialog
101      * @param callBack How the parent is notified that the date is set.
102      * @param year The initial year of the dialog or {@link DatePickerDialog#NO_YEAR} if no
103      *  year has been specified.
104      * @param monthOfYear The initial month of the dialog.
105      * @param dayOfMonth The initial day of the dialog.
106      * @param yearOptional Whether the year can be toggled by the user
107      */
DatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth, boolean yearOptional)108     public DatePickerDialog(Context context,
109             int theme,
110             OnDateSetListener callBack,
111             int year,
112             int monthOfYear,
113             int dayOfMonth,
114             boolean yearOptional) {
115         super(context, theme);
116 
117         mCallBack = callBack;
118         mInitialYear = year;
119         mInitialMonth = monthOfYear;
120         mInitialDay = dayOfMonth;
121 
122         mTitleDateFormat = DateFormat.getDateInstance(DateFormat.FULL);
123         mTitleNoYearDateFormat = DateUtils.getLocalizedDateFormatWithoutYear(getContext());
124         updateTitle(mInitialYear, mInitialMonth, mInitialDay);
125 
126         setButton(BUTTON_POSITIVE, context.getText(R.string.date_time_set),
127                 this);
128         setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel),
129                 (OnClickListener) null);
130 
131         LayoutInflater inflater =
132                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
133         View view = inflater.inflate(R.layout.date_picker_dialog, null);
134         setView(view);
135         mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
136         mDatePicker.init(mInitialYear, mInitialMonth, mInitialDay, yearOptional, this);
137     }
138 
139     @Override
onClick(DialogInterface dialog, int which)140     public void onClick(DialogInterface dialog, int which) {
141         if (mCallBack != null) {
142             mDatePicker.clearFocus();
143             mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
144                     mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
145         }
146     }
147 
148     @Override
onDateChanged(DatePicker view, int year, int month, int day)149     public void onDateChanged(DatePicker view, int year, int month, int day) {
150         updateTitle(year, month, day);
151     }
152 
updateTitle(int year, int month, int day)153     private void updateTitle(int year, int month, int day) {
154         final Calendar calendar = Calendar.getInstance();
155         calendar.set(Calendar.YEAR, year);
156         calendar.set(Calendar.MONTH, month);
157         calendar.set(Calendar.DAY_OF_MONTH, day);
158         final DateFormat dateFormat =
159                 year == NO_YEAR ? mTitleNoYearDateFormat : mTitleDateFormat;
160         setTitle(dateFormat.format(calendar.getTime()));
161     }
162 
163     @Override
onSaveInstanceState()164     public Bundle onSaveInstanceState() {
165         Bundle state = super.onSaveInstanceState();
166         state.putInt(YEAR, mDatePicker.getYear());
167         state.putInt(MONTH, mDatePicker.getMonth());
168         state.putInt(DAY, mDatePicker.getDayOfMonth());
169         state.putBoolean(YEAR_OPTIONAL, mDatePicker.isYearOptional());
170         return state;
171     }
172 
173     @Override
onRestoreInstanceState(Bundle savedInstanceState)174     public void onRestoreInstanceState(Bundle savedInstanceState) {
175         super.onRestoreInstanceState(savedInstanceState);
176         int year = savedInstanceState.getInt(YEAR);
177         int month = savedInstanceState.getInt(MONTH);
178         int day = savedInstanceState.getInt(DAY);
179         boolean yearOptional = savedInstanceState.getBoolean(YEAR_OPTIONAL);
180         mDatePicker.init(year, month, day, yearOptional, this);
181         updateTitle(year, month, day);
182     }
183 }
184