From 6d24534804ddf54cd353ed46c4cbd6d23152f899 Mon Sep 17 00:00:00 2001 From: Tony Mantler Date: Fri, 9 Aug 2013 16:38:23 -0700 Subject: [PATCH] Continue rewriting QuickResponse support Change-Id: I95530e84d91f4becb3de5280af83ce546e1ed093 --- .../android/emailcommon/provider/Account.java | 4 + .../emailcommon/provider/EmailContent.java | 11 + res/layout/quick_response_item.xml | 4 +- .../activity/InsertQuickResponseDialog.java | 7 +- ...untSettingsEditQuickResponsesFragment.java | 217 +++++------------- .../setup/EditQuickResponseDialog.java | 103 ++++----- 6 files changed, 131 insertions(+), 215 deletions(-) diff --git a/emailcommon/src/com/android/emailcommon/provider/Account.java b/emailcommon/src/com/android/emailcommon/provider/Account.java index 76ef70d82..0e5f01520 100755 --- a/emailcommon/src/com/android/emailcommon/provider/Account.java +++ b/emailcommon/src/com/android/emailcommon/provider/Account.java @@ -255,6 +255,10 @@ public final class Account extends EmailContent implements AccountColumns, Parce return Long.parseLong(u.getPathSegments().get(1)); } + public long getId() { + return mId; + } + /** * @return the user-visible name for the account */ diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index 6d5465c2c..300e62e1a 100755 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -1582,12 +1582,23 @@ public abstract class EmailContent { } public interface QuickResponseColumns { + static final String ID = "_id"; // The QuickResponse text static final String TEXT = "quickResponse"; // A foreign key into the Account table owning the QuickResponse static final String ACCOUNT_KEY = "accountKey"; } + public static final int QUICK_RESPONSE_COLUMN_ID = 0; + public static final int QUICK_RESPONSE_COLUMN_TEXT = 1; + public static final int QUICK_RESPONSE_COLUMN_ACCOUNT = 2; + + public static final String [] QUICK_RESPONSE_PROJECTION = new String [] { + QuickResponseColumns.ID, + QuickResponseColumns.TEXT, + QuickResponseColumns.ACCOUNT_KEY + }; + public interface MailboxColumns { public static final String ID = "_id"; // The display name of this mailbox [INDEX] diff --git a/res/layout/quick_response_item.xml b/res/layout/quick_response_item.xml index af0966242..741e634b9 100644 --- a/res/layout/quick_response_item.xml +++ b/res/layout/quick_response_item.xml @@ -20,8 +20,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/listChoiceBackgroundIndicator" - android:focusable="true" + android:focusable="false" android:padding="7dip" + android:minHeight="?android:attr/listPreferredItemHeight" > diff --git a/src/com/android/email/activity/InsertQuickResponseDialog.java b/src/com/android/email/activity/InsertQuickResponseDialog.java index 0e0b04d40..36822b07e 100644 --- a/src/com/android/email/activity/InsertQuickResponseDialog.java +++ b/src/com/android/email/activity/InsertQuickResponseDialog.java @@ -17,8 +17,6 @@ package com.android.email.activity; import com.android.email.R; -import com.android.email.activity.setup. - AccountSettingsEditQuickResponsesFragment.QuickResponseFinder; import com.android.emailcommon.provider.Account; import com.android.emailcommon.utility.EmailAsyncTask; @@ -99,8 +97,9 @@ public class InsertQuickResponseDialog extends DialogFragment Account account = (Account) getArguments().getParcelable(ACCOUNT_KEY); mTaskTracker = new EmailAsyncTask.Tracker(); - new QuickResponseFinder(mTaskTracker, account.mId, mQuickResponsesView, - context, null, this, false).executeParallel(); + // TODO: fix everything + //new QuickResponseFinder(mTaskTracker, account.mId, mQuickResponsesView, + // context, null, this, false).executeParallel(); b.setTitle(getResources() .getString(R.string.message_compose_insert_quick_response_list_title)) diff --git a/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java b/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java index d440a39d1..d377b668e 100644 --- a/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java +++ b/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java @@ -29,18 +29,26 @@ import com.android.mail.utils.LogUtils; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; +import android.app.LoaderManager; +import android.content.ContentUris; import android.content.Context; +import android.content.CursorLoader; +import android.content.Loader; import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; +import android.widget.SimpleCursorAdapter; import android.widget.TextView; /** @@ -55,130 +63,12 @@ import android.widget.TextView; *

This fragment is run as a preference panel from AccountSettings.

*/ public class AccountSettingsEditQuickResponsesFragment extends Fragment { - private ListView mQuickResponsesView; private Account mAccount; - private Context mContext; - private EmailAsyncTask.Tracker mTaskTracker; + private SimpleCursorAdapter mAdapter; private static final String BUNDLE_KEY_ACTIVITY_TITLE = "AccountSettingsEditQuickResponsesFragment.title"; - // Helper class to place a TextView alongside "Delete" icon in the ListView - // displaying the QuickResponses - private static class ArrayAdapterWithButtons extends ArrayAdapter { - private QuickResponse[] mQuickResponses; - private final long mAccountId; - private final FragmentManager mFragmentManager; - - private final OnClickListener mOnEditListener = new OnClickListener() { - @Override - public void onClick(View view) { - QuickResponse quickResponse = (QuickResponse) (view.getTag()); - EditQuickResponseDialog - .newInstance(quickResponse, mAccountId) - .show(mFragmentManager, null); - } - }; - - private static final int resourceId = R.layout.quick_response_item; - private static final int textViewId = R.id.quick_response_text; - - /** - * Instantiates the custom ArrayAdapter, allowing editing and deletion of QuickResponses. - * @param context - context of owning activity - * @param quickResponses - the QuickResponses to represent in the ListView. - * @param fragmentManager - fragmentManager to which an EditQuickResponseDialog will - * attach itself. - * @param accountId - accountId of the QuickResponses - */ - public ArrayAdapterWithButtons( - Context context, QuickResponse[] quickResponses, - FragmentManager fragmentManager, long accountId) { - super(context, resourceId, textViewId, quickResponses); - mQuickResponses = quickResponses; - mAccountId = accountId; - mFragmentManager = fragmentManager; - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - convertView = super.getView(position, convertView, parent); - convertView.setTag(mQuickResponses[position]); - convertView.setOnClickListener(mOnEditListener); - - return convertView; - } - } - - /** - * Finds existing QuickResponses for the specified account and attaches the contents to - * a ListView. Optionally allows for editing and deleting of QuickResposnes from ListView. - */ - public static class QuickResponseFinder extends EmailAsyncTask { - private final long mAccountId; - private final ListView mQuickResponsesView; - private final Context mContext; - private final FragmentManager mFragmentManager; - private final OnItemClickListener mListener; - private final boolean mIsEditable; - - /** - * Finds all QuickResponses for the given account. Creates either a standard ListView - * with a caller-implemented listener or one with a custom adapter that allows deleting - * and editing of QuickResponses via EditQuickResponseDialog. - * - * @param tracker - tracks the finding and listing of QuickResponses. Should be canceled - * onDestroy() or when the results are no longer needed. - * @param accountId - id of the account whose QuickResponses are to be returned - * @param quickResponsesView - ListView to which an ArrayAdapter with the QuickResponses - * will be attached. - * @param context - context of the owning activity - * @param fragmentManager - required when isEditable is true so that an EditQuickResponse - * dialog may properly attach itself. Unused when isEditable is false. - * @param listener - optional when isEditable is true, unused when false. - * @param isEditable - specifies whether the ListView will allow for user editing of - * QuickResponses - */ - public QuickResponseFinder(EmailAsyncTask.Tracker tracker, long accountId, - ListView quickResponsesView, Context context, FragmentManager fragmentManager, - OnItemClickListener listener, boolean isEditable) { - super(tracker); - mAccountId = accountId; - mQuickResponsesView = quickResponsesView; - mContext = context; - mFragmentManager = fragmentManager; - mListener = listener; - mIsEditable = isEditable; - } - - @Override - protected QuickResponse[] doInBackground(Void... params) { - QuickResponse[] quickResponses = QuickResponse.restoreQuickResponsesWithAccountId( - mContext, mAccountId); - return quickResponses; - } - - @Override - protected void onSuccess(QuickResponse[] quickResponseItems) { - ArrayAdapter adapter; - if (mIsEditable) { - adapter = new ArrayAdapterWithButtons( - mContext, - quickResponseItems, - mFragmentManager, - mAccountId); - } else { - adapter = new ArrayAdapter( - mContext, - R.layout.insert_quick_response, - quickResponseItems - ); - mQuickResponsesView.setOnItemClickListener(mListener); - } - mQuickResponsesView.setAdapter(adapter); - } - } - @Override public void onAttach(Activity activity) { super.onAttach(activity); @@ -188,10 +78,38 @@ public class AccountSettingsEditQuickResponsesFragment extends Fragment { public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // startPreferencePanel launches this fragment with the right title initially, but - // if the device is rotate we must set the title ourselves + // if the device is rotated we must set the title ourselves if (savedInstanceState != null) { getActivity().setTitle(savedInstanceState.getString(BUNDLE_KEY_ACTIVITY_TITLE)); } + + mAdapter = new SimpleCursorAdapter(getActivity(), R.layout.quick_response_item, null, + new String [] {EmailContent.QuickResponseColumns.TEXT}, + new int [] {R.id.quick_response_text}, 0); + + final ListView listView = UiUtilities.getView(getView(), + R.id.account_settings_quick_responses_list); + listView.setAdapter(mAdapter); + + getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks() { + @Override + public Loader onCreateLoader(int id, Bundle args) { + final Uri baseUri = Uri.parse(EmailContent.CONTENT_URI + "/quickresponse/account"); + final Uri uri = ContentUris.withAppendedId(baseUri, mAccount.getId()); + return new CursorLoader(getActivity(), uri, EmailContent.QUICK_RESPONSE_PROJECTION, + null, null, null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + mAdapter.swapCursor(data); + } + + @Override + public void onLoaderReset(Loader loader) { + mAdapter.swapCursor(null); + } + }); } @Override @@ -208,7 +126,6 @@ public class AccountSettingsEditQuickResponsesFragment extends Fragment { Bundle args = getArguments(); mAccount = args.getParcelable("account"); - mTaskTracker = new EmailAsyncTask.Tracker(); } @Override @@ -217,45 +134,37 @@ public class AccountSettingsEditQuickResponsesFragment extends Fragment { if (Logging.DEBUG_LIFECYCLE && MailActivityEmail.DEBUG) { LogUtils.d(Logging.LOG_TAG, "AccountSettingsEditQuickResponsesFragment onCreateView"); } - View view = inflater.inflate(R.layout.account_settings_edit_quick_responses_fragment, + final View view = inflater.inflate(R.layout.account_settings_edit_quick_responses_fragment, container, false); - mContext = getActivity(); - mQuickResponsesView = UiUtilities.getView(view, + final ListView listView = UiUtilities.getView(view, R.id.account_settings_quick_responses_list); - TextView emptyView = - UiUtilities.getView(((ViewGroup) mQuickResponsesView.getParent()), R.id.empty_view); - mQuickResponsesView.setEmptyView(emptyView); - - new QuickResponseFinder(mTaskTracker, mAccount.mId, mQuickResponsesView, - mContext, getFragmentManager(), null, true) - .executeParallel(); - - this.getActivity().getContentResolver().registerContentObserver( - QuickResponse.CONTENT_URI, false, new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - new QuickResponseFinder(mTaskTracker, mAccount.mId, mQuickResponsesView, - mContext, getFragmentManager(), null, true) - .executeParallel(); - } - }); - - UiUtilities.getView(view, R.id.create_new).setOnClickListener(new OnClickListener() { + final TextView emptyView = + UiUtilities.getView((ViewGroup) listView.getParent(), R.id.empty_view); + listView.setEmptyView(emptyView); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override - public void onClick(View v) { - EditQuickResponseDialog - .newInstance(null, mAccount.mId) + public void onItemClick(AdapterView parent, View view, int position, long id) { + final Cursor c = (Cursor) listView.getItemAtPosition(position); + final int quickResponseId = c.getInt(EmailContent.QUICK_RESPONSE_COLUMN_ID); + final String quickResponseText = + c.getString(EmailContent.QUICK_RESPONSE_COLUMN_TEXT); + final Uri baseUri = Uri.parse(EmailContent.CONTENT_URI + "/quickresponse"); + final Uri uri = ContentUris.withAppendedId(baseUri, quickResponseId); + EditQuickResponseDialog.newInstance(quickResponseText, uri, mAccount.getId(), false) + .show(getFragmentManager(), null); + } + }); + final View createNewView = + UiUtilities.getView((ViewGroup) listView.getParent(), R.id.create_new); + createNewView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + final Uri baseUri = Uri.parse(EmailContent.CONTENT_URI + "/quickresponse"); + EditQuickResponseDialog.newInstance(null, baseUri, mAccount.getId(), true) .show(getFragmentManager(), null); } }); - return view; } - - @Override - public void onDestroy() { - mTaskTracker.cancellAllInterrupt(); - super.onDestroy(); - } -} \ No newline at end of file +} diff --git a/src/com/android/email/activity/setup/EditQuickResponseDialog.java b/src/com/android/email/activity/setup/EditQuickResponseDialog.java index 47cb2b18f..30c66237f 100644 --- a/src/com/android/email/activity/setup/EditQuickResponseDialog.java +++ b/src/com/android/email/activity/setup/EditQuickResponseDialog.java @@ -27,12 +27,12 @@ import android.app.DialogFragment; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; +import android.net.Uri; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; -import android.view.WindowManager; import android.widget.EditText; /** @@ -40,29 +40,30 @@ import android.widget.EditText; */ public class EditQuickResponseDialog extends DialogFragment { private EditText mQuickResponseEditText; - private QuickResponse mQuickResponse; private AlertDialog mDialog; - private static final String QUICK_RESPONSE_EDITED_STRING = "quick_response_edited_string"; - private static final String QUICK_RESPONSE = "quick_response"; + private static final String QUICK_RESPONSE_STRING = "quick_response_edited_string"; + private static final String QUICK_RESPONSE_CONTENT_URI = "quick_response_content_uri"; + private static final String QUICK_RESPONSE_CREATE = "quick_response_create"; + private static final String ACCOUNT_ID = "accountId"; /** * Creates a new dialog to edit an existing QuickResponse or create a new * one. * - * @param quickResponse - The QuickResponse fwhich the user is editing; - * null if user is creating a new QuickResponse. + * @param baseUri - The content Uri QuickResponse which the user is editing; * @param accountId - The accountId for the account which holds this QuickResponse + * @param create - True if this is a new QuickResponse */ - public static EditQuickResponseDialog newInstance( - QuickResponse quickResponse, long accountId) { + public static EditQuickResponseDialog newInstance(String text, + Uri baseUri, long accountId, boolean create) { final EditQuickResponseDialog dialog = new EditQuickResponseDialog(); - Bundle args = new Bundle(); - args.putLong("accountId", accountId); - if (quickResponse != null) { - args.putParcelable(QUICK_RESPONSE, quickResponse); - } + Bundle args = new Bundle(4); + args.putString(QUICK_RESPONSE_STRING, text); + args.putLong(ACCOUNT_ID, accountId); + args.putParcelable(QUICK_RESPONSE_CONTENT_URI, baseUri); + args.putBoolean(QUICK_RESPONSE_CREATE, create); dialog.setArguments(args); return dialog; @@ -70,20 +71,27 @@ public class EditQuickResponseDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - final Context context = getActivity(); - mQuickResponse = (QuickResponse) getArguments().getParcelable(QUICK_RESPONSE); - final View wrapper = LayoutInflater.from(context) + final long accountId = getArguments().getLong(ACCOUNT_ID); + final Uri uri = getArguments().getParcelable(QUICK_RESPONSE_CONTENT_URI); + final boolean create = getArguments().getBoolean(QUICK_RESPONSE_CREATE); + + String quickResponseSavedString = null; + if (savedInstanceState != null) { + quickResponseSavedString = + savedInstanceState.getString(QUICK_RESPONSE_STRING); + } + if (quickResponseSavedString == null) { + quickResponseSavedString = getArguments().getString(QUICK_RESPONSE_STRING); + } + + final View wrapper = LayoutInflater.from(getActivity()) .inflate(R.layout.quick_response_edit_dialog, null); mQuickResponseEditText = (EditText) wrapper.findViewById(R.id.quick_response_text); - if (savedInstanceState != null) { - String quickResponseSavedString = - savedInstanceState.getString(QUICK_RESPONSE_EDITED_STRING); - if (quickResponseSavedString != null) { - mQuickResponseEditText.setText(quickResponseSavedString); - } - } else if (mQuickResponse != null) { - mQuickResponseEditText.setText(mQuickResponse.toString()); + + if (quickResponseSavedString != null) { + mQuickResponseEditText.setText(quickResponseSavedString); } + mQuickResponseEditText.setSelection(mQuickResponseEditText.length()); mQuickResponseEditText.addTextChangedListener(new TextWatcher() { @Override @@ -102,49 +110,34 @@ public class EditQuickResponseDialog extends DialogFragment { new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - final long accountId = getArguments().getLong("accountId"); final String text = mQuickResponseEditText.getText().toString(); - final Context context = getActivity(); - if (mQuickResponse == null) { - mQuickResponse = new QuickResponse(accountId, text); + final ContentValues values = new ContentValues(2); + values.put(QuickResponseColumns.ACCOUNT_KEY, accountId); + values.put(QuickResponseColumns.TEXT, text); + + if (create) { + getActivity().getContentResolver().insert(uri, values); + } else { + getActivity().getContentResolver().update(uri, values, null, null); } - - // Insert the new QuickResponse into the database. Content watchers used to - // update the ListView of QuickResponses upon insertion. - EmailAsyncTask.runAsyncParallel(new Runnable() { - @Override - public void run() { - if (!mQuickResponse.isSaved()) { - mQuickResponse.save(context); - } else { - ContentValues values = new ContentValues(); - values.put(QuickResponseColumns.TEXT, text); - mQuickResponse.update(context, values); - } - } - - }); } }; DialogInterface.OnClickListener deleteClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (mQuickResponse == null) { - return; - } - // TODO: confirm delete - mQuickResponse.delete(context, mQuickResponse.getBaseUri(), - mQuickResponse.getId()); + getActivity().getContentResolver().delete(uri, null, null); } }; - final AlertDialog.Builder b = new AlertDialog.Builder(context); + final AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); b.setTitle(getResources().getString(R.string.edit_quick_response_dialog)) .setView(wrapper) .setNegativeButton(R.string.cancel_action, null) - .setPositiveButton(R.string.save_action, saveClickListener) - .setNeutralButton(R.string.delete, deleteClickListener); + .setPositiveButton(R.string.save_action, saveClickListener); + if (!create) { + b.setNeutralButton(R.string.delete, deleteClickListener); + } mDialog = b.create(); return mDialog; } @@ -152,8 +145,6 @@ public class EditQuickResponseDialog extends DialogFragment { @Override public void onResume() { super.onResume(); - mDialog.getWindow() - .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); if (mQuickResponseEditText.length() == 0) { mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); } @@ -164,6 +155,6 @@ public class EditQuickResponseDialog extends DialogFragment { public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString( - QUICK_RESPONSE_EDITED_STRING, mQuickResponseEditText.getText().toString()); + QUICK_RESPONSE_STRING, mQuickResponseEditText.getText().toString()); } }