CreateEventDialogFragment.java revision 09fbd8e9ef61f667c0f20d36fbf40e5a4479c8d9
1/* Copyright (C) 2012 The Android Open Source Project
2
3     Licensed under the Apache License, Version 2.0 (the "License");
4     you may not use this file except in compliance with the License.
5     You may obtain a copy of the License at
6
7          http://www.apache.org/licenses/LICENSE-2.0
8
9     Unless required by applicable law or agreed to in writing, software
10     distributed under the License is distributed on an "AS IS" BASIS,
11     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12     See the License for the specific language governing permissions and
13     limitations under the License.
14*/
15
16package com.android.calendar.event;
17
18import android.app.Activity;
19import android.app.AlertDialog;
20import android.app.Dialog;
21import android.app.DialogFragment;
22import android.content.Context;
23import android.content.DialogInterface;
24import android.content.Intent;
25import android.database.Cursor;
26import android.os.Bundle;
27import android.provider.CalendarContract;
28import android.provider.CalendarContract.Calendars;
29import android.provider.Settings;
30import android.text.Editable;
31import android.text.TextWatcher;
32import android.text.format.DateUtils;
33import android.text.format.Time;
34import android.view.LayoutInflater;
35import android.view.View;
36import android.widget.Button;
37import android.widget.EditText;
38import android.widget.TextView;
39
40import com.android.calendar.AsyncQueryService;
41import com.android.calendar.CalendarController;
42import com.android.calendar.CalendarController.EventType;
43import com.android.calendar.CalendarEventModel;
44import com.android.calendar.GeneralPreferences;
45import com.android.calendar.R;
46import com.android.calendar.Utils;
47
48
49/**
50 * Allows the user to quickly create a new all-day event from the calendar's month view.
51 */
52public class CreateEventDialogFragment extends DialogFragment implements TextWatcher {
53
54    private static final int TOKEN_CALENDARS = 1 << 3;
55
56    private static final String KEY_DATE_STRING = "date_string";
57    private static final String KEY_DATE_IN_MILLIS = "date_in_millis";
58    private static final String EVENT_DATE_FORMAT = "%a, %b %d, %Y";
59
60    private AlertDialog mAlertDialog;
61
62    private CalendarQueryService mService;
63
64    private EditText mEventTitle;
65    private View mColor;
66    private TextView mCalendarName;
67    private TextView mAccountName;
68    private TextView mDate;
69    private Button mButtonAddEvent;
70
71    private CalendarController mController;
72    private EditEventHelper mEditEventHelper;
73
74    private String mDateString;
75    private long mDateInMillis;
76
77    private CalendarEventModel mModel;
78    private long mCalendarId = -1;
79
80    private class CalendarQueryService extends AsyncQueryService {
81
82        /**
83         * @param context
84         */
85        public CalendarQueryService(Context context) {
86            super(context);
87        }
88
89        @Override
90        public void onQueryComplete(int token, Object cookie, Cursor cursor) {
91            setDefaultCalendarView(cursor);
92            if (cursor != null) {
93                cursor.close();
94            }
95        }
96    }
97
98    public CreateEventDialogFragment() {
99        // Empty constructor required for DialogFragment.
100    }
101
102    public CreateEventDialogFragment(Time day) {
103        setDay(day);
104    }
105
106    public void setDay(Time day) {
107        mDateString = day.format(EVENT_DATE_FORMAT);
108        mDateInMillis = day.toMillis(true);
109    }
110
111    @Override
112    public void onCreate(Bundle savedInstanceState) {
113        super.onCreate(savedInstanceState);
114        if (savedInstanceState != null) {
115            mDateString = savedInstanceState.getString(KEY_DATE_STRING);
116            mDateInMillis = savedInstanceState.getLong(KEY_DATE_IN_MILLIS);
117        }
118    }
119
120    @Override
121    public Dialog onCreateDialog(Bundle savedInstanceState) {
122        final Activity activity = getActivity();
123        final LayoutInflater layoutInflater = (LayoutInflater) activity
124                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
125        View view = layoutInflater.inflate(R.layout.create_event_dialog, null);
126
127        mColor = view.findViewById(R.id.color);
128        mCalendarName = (TextView) view.findViewById(R.id.calendar_name);
129        mAccountName = (TextView) view.findViewById(R.id.account_name);
130
131        mEventTitle = (EditText) view.findViewById(R.id.event_title);
132        mEventTitle.addTextChangedListener(this);
133
134        mDate = (TextView) view.findViewById(R.id.event_day);
135        if (mDateString != null) {
136            mDate.setText(mDateString);
137        }
138
139        mAlertDialog = new AlertDialog.Builder(activity)
140            .setTitle(R.string.new_event_dialog_label)
141            .setView(view)
142            .setPositiveButton(R.string.create_event_dialog_save,
143                    new DialogInterface.OnClickListener() {
144
145                        @Override
146                        public void onClick(DialogInterface dialog, int which) {
147                            createAllDayEvent();
148                            dismiss();
149                        }
150                    })
151            .setNeutralButton(R.string.edit_label,
152                    new DialogInterface.OnClickListener() {
153
154                        @Override
155                        public void onClick(DialogInterface dialog, int which) {
156                            mController.sendEventRelatedEventWithExtraWithTitleWithCalendarId(this,
157                                    EventType.CREATE_EVENT, -1, mDateInMillis,
158                                    mDateInMillis + DateUtils.DAY_IN_MILLIS, 0, 0,
159                                    CalendarController.EXTRA_CREATE_ALL_DAY, -1,
160                                    mEventTitle.getText().toString(),
161                                    mCalendarId);
162                            dismiss();
163                        }
164                    })
165            .setNegativeButton(android.R.string.cancel, null)
166            .create();
167
168        return mAlertDialog;
169    }
170
171    @Override
172    public void onResume() {
173        super.onResume();
174        if (mButtonAddEvent == null) {
175            mButtonAddEvent = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
176            mButtonAddEvent.setEnabled(mEventTitle.getText().toString().length() > 0);
177        }
178    }
179
180    @Override
181    public void onSaveInstanceState(Bundle outState) {
182        super.onSaveInstanceState(outState);
183        outState.putString(KEY_DATE_STRING, mDateString);
184        outState.putLong(KEY_DATE_IN_MILLIS, mDateInMillis);
185    }
186
187    @Override
188    public void onActivityCreated(Bundle args) {
189        super.onActivityCreated(args);
190        final Context context = getActivity();
191        mController = CalendarController.getInstance(getActivity());
192        mEditEventHelper = new EditEventHelper(context);
193        mModel = new CalendarEventModel(context);
194        mService = new CalendarQueryService(context);
195        mService.startQuery(TOKEN_CALENDARS, null, Calendars.CONTENT_URI,
196                EditEventHelper.CALENDARS_PROJECTION,
197                EditEventHelper.CALENDARS_WHERE_WRITEABLE_VISIBLE, null,
198                null);
199    }
200
201    private void createAllDayEvent() {
202        mModel.mStart = mDateInMillis;
203        mModel.mEnd = mDateInMillis + DateUtils.DAY_IN_MILLIS;
204        mModel.mTitle = mEventTitle.getText().toString();
205        mModel.mAllDay = true;
206        mEditEventHelper.saveEvent(mModel, null, 0);
207    }
208
209    @Override
210    public void afterTextChanged(Editable s) {
211        // Do nothing.
212    }
213
214    @Override
215    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
216        // Do nothing.
217    }
218
219    @Override
220    public void onTextChanged(CharSequence s, int start, int before, int count) {
221        if (mButtonAddEvent != null) {
222            mButtonAddEvent.setEnabled(s.length() > 0);
223        }
224    }
225
226    // Find the calendar position in the cursor that matches calendar in
227    // preference
228    private void setDefaultCalendarView(Cursor cursor) {
229        if (cursor == null || cursor.getCount() == 0) {
230            // Create an error message for the user that, when clicked,
231            // will exit this activity without saving the event.
232            dismiss();
233            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
234            builder.setTitle(R.string.no_syncable_calendars).setIconAttribute(
235                    android.R.attr.alertDialogIcon).setMessage(R.string.no_calendars_found)
236                    .setPositiveButton(R.string.add_account, new DialogInterface.OnClickListener() {
237
238                        @Override
239                        public void onClick(DialogInterface dialog, int which) {
240                                Intent nextIntent = new Intent(Settings.ACTION_ADD_ACCOUNT);
241                                final String[] array = {"com.android.calendar"};
242                                nextIntent.putExtra(Settings.EXTRA_AUTHORITIES, array);
243                                nextIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
244                                        Intent.FLAG_ACTIVITY_NEW_TASK);
245                                getActivity().startActivity(nextIntent);
246                        }
247                    })
248                    .setNegativeButton(android.R.string.no, null);
249            builder.show();
250            return;
251        }
252
253        String defaultCalendar = Utils.getSharedPreference(
254                getActivity(), GeneralPreferences.KEY_DEFAULT_CALENDAR, (String) null);
255
256        int calendarsOwnerColumn = cursor.getColumnIndexOrThrow(Calendars.OWNER_ACCOUNT);
257        int accountNameIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
258        int accountTypeIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_TYPE);
259
260        int position = 0;
261        cursor.moveToPosition(-1);
262        while (cursor.moveToNext()) {
263            String calendarOwner = cursor.getString(calendarsOwnerColumn);
264            if (defaultCalendar == null) {
265                // There is no stored default upon the first time running.  Use a primary
266                // calendar in this case.
267                if (calendarOwner != null &&
268                        calendarOwner.equals(cursor.getString(accountNameIndex)) &&
269                        !CalendarContract.ACCOUNT_TYPE_LOCAL.equals(
270                                cursor.getString(accountTypeIndex))) {
271                    setCalendarFields(cursor);
272                    return;
273                }
274            } else if (defaultCalendar.equals(calendarOwner)) {
275                // Found the default calendar.
276                setCalendarFields(cursor);
277                return;
278            }
279        }
280        cursor.moveToFirst();
281        setCalendarFields(cursor);
282    }
283
284    private void setCalendarFields(Cursor cursor) {
285        int calendarIdIndex = cursor.getColumnIndexOrThrow(Calendars._ID);
286        int colorIndex = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_COLOR);
287        int calendarNameIndex = cursor.getColumnIndexOrThrow(Calendars.CALENDAR_DISPLAY_NAME);
288        int accountNameIndex = cursor.getColumnIndexOrThrow(Calendars.ACCOUNT_NAME);
289
290        mCalendarId = cursor.getLong(calendarIdIndex);
291        mColor.setBackgroundColor(Utils.getDisplayColorFromColor(cursor
292                .getInt(colorIndex)));
293        String accountName = cursor.getString(accountNameIndex);
294        String calendarName = cursor.getString(calendarNameIndex);
295        mCalendarName.setText(calendarName);
296        if (calendarName.equals(accountName)) {
297            mAccountName.setVisibility(View.GONE);
298        } else {
299            mAccountName.setVisibility(View.VISIBLE);
300            mAccountName.setText(accountName);
301        }
302    }
303}
304