Merge "Continue rewriting QuickResponse support" into jb-ub-mail-ur10
diff --git a/emailcommon/src/com/android/emailcommon/provider/Account.java b/emailcommon/src/com/android/emailcommon/provider/Account.java
index 76ef70d..0e5f015 100755
--- a/emailcommon/src/com/android/emailcommon/provider/Account.java
+++ b/emailcommon/src/com/android/emailcommon/provider/Account.java
@@ -255,6 +255,10 @@
         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 6d5465c..300e62e 100755
--- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
+++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
@@ -1582,12 +1582,23 @@
     }
 
     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 af09662..741e634 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"
     >
         <TextView
             android:id="@+id/quick_response_text"
@@ -32,5 +33,6 @@
             android:ellipsize="end"
             android:focusable="false"
             android:maxLines="2"
+            android:textIsSelectable="false"
             />
 </LinearLayout>
diff --git a/src/com/android/email/activity/InsertQuickResponseDialog.java b/src/com/android/email/activity/InsertQuickResponseDialog.java
index 0e0b04d..36822b0 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 @@
 
         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 d440a39..d377b66 100644
--- a/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java
+++ b/src/com/android/email/activity/setup/AccountSettingsEditQuickResponsesFragment.java
@@ -29,18 +29,26 @@
 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 @@
  * <p>This fragment is run as a preference panel from AccountSettings.</p>
  */
 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<QuickResponse> {
-        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<Void, Void, QuickResponse[]> {
-        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<QuickResponse> adapter;
-            if (mIsEditable) {
-                    adapter = new ArrayAdapterWithButtons(
-                    mContext,
-                    quickResponseItems,
-                    mFragmentManager,
-                    mAccountId);
-            } else {
-                adapter = new ArrayAdapter<QuickResponse>(
-                        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 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<Cursor>() {
+            @Override
+            public Loader<Cursor> 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<Cursor> loader, Cursor data) {
+                mAdapter.swapCursor(data);
+            }
+
+            @Override
+            public void onLoaderReset(Loader<Cursor> loader) {
+                mAdapter.swapCursor(null);
+            }
+        });
     }
 
     @Override
@@ -208,7 +126,6 @@
 
         Bundle args = getArguments();
         mAccount = args.getParcelable("account");
-        mTaskTracker = new EmailAsyncTask.Tracker();
     }
 
     @Override
@@ -217,45 +134,37 @@
         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 47cb2b1..30c6623 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.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 @@
  */
 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 @@
 
     @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 @@
                 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 @@
     @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 void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putString(
-                QUICK_RESPONSE_EDITED_STRING, mQuickResponseEditText.getText().toString());
+                QUICK_RESPONSE_STRING, mQuickResponseEditText.getText().toString());
     }
 }