blob: 4c29330945bc1634043fc47d5c89ba4f4ab0bbfe [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;
Wenyi Wang2da5d2f2015-09-29 22:15:38 -070023import android.provider.ContactsContract.CommonDataKinds.Event;
Chiao Chenge0b2f1e2012-06-12 13:07:56 -070024import android.text.TextUtils;
25import android.util.AttributeSet;
26import android.view.View;
27import android.widget.Button;
28
Daniel Lehmann392ccec2010-11-01 20:50:03 -070029import com.android.contacts.R;
30import com.android.contacts.datepicker.DatePicker;
31import com.android.contacts.datepicker.DatePickerDialog;
32import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
Gary Mai69c182a2016-12-05 13:07:03 -080033import com.android.contacts.model.RawContactDelta;
34import com.android.contacts.model.ValuesDelta;
35import com.android.contacts.model.account.AccountType.EditField;
36import com.android.contacts.model.account.AccountType.EventEditType;
37import com.android.contacts.model.dataitem.DataKind;
38import com.android.contacts.util.CommonDateUtils;
39import com.android.contacts.util.DateUtils;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070040
Daniel Lehmann392ccec2010-11-01 20:50:03 -070041import java.text.ParsePosition;
42import java.util.Calendar;
43import java.util.Date;
Daniel Lehmann4b648482011-03-04 14:59:04 -080044import java.util.Locale;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070045
46/**
47 * Editor that allows editing Events using a {@link DatePickerDialog}
48 */
49public class EventFieldEditorView extends LabeledEditorView {
Daniel Lehmann392ccec2010-11-01 20:50:03 -070050
Katherine Kuanfd709032011-08-02 14:18:16 -070051 /**
52 * Default string to show when there is no date selected yet.
53 */
54 private String mNoDateString;
55 private int mPrimaryTextColor;
Brian Attwelld690dff2014-12-02 15:04:56 -080056 private int mHintTextColor;
Katherine Kuanfd709032011-08-02 14:18:16 -070057
Dmitri Plotnikov135b44c2011-01-19 11:05:04 -080058 private Button mDateView;
Daniel Lehmann392ccec2010-11-01 20:50:03 -070059
60 public EventFieldEditorView(Context context) {
61 super(context);
62 }
63
64 public EventFieldEditorView(Context context, AttributeSet attrs) {
65 super(context, attrs);
66 }
67
68 public EventFieldEditorView(Context context, AttributeSet attrs, int defStyle) {
69 super(context, attrs, defStyle);
70 }
71
Katherine Kuan63ffb902011-04-26 19:53:40 -070072 /** {@inheritDoc} */
Daniel Lehmann392ccec2010-11-01 20:50:03 -070073 @Override
Katherine Kuan63ffb902011-04-26 19:53:40 -070074 protected void onFinishInflate() {
75 super.onFinishInflate();
Dmitri Plotnikov91d8e892010-12-07 20:36:51 -080076
Brian Attwellf1402272014-12-16 16:00:08 -080077 Resources resources = getContext().getResources();
Katherine Kuanfd709032011-08-02 14:18:16 -070078 mPrimaryTextColor = resources.getColor(R.color.primary_text_color);
Brian Attwelld690dff2014-12-02 15:04:56 -080079 mHintTextColor = resources.getColor(R.color.editor_disabled_text_color);
Brian Attwellf1402272014-12-16 16:00:08 -080080 mNoDateString = getContext().getString(R.string.event_edit_field_hint_text);
Katherine Kuanfd709032011-08-02 14:18:16 -070081
Katherine Kuan63ffb902011-04-26 19:53:40 -070082 mDateView = (Button) findViewById(R.id.date_view);
83 mDateView.setOnClickListener(new OnClickListener() {
84 @Override
85 public void onClick(View v) {
86 showDialog(R.id.dialog_event_date_picker);
87 }
88 });
Daniel Lehmann392ccec2010-11-01 20:50:03 -070089 }
90
91 @Override
Josh Gargus26918da2012-02-02 16:58:04 -080092 public void editNewlyAddedField() {
93 showDialog(R.id.dialog_event_date_picker);
94 }
95
96 @Override
Daniel Lehmann392ccec2010-11-01 20:50:03 -070097 protected void requestFocusForFirstEditField() {
Katherine Kuan63ffb902011-04-26 19:53:40 -070098 mDateView.requestFocus();
Daniel Lehmann392ccec2010-11-01 20:50:03 -070099 }
100
101 @Override
102 public void setEnabled(boolean enabled) {
103 super.setEnabled(enabled);
104
Katherine Kuan63ffb902011-04-26 19:53:40 -0700105 mDateView.setEnabled(!isReadOnly() && enabled);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700106 }
107
108 @Override
Maurice Chu851222a2012-06-21 11:43:08 -0700109 public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly,
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700110 ViewIdGenerator vig) {
111 if (kind.fieldList.size() != 1) throw new IllegalStateException("kind must have 1 field");
112 super.setValues(kind, entry, state, readOnly, vig);
113
Katherine Kuan63ffb902011-04-26 19:53:40 -0700114 mDateView.setEnabled(isEnabled() && !readOnly);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700115
116 rebuildDateView();
Brian Attwell8f9d84f2014-11-03 23:17:04 -0800117 updateEmptiness();
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700118 }
119
120 private void rebuildDateView() {
121 final EditField editField = getKind().fieldList.get(0);
122 final String column = editField.column;
Yorke Lee4b294d62012-12-19 12:04:38 -0800123 String data = DateUtils.formatDate(getContext(), getEntry().getAsString(column),
124 false /*Use the short DateFormat to ensure that it fits inside the EditText*/);
Dmitri Plotnikov135b44c2011-01-19 11:05:04 -0800125 if (TextUtils.isEmpty(data)) {
Katherine Kuanfd709032011-08-02 14:18:16 -0700126 mDateView.setText(mNoDateString);
Brian Attwelld690dff2014-12-02 15:04:56 -0800127 mDateView.setTextColor(mHintTextColor);
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
Jay Shrauner7bcdf512015-05-26 15:45:36 -0700171 final boolean isYearOptional = getType() != null && getType().isYearOptional();
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700172
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);
Walter Jang5f8932d2016-10-12 17:45:44 -0700175 final Date date2 = kind.dateFormatWithoutYear == null
176 ? null : kind.dateFormatWithoutYear.parse(oldValue, position);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700177
178 // Don't understand the date, lets not change it
179 if (date2 == null) return;
180
181 // This value is missing the year. Add it now
182 calendar.setTime(date2);
183 calendar.set(defaultYear, calendar.get(Calendar.MONTH),
Yorke Leecd321f62013-10-28 15:20:15 -0700184 calendar.get(Calendar.DAY_OF_MONTH), CommonDateUtils.DEFAULT_HOUR, 0, 0);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700185
Walter Jang5f8932d2016-10-12 17:45:44 -0700186 final String formattedDate = kind.dateFormatWithYear == null
187 ? null : kind.dateFormatWithYear.format(calendar.getTime());
188 if (formattedDate == null) return;
189
190 onFieldChanged(column, formattedDate);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700191 rebuildDateView();
192 }
193 }
194
195 /**
196 * Prepare dialog for entering a date
197 */
198 private Dialog createDatePickerDialog() {
199 final String column = getKind().fieldList.get(0).column;
200 final String oldValue = getEntry().getAsString(column);
201 final DataKind kind = getKind();
202
Daniel Lehmann4b648482011-03-04 14:59:04 -0800203 final Calendar calendar = Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700204 final int defaultYear = calendar.get(Calendar.YEAR);
205
206 // Check whether the year is optional
207 final boolean isYearOptional = getType().isYearOptional();
208
209 final int oldYear, oldMonth, oldDay;
Yorke Leeec6bfa02012-12-19 15:45:37 -0800210
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700211 if (TextUtils.isEmpty(oldValue)) {
Yorke Lee78253a92012-12-04 12:22:12 -0800212 // Default to the current date
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700213 oldYear = defaultYear;
Yorke Lee78253a92012-12-04 12:22:12 -0800214 oldMonth = calendar.get(Calendar.MONTH);
215 oldDay = calendar.get(Calendar.DAY_OF_MONTH);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700216 } else {
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700217 // Try parsing with year
Yorke Leeec6bfa02012-12-19 15:45:37 -0800218 Calendar cal = DateUtils.parseDate(oldValue, false);
219 if (cal != null) {
220 if (DateUtils.isYearSet(cal)) {
221 oldYear = cal.get(Calendar.YEAR);
Daniel Lehmann5a7a2692012-08-03 21:39:01 -0700222 } else {
Yorke Leeec6bfa02012-12-19 15:45:37 -0800223 //cal.set(Calendar.YEAR, 0);
Daniel Lehmann5a7a2692012-08-03 21:39:01 -0700224 oldYear = isYearOptional ? DatePickerDialog.NO_YEAR : defaultYear;
Daniel Lehmann5a7a2692012-08-03 21:39:01 -0700225 }
Yorke Leeec6bfa02012-12-19 15:45:37 -0800226 oldMonth = cal.get(Calendar.MONTH);
227 oldDay = cal.get(Calendar.DAY_OF_MONTH);
228 } else {
229 return null;
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700230 }
231 }
232 final OnDateSetListener callBack = new OnDateSetListener() {
233 @Override
234 public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
235 if (year == 0 && !isYearOptional) throw new IllegalStateException();
Daniel Lehmann4b648482011-03-04 14:59:04 -0800236 final Calendar outCalendar =
237 Calendar.getInstance(DateUtils.UTC_TIMEZONE, Locale.US);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700238
Daniel Lehmann11812c52012-03-29 17:50:29 -0700239 // If no year specified, set it to 2000 (we could pick any leap year here).
240 // The format string will ignore that year.
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700241 // For formats other than Exchange, the time of the day is ignored
242 outCalendar.clear();
Daniel Lehmann5a7a2692012-08-03 21:39:01 -0700243 outCalendar.set(year == DatePickerDialog.NO_YEAR ? 2000 : year, monthOfYear,
Yorke Leecd321f62013-10-28 15:20:15 -0700244 dayOfMonth, CommonDateUtils.DEFAULT_HOUR, 0, 0);
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700245
246 final String resultString;
247 if (year == 0) {
Walter Jang5f8932d2016-10-12 17:45:44 -0700248 resultString = kind.dateFormatWithoutYear == null
249 ? null : kind.dateFormatWithoutYear.format(outCalendar.getTime());
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700250 } else {
Walter Jang5f8932d2016-10-12 17:45:44 -0700251 resultString = kind.dateFormatWithYear == null
252 ? null : kind.dateFormatWithYear.format(outCalendar.getTime());
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700253 }
Walter Jang5f8932d2016-10-12 17:45:44 -0700254 if (resultString == null) return;
255
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700256 onFieldChanged(column, resultString);
257 rebuildDateView();
258 }
259 };
260 final DatePickerDialog resultDialog = new DatePickerDialog(getContext(), callBack,
261 oldYear, oldMonth, oldDay, isYearOptional);
262 return resultDialog;
263 }
Daisuke Miyakawad37a8912011-03-27 09:35:28 -0700264
Katherine Kuan2293e552011-07-21 20:25:44 -0700265 @Override
266 public void clearAllFields() {
267 // Update UI
Katherine Kuanfd709032011-08-02 14:18:16 -0700268 mDateView.setText(mNoDateString);
Brian Attwelld690dff2014-12-02 15:04:56 -0800269 mDateView.setTextColor(mHintTextColor);
Katherine Kuan2293e552011-07-21 20:25:44 -0700270
271 // Update state
272 final String column = getKind().fieldList.get(0).column;
273 onFieldChanged(column, "");
274 }
Wenyi Wang2da5d2f2015-09-29 22:15:38 -0700275
276 /**
277 * Sets the typeColumn of entry as TYPE_BIRTHDAY and calls rebuildValues() to refresh the view.
278 */
279 public void restoreBirthday() {
280 saveValue(getKind().typeColumn, Integer.toString(Event.TYPE_BIRTHDAY));
281 rebuildValues();
282 }
283
284 /**
285 * EventEditType Birthday:
286 * rawValue=3 labelRes=17039911 secondary=false specificMax=1 customColumn=null
287 * mYearOptional=true
288 */
289 public boolean isBirthdayType(){
290 final EventEditType eventType = getType();
291 return eventType.rawValue == Event.TYPE_BIRTHDAY && !eventType.secondary
292 && eventType.specificMax == 1 && eventType.customColumn == null
293 && eventType.isYearOptional();
294 }
Daniel Lehmann392ccec2010-11-01 20:50:03 -0700295}