Fixed group editing popup from contact editor

Removed checkbox next to the last "Create new group" option
in popup and removed square brackets in string.

After creating a new group, the view shows the popup again
with the newly create group visible and checked.  This is
accomplished via a listener interface to the
GroupCreationDialogFragment.  The tricky part to this is if
the user changes device orientation while the
GroupCreationDialogFragment is open.  The ContactEditorFragment
will save the resource id of the RawContactEditorView (since
there can be many via joins) and the view id of the
GroupMembershipView which is the listener.

Bug: 6013015
Change-Id: Ia50a68fb6f4631995ae913182765efb24ef227ec
diff --git a/res/layout/item_group_membership.xml b/res/layout/item_group_membership.xml
index 47f99b2..91480cc 100644
--- a/res/layout/item_group_membership.xml
+++ b/res/layout/item_group_membership.xml
@@ -16,6 +16,7 @@
 
 <com.android.contacts.editor.GroupMembershipView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/group_membership_view"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical">
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bf4be1a..1c375e8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1505,7 +1505,7 @@
     <string name="create_group_dialog_title">Create new group</string>
 
     <!-- An item in the popup list of groups that triggers creation of a contact group [CHAR LIMIT=128] -->
-    <string name="create_group_item_label">[Create new group]</string>
+    <string name="create_group_item_label">Create new group</string>
 
     <!-- Shows how many groups are from the specified account [CHAR LIMIT=15] -->
     <plurals name="num_groups_in_account">
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index a92c49c..a8e8d03 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -19,6 +19,7 @@
 import com.android.contacts.GroupMetaDataLoader;
 import com.android.contacts.R;
 import com.android.contacts.interactions.GroupCreationDialogFragment;
+import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
 import com.android.contacts.model.DataKind;
 import com.android.contacts.model.EntityDelta;
 import com.android.contacts.model.EntityDelta.ValuesDelta;
@@ -35,9 +36,11 @@
 import android.util.AttributeSet;
 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.CheckedTextView;
 import android.widget.LinearLayout;
 import android.widget.ListPopupWindow;
 import android.widget.ListView;
@@ -83,19 +86,61 @@
         }
     }
 
+    /**
+     * Extends the array adapter to show checkmarks on all but the last list item for
+     * the group membership popup.  Note that this is highly specific to the fact that the
+     * group_membership_list_item.xml is a CheckedTextView object.
+     */
+    private class GroupMembershipAdapter<T> extends ArrayAdapter<T> {
+
+        public GroupMembershipAdapter(Context context, int textViewResourceId) {
+            super(context, textViewResourceId);
+        }
+
+        public boolean getItemIsCheckable(int position) {
+            // Item is checkable if it is NOT the last one in the list
+            return position != getCount()-1;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return getItemIsCheckable(position) ? 0 : 1;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 2;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final View itemView = super.getView(position, convertView, parent);
+
+            // Hide the checkable drawable.  This assumes that the item views
+            // are CheckedTextView objects
+            final CheckedTextView checkedTextView = (CheckedTextView)itemView;
+            if (!getItemIsCheckable(position)) {
+                checkedTextView.setCheckMarkDrawable(null);
+            }
+
+            return checkedTextView;
+        }
+    }
+
     private EntityDelta mState;
     private Cursor mGroupMetaData;
     private String mAccountName;
     private String mAccountType;
     private String mDataSet;
     private TextView mGroupList;
-    private ArrayAdapter<GroupSelectionItem> mAdapter;
+    private GroupMembershipAdapter<GroupSelectionItem> mAdapter;
     private long mDefaultGroupId;
     private long mFavoritesGroupId;
     private ListPopupWindow mPopup;
     private DataKind mKind;
     private boolean mDefaultGroupVisibilityKnown;
     private boolean mDefaultGroupVisible;
+    private boolean mCreatedNewGroup;
 
     private String mNoGroupString;
     private int mPrimaryTextColor;
