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 */ 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 && 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 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 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 }