Merge "Clear field if try to delete last field in section of contact editor"
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 1ec590c..5d9494c 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -625,7 +625,7 @@
                     }
 
                     @Override
-                    public void onDeleted(Editor removedEditor) {
+                    public void onDeleteRequested(Editor removedEditor) {
                     }
                 };
 
@@ -1673,7 +1673,9 @@
         }
 
         @Override
-        public void onDeleted(Editor removedEditor) {
+        public void onDeleteRequested(Editor removedEditor) {
+            // The picture cannot be deleted, it can only be removed, which is handled by
+            // onRemovePictureChosen()
         }
 
         /**
@@ -1697,7 +1699,7 @@
          * User has chosen to remove a picture
          */
         @Override
-        public void onRemovePictureChose() {
+        public void onRemovePictureChosen() {
             mEditor.setPhotoBitmap(null);
         }
 
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index a70bf3f..423ca94 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -30,9 +30,9 @@
 
     public interface EditorListener {
         /**
-         * Called when the given {@link Editor} has been deleted.
+         * Called when the given {@link Editor} is requested to be deleted by the user.
          */
-        public void onDeleted(Editor editor);
+        public void onDeleteRequested(Editor editor);
 
         /**
          * Called when the given {@link Editor} has a request, for example it
@@ -75,4 +75,14 @@
      * allowing advanced editors to persist data in a specific way.
      */
     public void onFieldChanged(String column, String value);
+
+    /**
+     * Performs the delete operation for this {@link Editor}.
+     */
+    public void deleteEditor();
+
+    /**
+     * Clears all fields in this {@link Editor}.
+     */
+    public void clearAllFields();
 }
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 41d564a..4c5affd 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -242,4 +242,14 @@
     public static int getDefaultHourForBirthday() {
         return DEFAULT_HOUR;
     }
+
+    @Override
+    public void clearAllFields() {
+        // Update UI
+        mDateView.setText("");
+
+        // Update state
+        final String column = getKind().fieldList.get(0).column;
+        onFieldChanged(column, "");
+    }
 }
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index c4da9fa..3b46307 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -106,14 +106,19 @@
         });
     }
 
-    /** {@inheritDoc} */
     @Override
-    public void onDeleted(Editor editor) {
+    public void onDeleteRequested(Editor editor) {
+        // If there is only 1 editor in the section, then don't allow the user to delete it.
+        // Just clear the fields in the editor.
+        if (getEditorCount() == 1) {
+            editor.clearAllFields();
+        } else {
+            // Otherwise it's okay to delete this {@link Editor}
+            editor.deleteEditor();
+        }
         updateAddFooterVisible();
-        updateSectionVisible();
     }
 
-    /** {@inheritDoc} */
     @Override
     public void onRequest(int request) {
         // If a field has become empty or non-empty, then check if another row
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 91819a2..5bba2c4 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -75,6 +75,7 @@
     private boolean mReadOnly;
     private boolean mWasEmpty = true;
     private boolean mIsDeletable = true;
+    private boolean mIsAttachedToWindow;
 
     private EditType mType;
 
@@ -137,14 +138,17 @@
                 new Handler().post(new Runnable() {
                     @Override
                     public void run() {
-                        // Keep around in model, but mark as deleted
-                        mEntry.markDeleted();
-
-                        ((ViewGroup) getParent()).removeView(LabeledEditorView.this);
-
+                        // Don't do anything if the view is no longer attached to the window
+                        // (This check is needed because when this {@link Runnable} is executed,
+                        // we can't guarantee the view is still valid.
+                        if (!mIsAttachedToWindow) {
+                            return;
+                        }
+                        // Send the delete request to the listener (which will in turn call
+                        // deleteEditor() on this view if the deletion is valid - i.e. this is not
+                        // the last {@link Editor} in the section).
                         if (mListener != null) {
-                            // Notify listener when present
-                            mListener.onDeleted(LabeledEditorView.this);
+                            mListener.onDeleteRequested(LabeledEditorView.this);
                         }
                     }
                 });
@@ -152,6 +156,29 @@
         });
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        // Keep track of when the view is attached or detached from the window, so we know it's
+        // safe to remove views (in case the user requests to delete this editor).
+        mIsAttachedToWindow = true;
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mIsAttachedToWindow = false;
+    }
+
+    @Override
+    public void deleteEditor() {
+        // Keep around in model, but mark as deleted
+        mEntry.markDeleted();
+
+        // Remove the view
+        ((ViewGroup) getParent()).removeView(LabeledEditorView.this);
+    }
+
     public boolean isReadOnly() {
         return mReadOnly;
     }
diff --git a/src/com/android/contacts/editor/PhotoActionPopup.java b/src/com/android/contacts/editor/PhotoActionPopup.java
index bc50da9..ac2d64f 100644
--- a/src/com/android/contacts/editor/PhotoActionPopup.java
+++ b/src/com/android/contacts/editor/PhotoActionPopup.java
@@ -83,7 +83,7 @@
                         listener.onUseAsPrimaryChosen();
                         break;
                     case ChoiceListItem.ID_REMOVE:
-                        listener.onRemovePictureChose();
+                        listener.onRemovePictureChosen();
                         break;
                     case ChoiceListItem.ID_TAKE_PHOTO:
                         listener.onTakePhotoChosen();
@@ -131,7 +131,7 @@
 
     public interface Listener {
         void onUseAsPrimaryChosen();
-        void onRemovePictureChose();
+        void onRemovePictureChosen();
         void onTakePhotoChosen();
         void onPickFromGalleryChosen();
     }
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 7b86291..b9b8c2c 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -183,4 +183,14 @@
     public boolean isEmpty() {
         return !mHasSetPhoto;
     }
+
+    @Override
+    public void deleteEditor() {
+        // Photo is not deletable
+    }
+
+    @Override
+    public void clearAllFields() {
+        resetDefault();
+    }
 }
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index ad1c7b6..0d8aba6 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -405,4 +405,14 @@
             }
         }
     }
+
+    @Override
+    public void clearAllFields() {
+        if (mFieldEditTexts != null) {
+            for (EditText fieldEditText : mFieldEditTexts) {
+                // Update UI (which will trigger a state change through the {@link TextWatcher})
+                fieldEditText.setText("");
+            }
+        }
+    }
 }