@@ -135,6 +180,21 @@
     public void setGroupMetaData(Cursor groupMetaData) {
         this.mGroupMetaData = groupMetaData;
         updateView();
+        // Open up the list of groups if a new group was just created.
+        if (mCreatedNewGroup) {
+            mCreatedNewGroup = false;
+            onClick(this); // This causes the popup to open.
+            if (mPopup != null) {
+                // Ensure that the newly created group is checked.
+                int position = mAdapter.getCount() - 2;
+                ListView listView = mPopup.getListView();
+                if (!listView.isItemChecked(position)) {
+                    // Newly created group is not checked, so check it.
+                    listView.setItemChecked(position, true);
+                    onItemClick(listView, null, position, listView.getItemIdAtPosition(position));
+                }
+            }
+        }
     }
 
     public void setState(EntityDelta state) {
@@ -144,6 +204,7 @@
         mAccountName = values.getAsString(RawContacts.ACCOUNT_NAME);
         mDataSet = values.getAsString(RawContacts.DATA_SET);
         mDefaultGroupVisibilityKnown = false;
+        mCreatedNewGroup = false;
         updateView();
     }
 
@@ -226,7 +287,7 @@
             return;
         }
 
-        mAdapter = new ArrayAdapter<GroupSelectionItem>(
+        mAdapter = new GroupMembershipAdapter<GroupSelectionItem>(
                 getContext(), R.layout.group_membership_list_item);
 
         mGroupMetaData.moveToPosition(-1);
@@ -356,7 +417,16 @@
         }
 
         GroupCreationDialogFragment.show(
-                ((Activity) getContext()).getFragmentManager(), mAccountType, mAccountName,
-                mDataSet);
+                ((Activity) getContext()).getFragmentManager(),
+                mAccountType,
+                mAccountName,
+                mDataSet,
+                new OnGroupCreatedListener() {
+                    @Override
+                    public void onGroupCreated() {
+                        mCreatedNewGroup = true;
+                    }
+                });
     }
+
 }
diff --git a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
index 224b4a0..051dc13 100644
--- a/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
+++ b/src/com/android/contacts/interactions/GroupCreationDialogFragment.java
@@ -33,16 +33,38 @@
     private static final String ARG_ACCOUNT_NAME = "accountName";
     private static final String ARG_DATA_SET = "dataSet";
 
+    public static final String FRAGMENT_TAG = "createGroupDialog";
+
+    private final OnGroupCreatedListener mListener;
+
+    public interface OnGroupCreatedListener {
+        public void onGroupCreated();
+    }
+
     public static void show(
             FragmentManager fragmentManager, String accountType, String accountName,
-            String dataSet) {
-        GroupCreationDialogFragment dialog = new GroupCreationDialogFragment();
+            String dataSet, OnGroupCreatedListener listener) {
+        GroupCreationDialogFragment dialog = new GroupCreationDialogFragment(listener);
         Bundle args = new Bundle();
         args.putString(ARG_ACCOUNT_TYPE, accountType);
         args.putString(ARG_ACCOUNT_NAME, accountName);
         args.putString(ARG_DATA_SET, dataSet);
         dialog.setArguments(args);
-        dialog.show(fragmentManager, "createGroup");
+        dialog.show(fragmentManager, FRAGMENT_TAG);
+    }
+
+    public GroupCreationDialogFragment() {
+        super();
+        mListener = null;
+    }
+
+    private GroupCreationDialogFragment(OnGroupCreatedListener listener) {
+        super();
+        mListener = listener;
+    }
+
+    public OnGroupCreatedListener getOnGroupCreatedListener() {
+        return mListener;
     }
 
     @Override
@@ -61,6 +83,13 @@
         String accountName = arguments.getString(ARG_ACCOUNT_NAME);
         String dataSet = arguments.getString(ARG_DATA_SET);
 
+        // Indicate to the listener that a new group will be created.
+        // If the device is rotated, mListener will become null, so that the
+        // popup from GroupMembershipView will not be shown.
+        if (mListener != null) {
+            mListener.onGroupCreated();
+        }
+
         Activity activity = getActivity();
         activity.startService(ContactSaveService.createNewGroupIntent(activity,
                 new AccountWithDataSet(accountName, accountType, dataSet), groupLabel,