blob: ff2622fde27900ef05cf57739be77a30e207097a [file] [log] [blame]
Daniel Lehmann392ccec2010-11-01 20:50:03 -07001/*
2 * Copyright (C) 2010 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
Dmitri Plotnikov18ffaa22010-12-03 14:28:00 -080017package com.android.contacts.editor;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070018
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070019import android.app.Dialog;
20import android.content.Context;
21import android.content.res.Resources;
22import android.os.Bundle;
23import android.text.TextUtils;
24import android.util.AttributeSet;
25import android.view.View;
26import android.widget.Button;
27
Daniel Lehmann392ccec2010-11-01 20:50:03 -070028import com.android.contacts.R;
29import com.android.contacts.datepicker.DatePicker;
30import com.android.contacts.datepicker.DatePickerDialog;
31import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
Dmitri Plotnikov4597c922010-11-15 13:03:06 -080032import com.android.contacts.model.AccountType.EditField;
33import com.android.contacts.model.AccountType.EventEditType;
Daisuke Miyakawa405671a2011-03-29 09:34:07 -070034import com.android.contacts.model.DataKind;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070035import com.android.contacts.model.EntityDelta;
36import com.android.contacts.model.EntityDelta.ValuesDelta;
37import com.android.contacts.util.DateUtils;
38
Daniel Lehmann392ccec2010-11-01 20:50:03 -070039import java.text.ParsePosition;
40import java.util.Calendar;
41import java.util.Date;
Daniel Lehmann4b648482011-03-04 14:59:04 -080042import java.util.Locale;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070043
44/**
45 * Editor that allows editing Events using a {@link DatePickerDialog}
46 */
47public class EventFieldEditorView extends LabeledEditorView {
48 /**
49 * Exchange requires 8:00 for birthdays
50 */
Daisuke Miyakawad37a8912011-03-27 09:35:28 -070051 private final static int DEFAULT_HOUR = 8;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070052
Katherine Kuanfd709032011-08-02 14:18:16 -070053 /**
54 * Default string to show when there is no date selected yet.
55 */
56 private String mNoDateString;
57 private int mPrimaryTextColor;
58 private int mSecondaryTextColor;
59
Dmitri Plotnikov135b44c2011-01-19 11:05:04 -080060 private Button mDateView;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070061
62 public EventFieldEditorView(Context context) {
63 super(context);
64 }
65
66 public EventFieldEditorView(Context context, AttributeSet attrs) {
67 super(context, attrs);
68 }
69
70 public EventFieldEditorView(Context context, AttributeSet attrs, int defStyle) {
71 super(context, attrs, defStyle);
72 }
73
Katherine Kuan63ffb902011-04-26 19:53:40 -070074 /** {@inheritDoc} */
Daniel Lehmann392ccec2010-11-01 20:50:03 -070075 @Override
Katherine Kuan63ffb902011-04-26 19:53:40 -070076 protected void onFinishInflate() {
77 super.onFinishInflate();
Dmitri Plotnikov91d8e892010-12-07 20:36:51 -080078
Katherine Kuanfd709032011-08-02 14:18:16 -070079 Resources resources = mContext.getResources();
80 mPrimaryTextColor = resources.getColor(R.color.primary_text_color);
81 mSecondaryTextColor = resources.getColor(R.color.secondary_text_color);
Katherine Kuan95743142011-08-10 17:56:11 -070082 mNoDateString = mContext.getString(R.string.event_edit_field_hint_text);
Katherine Kuanfd709032011-08-02 14:18:16 -070083
Katherine Kuan63ffb902011-04-26 19:53:40 -070084 mDateView = (Button) findViewById(R.id.date_view);
85 mDateView.setOnClickListener(new OnClickListener() {
86 @Override
87 public void onClick(View v) {
88 showDialog(R.id.dialog_event_date_picker);
89 }
90 });
Daniel Lehmann392ccec2010-11-01 20:50:03 -070091 }
92
93 @Override
Josh Gargus26918da2012-02-02 16:58:04 -080094 public void editNewlyAddedField() {
95 showDialog(R.id.dialog_event_date_picker);
96 }
97
98 @Override
Daniel Lehmann392ccec2010-11-01 20:50:03 -070099 protected void requestFocusForFirstEditField() {
Katherine Kuan63ffb902011-04-26 19:53:40 -0700100 mDateView.requestFocus();
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700101 }
102
103 @Override
104 public void setEnabled(boolean enabled) {
105 super.setEnabled(enabled);
106
Katherine Kuan63ffb902011-04-26 19:53:40 -0700107 mDateView.setEnabled(!isReadOnly() && enabled);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700108 }
109
110 @Override
111 public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
112 ViewIdGenerator vig) {
113 if (kind.fieldList.size() != 1) throw new IllegalStateException("kind must have 1 field");
114 super.setValues(kind, entry, state, readOnly, vig);
115
Katherine Kuan63ffb902011-04-26 19:53:40 -0700116 mDateView.setEnabled(isEnabled() && !readOnly);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700117
118 rebuildDateView();
119 }
120
121 private void rebuildDateView() {
122 final EditField editField = getKind().fieldList.get(0);
123 final String column = editField.column;
Dmitri Plotnikov135b44c2011-01-19 11:05:04 -0800124 String data = DateUtils.formatDate(getContext(), getEntry().getAsString(column));
125 if (TextUtils.isEmpty(data)) {
Katherine Kuanfd709032011-08-02 14:18:16 -0700126 mDateView.setText(mNoDateString);
127 mDateView.setTextColor(mSecondaryTextColor);
Katherine Kuan5e330ed2011-07-15 15:06:06 -0700128 setDeleteButtonVisible(false);
129 } else {
Katherine Kuanfd709032011-08-02 14:18:16 -0700130 mDateView.setText(data);
131 mDateView.setTextColor(mPrimaryTextColor);
Katherine Kuan5e330ed2011-07-15 15:06:06 -0700132 setDeleteButtonVisible(true);
Dmitri Plotnikov135b44c2011-01-19 11:05:04 -0800133 }
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700134 }
135
Katherine Kuan25914362011-04-29 19:42:01 -0700136 @Override
137 public boolean isEmpty() {
Josh Gargus296cca52011-12-01 17:57:48 -0800138 final EditField editField = getKind().fieldList.get(0);
139 final String column = editField.column;
140 return TextUtils.isEmpty(getEntry().getAsString(column));
Katherine Kuan1b220732011-04-28 18:45:39 -0700141 }
142
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700143 @Override
144 public Dialog createDialog(Bundle bundle) {
145 if (bundle == null) throw new IllegalArgumentException("bundle must not be null");
146 int dialogId = bundle.getInt(DIALOG_ID_KEY);
147 switch (dialogId) {
148 case R.id.dialog_event_date_picker:
149 return createDatePickerDialog();
150 default:
151 return super.createDialog(bundle);
152 }
153 }
154
155 @Override
156 protected EventEditType getType() {
157 return (EventEditType) super.getType();
158 }
159
160 @Override
161 protected void onLabelRebuilt() {
162 // if we changed to a type that requires a year, ensure that it is actually set
163 final String column = getKind().fieldList.get(0).column;
164 final String oldValue = getEntry().getAsString(column);
165 final DataKind kind = getKind();
166
Daniel Lehmann4b648482011-03-04 14:59:04 -0800167 final Calendar calendar = Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700168 final int defaultYear = calendar.get(Calendar.YEAR);
169
170 // Check whether the year is optional
171 final boolean isYearOptional = getType().isYearOptional();
172
Dmitri Plotnikov17e6f9d2011-01-03 11:27:49 -0800173 if (!isYearOptional && !TextUtils.isEmpty(oldValue)) {
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700174 final ParsePosition position = new ParsePosition(0);
175 final Date date2 = kind.dateFormatWithoutYear.parse(oldValue, position);
176
177 // Don't understand the date, lets not change it
178 if (date2 == null) return;
179
180 // This value is missing the year. Add it now
181 calendar.setTime(date2);
182 calendar.set(defaultYear, calendar.get(Calendar.MONTH),
183 calendar.get(Calendar.DAY_OF_MONTH), DEFAULT_HOUR, 0, 0);
184
185 onFieldChanged(column, kind.dateFormatWithYear.format(calendar.getTime()));
186 rebuildDateView();
187 }
188 }
189
190 /**
191 * Prepare dialog for entering a date
192 */
193 private Dialog createDatePickerDialog() {
194 final String column = getKind().fieldList.get(0).column;
195 final String oldValue = getEntry().getAsString(column);
196 final DataKind kind = getKind();
197
Daniel Lehmann4b648482011-03-04 14:59:04 -0800198 final Calendar calendar = Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700199 final int defaultYear = calendar.get(Calendar.YEAR);
200
201 // Check whether the year is optional
202 final boolean isYearOptional = getType().isYearOptional();
203
204 final int oldYear, oldMonth, oldDay;
205 if (TextUtils.isEmpty(oldValue)) {
206 // Default to January first, 30 years ago
207 oldYear = defaultYear;
208 oldMonth = 0;
209 oldDay = 1;
210 } else {
211 final ParsePosition position = new ParsePosition(0);
212 // Try parsing with year
Dmitri Plotnikov2b3f95c2011-01-03 14:21:32 -0800213 Date date1 = kind.dateFormatWithYear.parse(oldValue, position);
214 if (date1 == null) {
215 // If that format does not fit, try guessing the right format
216 date1 = DateUtils.parseDate(oldValue);
217 }
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700218 if (date1 != null) {
219 calendar.setTime(date1);
220 oldYear = calendar.get(Calendar.YEAR);
221 oldMonth = calendar.get(Calendar.MONTH);
222 oldDay = calendar.get(Calendar.DAY_OF_MONTH);
223 } else {
224 final Date date2 = kind.dateFormatWithoutYear.parse(oldValue, position);
225 // Don't understand the date, lets not change it
226 if (date2 == null) return null;
227 calendar.setTime(date2);
228 oldYear = isYearOptional ? 0 : defaultYear;
229 oldMonth = calendar.get(Calendar.MONTH);
230 oldDay = calendar.get(Calendar.DAY_OF_MONTH);
231 }
232 }
233 final OnDateSetListener callBack = new OnDateSetListener() {
234 @Override
235 public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
236 if (year == 0 && !isYearOptional) throw new IllegalStateException();
Daniel Lehmann4b648482011-03-04 14:59:04 -0800237 final Calendar outCalendar =
238 Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700239
Daniel Lehmann11812c52012-03-29 17:50:29 -0700240 // If no year specified, set it to 2000 (we could pick any leap year here).
241 // The format string will ignore that year.
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700242 // For formats other than Exchange, the time of the day is ignored
243 outCalendar.clear();
Daniel Lehmann11812c52012-03-29 17:50:29 -0700244 outCalendar.set(year == 0 ? 2000 : year, monthOfYear, dayOfMonth,
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700245 DEFAULT_HOUR, 0, 0);
246
247 final String resultString;
248 if (year == 0) {
249 resultString = kind.dateFormatWithoutYear.format(outCalendar.getTime());
250 } else {
251 resultString = kind.dateFormatWithYear.format(outCalendar.getTime());
252 }
Josh Gargus296cca52011-12-01 17:57:48 -0800253
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700254 onFieldChanged(column, resultString);
255 rebuildDateView();
256 }
257 };
258 final DatePickerDialog resultDialog = new DatePickerDialog(getContext(), callBack,
259 oldYear, oldMonth, oldDay, isYearOptional);
260 return resultDialog;
261 }
Daisuke Miyakawad37a8912011-03-27 09:35:28 -0700262
263 /**
264 * @return Default hour which should be used for birthday field.
265 */
266 public static int getDefaultHourForBirthday() {
267 return DEFAULT_HOUR;
268 }
Katherine Kuan2293e552011-07-21 20:25:44 -0700269
270 @Override
271 public void clearAllFields() {
272 // Update UI
Katherine Kuanfd709032011-08-02 14:18:16 -0700273 mDateView.setText(mNoDateString);
274 mDateView.setTextColor(mSecondaryTextColor);
Katherine Kuan2293e552011-07-21 20:25:44 -0700275
276 // Update state
277 final String column = getKind().fieldList.get(0).column;
278 onFieldChanged(column, "");
279 }
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700280}