AccountSettingsEditQuickResponsesFragment.java revision f419287f22ae44f25e1ba1f757ec33c7941bbfa8
1/*
2 * Copyright (C) 2011 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
17package com.android.email.activity.setup;
18
19import com.android.email.R;
20import com.android.email.activity.UiUtilities;
21import com.android.email2.ui.MailActivityEmail;
22import com.android.emailcommon.Logging;
23import com.android.emailcommon.provider.EmailContent;
24import com.android.emailcommon.provider.Account;
25import com.android.emailcommon.provider.QuickResponse;
26import com.android.emailcommon.utility.EmailAsyncTask;
27
28import android.app.Activity;
29import android.app.Fragment;
30import android.app.FragmentManager;
31import android.content.Context;
32import android.database.ContentObserver;
33import android.os.Bundle;
34import android.os.Handler;
35import android.util.Log;
36import android.view.LayoutInflater;
37import android.view.View;
38import android.view.View.OnClickListener;
39import android.view.ViewGroup;
40import android.widget.AdapterView.OnItemClickListener;
41import android.widget.ArrayAdapter;
42import android.widget.ImageView;
43import android.widget.ListView;
44import android.widget.TextView;
45
46/**
47 * Lists quick responses associated with the specified email account. Allows users to create,
48 * edit, and delete quick responses. Owning activity must:
49 * <ul>
50 *   <li>Launch this fragment using startPreferencePanel().</li>
51 *   <li>Provide an Account as an argument named "account". This account's quick responses
52 *   will be read and potentially modified.</li>
53 * </ul>
54 *
55 * <p>This fragment is run as a preference panel from AccountSettings.</p>
56 */
57public class AccountSettingsEditQuickResponsesFragment extends Fragment
58        implements OnClickListener {
59    private ListView mQuickResponsesView;
60    private Account mAccount;
61    private Context mContext;
62    private EmailAsyncTask.Tracker mTaskTracker;
63
64    private static final String BUNDLE_KEY_ACTIVITY_TITLE
65            = "AccountSettingsEditQuickResponsesFragment.title";
66
67    // Helper class to place a TextView alongside "Delete" icon in the ListView
68    // displaying the QuickResponses
69    private static class ArrayAdapterWithButtons extends ArrayAdapter<QuickResponse> {
70        private QuickResponse[] mQuickResponses;
71        private final long mAccountId;
72        private final Context mContext;
73        private final FragmentManager mFragmentManager;
74
75        private OnClickListener mOnEditListener = new OnClickListener() {
76            @Override
77            public void onClick(View view) {
78                    QuickResponse quickResponse = (QuickResponse) (view.getTag());
79                    EditQuickResponseDialog
80                            .newInstance(quickResponse, mAccountId)
81                            .show(mFragmentManager, null);
82            }
83        };
84
85        private OnClickListener mOnDeleteListener = new OnClickListener() {
86            @Override
87            public void onClick(View view) {
88                final QuickResponse quickResponse = (QuickResponse) view.getTag();
89
90                // Delete the QuickResponse from the database. Content watchers used to
91                // update the ListView of QuickResponses upon deletion.
92                EmailAsyncTask.runAsyncParallel(new Runnable() {
93                    @Override
94                    public void run() {
95                        EmailContent.delete(mContext, quickResponse.getBaseUri(),
96                                quickResponse.getId());
97                    }
98                });
99            }
100        };
101
102        private static final int resourceId = R.layout.quick_response_item;
103        private static final int textViewId = R.id.quick_response_text;
104
105        /**
106         * Instantiates the custom ArrayAdapter, allowing editing and deletion of QuickResponses.
107         * @param context - context of owning activity
108         * @param quickResponses - the QuickResponses to represent in the ListView.
109         * @param fragmentManager - fragmentManager to which an EditQuickResponseDialog will
110         * attach itself.
111         * @param accountId - accountId of the QuickResponses
112         */
113        public ArrayAdapterWithButtons(
114                Context context, QuickResponse[] quickResponses,
115                FragmentManager fragmentManager, long accountId) {
116            super(context, resourceId, textViewId, quickResponses);
117            mQuickResponses = quickResponses;
118            mAccountId = accountId;
119            mContext = context;
120            mFragmentManager = fragmentManager;
121        }
122
123        @Override
124        public View getView(final int position, View convertView, ViewGroup parent) {
125            convertView = super.getView(position, convertView, parent);
126            convertView.setTag(mQuickResponses[position]);
127            convertView.setOnClickListener(mOnEditListener);
128
129            ImageView deleteIcon = (ImageView) convertView.findViewById(R.id.delete_icon);
130            deleteIcon.setTag(mQuickResponses[position]);
131            deleteIcon.setOnClickListener(mOnDeleteListener);
132
133            return convertView;
134        }
135    }
136
137    /**
138     *  Finds existing QuickResponses for the specified account and attaches the contents to
139     *  a ListView. Optionally allows for editing and deleting of QuickResposnes from ListView.
140     */
141    public static class QuickResponseFinder extends EmailAsyncTask<Void, Void, QuickResponse[]> {
142        private final long mAccountId;
143        private final ListView mQuickResponsesView;
144        private final Context mContext;
145        private final FragmentManager mFragmentManager;
146        private final OnItemClickListener mListener;
147        private final boolean mIsEditable;
148
149        /**
150         * Finds all QuickResponses for the given account. Creates either a standard ListView
151         * with a caller-implemented listener or one with a custom adapter that allows deleting
152         * and editing of QuickResponses via EditQuickResponseDialog.
153         *
154         * @param tracker - tracks the finding and listing of QuickResponses. Should be canceled
155         * onDestroy() or when the results are no longer needed.
156         * @param accountId - id of the account whose QuickResponses are to be returned
157         * @param quickResponsesView - ListView to which an ArrayAdapter with the QuickResponses
158         * will be attached.
159         * @param context - context of the owning activity
160         * @param fragmentManager - required when isEditable is true so that an EditQuickResponse
161         * dialog may properly attach itself. Unused when isEditable is false.
162         * @param listener - optional when isEditable is true, unused when false.
163         * @param isEditable - specifies whether the ListView will allow for user editing of
164         * QuickResponses
165         */
166        public QuickResponseFinder(EmailAsyncTask.Tracker tracker, long accountId,
167                ListView quickResponsesView, Context context, FragmentManager fragmentManager,
168                OnItemClickListener listener, boolean isEditable) {
169            super(tracker);
170            mAccountId = accountId;
171            mQuickResponsesView = quickResponsesView;
172            mContext = context;
173            mFragmentManager = fragmentManager;
174            mListener = listener;
175            mIsEditable = isEditable;
176        }
177
178        @Override
179        protected QuickResponse[] doInBackground(Void... params) {
180            QuickResponse[] quickResponses = QuickResponse.restoreQuickResponsesWithAccountId(
181                    mContext, mAccountId);
182            return quickResponses;
183        }
184
185        @Override
186        protected void onSuccess(QuickResponse[] quickResponseItems) {
187            ArrayAdapter<QuickResponse> adapter;
188            if (mIsEditable) {
189                    adapter = new ArrayAdapterWithButtons(
190                    mContext,
191                    quickResponseItems,
192                    mFragmentManager,
193                    mAccountId);
194            } else {
195                adapter = new ArrayAdapter<QuickResponse>(
196                        mContext,
197                        R.layout.insert_quick_response,
198                        quickResponseItems
199                        );
200                mQuickResponsesView.setOnItemClickListener(mListener);
201            }
202            mQuickResponsesView.setAdapter(adapter);
203        }
204    }
205
206    @Override
207    public void onAttach(Activity activity) {
208        super.onAttach(activity);
209    }
210
211    @Override
212    public void onActivityCreated(Bundle savedInstanceState) {
213        super.onActivityCreated(savedInstanceState);
214        // startPreferencePanel launches this fragment with the right title initially, but
215        // if the device is rotate we must set the title ourselves
216        if (savedInstanceState != null) {
217            getActivity().setTitle(savedInstanceState.getString(BUNDLE_KEY_ACTIVITY_TITLE));
218        }
219    }
220
221    @Override
222    public void onSaveInstanceState(Bundle outState) {
223        outState.putString(BUNDLE_KEY_ACTIVITY_TITLE, (String) getActivity().getTitle());
224    }
225
226    @Override
227    public void onCreate(Bundle savedInstanceState) {
228        if (Logging.DEBUG_LIFECYCLE && MailActivityEmail.DEBUG) {
229            Log.d(Logging.LOG_TAG, "AccountSettingsEditQuickResponsesFragment onCreate");
230        }
231        super.onCreate(savedInstanceState);
232
233        Bundle args = getArguments();
234        mAccount = args.getParcelable("account");
235        mTaskTracker = new EmailAsyncTask.Tracker();
236    }
237
238    @Override
239    public View onCreateView(LayoutInflater inflater, ViewGroup container,
240            Bundle savedInstanceState) {
241        if (Logging.DEBUG_LIFECYCLE && MailActivityEmail.DEBUG) {
242            Log.d(Logging.LOG_TAG, "AccountSettingsEditQuickResponsesFragment onCreateView");
243        }
244        int layoutId = R.layout.account_settings_edit_quick_responses_fragment;
245        View view = inflater.inflate(layoutId, container, false);
246        mContext = getActivity();
247
248        mQuickResponsesView = UiUtilities.getView(view,
249                R.id.account_settings_quick_responses_list);
250        TextView emptyView = (TextView)
251                UiUtilities.getView(((ViewGroup) mQuickResponsesView.getParent()), R.id.empty_view);
252        mQuickResponsesView.setEmptyView(emptyView);
253
254        new QuickResponseFinder(mTaskTracker, mAccount.mId, mQuickResponsesView,
255                mContext, getFragmentManager(), null, true)
256                .executeParallel();
257
258        this.getActivity().getContentResolver().registerContentObserver(
259                QuickResponse.CONTENT_URI, false, new ContentObserver(new Handler()) {
260                    @Override
261                    public void onChange(boolean selfChange) {
262                        new QuickResponseFinder(mTaskTracker, mAccount.mId, mQuickResponsesView,
263                                mContext, getFragmentManager(), null, true)
264                                .executeParallel();
265                    }
266                });
267
268        UiUtilities.getView(view, R.id.create_new).setOnClickListener(this);
269
270        return view;
271    }
272
273    @Override
274    public void onDestroy() {
275        mTaskTracker.cancellAllInterrupt();
276        super.onDestroy();
277    }
278
279    /**
280     * Implements OnClickListener
281     */
282    @Override
283    public void onClick(View v) {
284        if (v.getId() == R.id.create_new) {
285            EditQuickResponseDialog
286                    .newInstance(null, mAccount.mId)
287                    .show(getFragmentManager(), null);
288        }
289    }
290}