Merge "Batch join contacts"
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d4826a1..ca3f450 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -163,6 +163,7 @@
         <item name="android:textColor">@color/tab_text_color</item>
         <item name="android:textSize">@dimen/tab_text_size</item>
         <item name="android:fontFamily">@string/tab_font_family</item>
+        <item name="android:elevation">0dp</item>
         <item name="android:textStyle">bold</item>
     </style>
 
diff --git a/src/com/android/contacts/editor/CompactContactEditorFragment.java b/src/com/android/contacts/editor/CompactContactEditorFragment.java
index 94e2263..8af3d13 100644
--- a/src/com/android/contacts/editor/CompactContactEditorFragment.java
+++ b/src/com/android/contacts/editor/CompactContactEditorFragment.java
@@ -134,6 +134,7 @@
     private long mPhotoRawContactId;
     private Bundle mUpdatedPhotos = new Bundle();
     private MaterialColorMapUtils.MaterialPalette mMaterialPalette;
+    private boolean mShowToastAfterSave = true;
 
     @Override
     public void onCreate(Bundle savedState) {
@@ -289,6 +290,11 @@
     }
 
     @Override
+    protected boolean showToastAfterSave() {
+        return mShowToastAfterSave;
+    }
+
+    @Override
     protected boolean doSaveAction(int saveMode) {
         // Save contact
         final Intent intent = ContactSaveService.createSaveContactIntent(mContext, mState,
@@ -352,7 +358,8 @@
             // Pass on all the data that has been entered so far
             ArrayList<ContentValues> contentValues = mState.get(0).getContentValues();
             if (contentValues != null && contentValues.size() != 0) {
-                intent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contentValues);
+                intent.putParcelableArrayListExtra(
+                        ContactsContract.Intents.Insert.DATA, contentValues);
             }
             // Name must be passed separately since it is skipped in RawContactModifier.parseValues
             final StructuredNameEditorView structuredNameEditorView =
@@ -365,7 +372,10 @@
             }
             getActivity().finish();
         } else {
-            // Whatever is in the form will be saved when the hosting activity is finished
+            // Prevent a Toast from being displayed as we transition to the full editor
+            mShowToastAfterSave = false;
+
+            // Save whatever is in the form
             save(SaveMode.RELOAD);
         }
 
diff --git a/src/com/android/contacts/editor/ContactEditorBaseFragment.java b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
index d8c20fb..a7dd5f3 100644
--- a/src/com/android/contacts/editor/ContactEditorBaseFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorBaseFragment.java
@@ -1269,7 +1269,7 @@
             Uri contactLookupUri) {
         if (hadChanges) {
             if (saveSucceeded) {
-                if (saveMode != SaveMode.JOIN) {
+                if (saveMode != SaveMode.JOIN && showToastAfterSave()) {
                     Toast.makeText(mContext, R.string.contactSavedToast, Toast.LENGTH_SHORT).show();
                 }
             } else {
@@ -1323,6 +1323,14 @@
     }
 
     /**
+     * Whether to show a Toast message after saves have completed.
+     * Does not affect successful toasts shown after joins, which are never displayed.
+     */
+    protected boolean showToastAfterSave() {
+        return true;
+    }
+
+    /**
      * Shows a list of aggregates that can be joined into the currently viewed aggregate.
      *
      * @param contactLookupUri the fresh URI for the currently edited contact (after saving it)
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 209f2d3..adeb8ad 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -196,12 +196,6 @@
         }
     }
 
-    private static void appendQueryParameter(Uri.Builder builder, String field, String value) {
-        if (!TextUtils.isEmpty(value)) {
-            builder.appendQueryParameter(field, value);
-        }
-    }
-
     /**
      * Set the display name onto the text field directly.  This does not affect the underlying
      * data structure so it is similar to the user typing the value in on the field directly.
@@ -215,10 +209,15 @@
     }
 
     /**
-     * Returns the display name from the underlying ValuesDelta.
+     * Returns the display name currently displayed in the editor.
      */
     public String getDisplayName() {
-        return getValues().getDisplayName();
+        final ValuesDelta valuesDelta = getValues();
+        if (hasShortAndLongForms() && areOptionalFieldsVisible()) {
+            return valuesDelta.getDisplayName();
+        }
+        final Map<String, String> structuredNameMap = valuesToStructuredNameMap(valuesDelta);
+        return NameConverter.structuredNameToDisplayName(getContext(), structuredNameMap);
     }
 
     @Override