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 17 package com.android.email.activity.setup; 18 19 import com.android.email.Email; 20 import com.android.email.R; 21 import com.android.email.activity.UiUtilities; 22 import com.android.emailcommon.Logging; 23 import com.android.emailcommon.provider.EmailContent; 24 import com.android.emailcommon.provider.Account; 25 import com.android.emailcommon.provider.QuickResponse; 26 import com.android.emailcommon.utility.EmailAsyncTask; 27 28 import android.app.Activity; 29 import android.app.Fragment; 30 import android.app.FragmentManager; 31 import android.content.Context; 32 import android.database.ContentObserver; 33 import android.os.Bundle; 34 import android.os.Handler; 35 import android.util.Log; 36 import android.view.LayoutInflater; 37 import android.view.View; 38 import android.view.View.OnClickListener; 39 import android.view.ViewGroup; 40 import android.widget.AdapterView.OnItemClickListener; 41 import android.widget.ArrayAdapter; 42 import android.widget.ImageView; 43 import android.widget.ListView; 44 import 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 */ 57 public 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 */ ArrayAdapterWithButtons( Context context, QuickResponse[] quickResponses, FragmentManager fragmentManager, long accountId)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 getView(final int position, View convertView, ViewGroup parent)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 */ QuickResponseFinder(EmailAsyncTask.Tracker tracker, long accountId, ListView quickResponsesView, Context context, FragmentManager fragmentManager, OnItemClickListener listener, boolean isEditable)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 doInBackground(Void... params)179 protected QuickResponse[] doInBackground(Void... params) { 180 QuickResponse[] quickResponses = QuickResponse.restoreQuickResponsesWithAccountId( 181 mContext, mAccountId); 182 return quickResponses; 183 } 184 185 @Override onSuccess(QuickResponse[] quickResponseItems)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 onAttach(Activity activity)207 public void onAttach(Activity activity) { 208 super.onAttach(activity); 209 } 210 211 @Override onActivityCreated(Bundle savedInstanceState)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 onSaveInstanceState(Bundle outState)222 public void onSaveInstanceState(Bundle outState) { 223 outState.putString(BUNDLE_KEY_ACTIVITY_TITLE, (String) getActivity().getTitle()); 224 } 225 226 @Override onCreate(Bundle savedInstanceState)227 public void onCreate(Bundle savedInstanceState) { 228 if (Logging.DEBUG_LIFECYCLE && Email.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 onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)239 public View onCreateView(LayoutInflater inflater, ViewGroup container, 240 Bundle savedInstanceState) { 241 if (Logging.DEBUG_LIFECYCLE && Email.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 onDestroy()274 public void onDestroy() { 275 mTaskTracker.cancellAllInterrupt(); 276 super.onDestroy(); 277 } 278 279 /** 280 * Implements OnClickListener 281 */ 282 @Override onClick(View v)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 }