Hookup building the contact header widget from deltas.
Bug: 2126659
diff --git a/src/com/android/contacts/model/Editor.java b/src/com/android/contacts/model/Editor.java
index b7ae045..b3e8443 100644
--- a/src/com/android/contacts/model/Editor.java
+++ b/src/com/android/contacts/model/Editor.java
@@ -42,6 +42,7 @@
public void onRequest(int request);
public static final int REQUEST_PICK_PHOTO = 1;
+ public static final int FIELD_CHANGED = 2;
}
/**
diff --git a/src/com/android/contacts/model/EntityDelta.java b/src/com/android/contacts/model/EntityDelta.java
index 7ac0f5b..dfc4fc4 100644
--- a/src/com/android/contacts/model/EntityDelta.java
+++ b/src/com/android/contacts/model/EntityDelta.java
@@ -162,6 +162,44 @@
}
/**
+ * calls {@link #getSuperPrimaryEntry(String, boolean)} with true
+ * @see #getSuperPrimaryEntry(String, boolean)
+ */
+ public ValuesDelta getSuperPrimaryEntry(String mimeType) {
+ return getSuperPrimaryEntry(mimeType, true);
+ }
+
+ /**
+ * Returns the super-primary entry for the given mime type
+ * @param forceSelection if true, will try to return some value even if a super-primary
+ * doesn't exist (may be a primary, or just a random item
+ * @return
+ */
+ public ValuesDelta getSuperPrimaryEntry(String mimeType, boolean forceSelection) {
+ final ArrayList<ValuesDelta> mimeEntries = getMimeEntries(mimeType, false);
+ if (mimeEntries == null) return null;
+
+ ValuesDelta primary = null;
+ for (ValuesDelta entry : mimeEntries) {
+ if (entry.isSuperPrimary()) {
+ return entry;
+ } else if (entry.isPrimary()) {
+ primary = entry;
+ }
+ }
+
+ if (!forceSelection) {
+ return null;
+ }
+
+ // When no direct super primary, return something
+ if (primary != null) {
+ return primary;
+ }
+ return mimeEntries.size() > 0 ? mimeEntries.get(0) : null;
+ }
+
+ /**
* Return the list of child {@link ValuesDelta} from our optimized map,
* creating the list if requested.
*/
@@ -552,6 +590,11 @@
return mFromTemplate;
}
+ public boolean isSuperPrimary() {
+ final Long isSuperPrimary = getAsLong(Data.IS_SUPER_PRIMARY);
+ return isSuperPrimary == null ? false : isSuperPrimary != 0;
+ }
+
public boolean beforeExists() {
return (mBefore != null && mBefore.containsKey(mIdColumn));
}
diff --git a/src/com/android/contacts/model/EntitySet.java b/src/com/android/contacts/model/EntitySet.java
index 2137987..adc87ee 100644
--- a/src/com/android/contacts/model/EntitySet.java
+++ b/src/com/android/contacts/model/EntitySet.java
@@ -16,22 +16,24 @@
package com.android.contacts.model;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.google.android.collect.Lists;
-
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Entity;
import android.content.EntityIterator;
import android.content.ContentProviderOperation.Builder;
+import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.provider.ContactsContract.AggregationExceptions;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.RawContacts;
-import android.util.Log;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+
+import com.google.android.collect.Lists;
+
+import com.android.contacts.model.EntityDelta.ValuesDelta;
import java.util.ArrayList;
@@ -223,6 +225,30 @@
return -1;
}
+ public ValuesDelta getSuperPrimaryEntry(final String mimeType) {
+ ValuesDelta primary = null;
+ ValuesDelta randomEntry = null;
+ for (EntityDelta delta : this) {
+ final ArrayList<ValuesDelta> mimeEntries = delta.getMimeEntries(mimeType);
+ if (mimeEntries == null) return null;
+
+ for (ValuesDelta entry : mimeEntries) {
+ if (entry.isSuperPrimary()) {
+ return entry;
+ } else if (primary == null && entry.isPrimary()) {
+ primary = entry;
+ } else if (randomEntry == null) {
+ randomEntry = entry;
+ }
+ }
+ }
+ // When no direct super primary, return something
+ if (primary != null) {
+ return primary;
+ }
+ return randomEntry;
+ }
+
/** {@inheritDoc} */
public int describeContents() {
// Nothing special about this parcel
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index 450f4a9..9c0c69a 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -33,6 +33,7 @@
import android.content.Intent;
import android.content.OperationApplicationException;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
@@ -41,8 +42,10 @@
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts.Data;
+import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
@@ -62,12 +65,12 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
import com.android.contacts.ScrollingTabWidget;
-import com.android.contacts.model.GoogleSource;
import com.android.contacts.model.ContactsSource;
import com.android.contacts.model.Editor;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityModifier;
import com.android.contacts.model.EntitySet;
+import com.android.contacts.model.GoogleSource;
import com.android.contacts.model.Sources;
import com.android.contacts.model.Editor.EditorListener;
import com.android.contacts.model.EntityDelta.ValuesDelta;
@@ -131,6 +134,7 @@
// Build editor and listen for photo requests
mEditor = (ContactEditorView)this.findViewById(android.R.id.tabcontent);
mEditor.getPhotoEditor().setEditorListener(this);
+ mEditor.setNameEditorListener(this);
findViewById(R.id.btn_done).setOnClickListener(this);
findViewById(R.id.btn_discard).setOnClickListener(this);
@@ -141,10 +145,12 @@
if (Intent.ACTION_EDIT.equals(action) && !hasIncomingState) {
// Read initial state from database
new QueryEntitiesTask(this).execute(intent);
-
+ mHeader.showStar(true);
+ mHeader.setContactUri(intent.getData(), false);
} else if (Intent.ACTION_INSERT.equals(action) && !hasIncomingState) {
// Trigger dialog to pick account type
doAddAction();
+ mHeader.showStar(false);
}
}
@@ -372,20 +378,49 @@
protected void bindHeader() {
if (!hasValidState()) return;
- // TODO: rebuild header widget based on internal entities
+ boolean starred = false;
- // TODO: fill header bar with newly parsed data for speed
- // TODO: handle legacy case correctly instead of assuming _id
+ ValuesDelta photoDelta = mState.getSuperPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
+ if (photoDelta != null) {
+ final byte[] photoBytes = photoDelta.getAsByteArray(Photo.PHOTO);
+ if (photoBytes != null) {
+ Bitmap photo = BitmapFactory.decodeByteArray(photoBytes, 0,
+ photoBytes.length);
+ mHeader.setPhoto(photo);
+ }
+ }
-// if (mContactId > 0) {
-// mHeader.bindFromContactId(mContactId);
-// }
+ ValuesDelta nameDelta = mState.getSuperPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
+ if (nameDelta != null) {
+ String visibleName = getVisibleName(nameDelta);
+ if (visibleName != null) {
+ mHeader.setDisplayName(visibleName, null);
+ }
+ }
-// mHeader.setDisplayName(displayName, phoneticName);
-// mHeader.setPhoto(bitmap);
+ for (EntityDelta delta : mState) {
+ Long isCurrStarred = delta.getValues().getAsLong(RawContacts.STARRED);
+ starred = starred || (isCurrStarred != null && isCurrStarred != 0);
+ }
+ mHeader.setStared(starred);
}
+ private static String getVisibleName(ValuesDelta nameDelta) {
+ final String givenName = nameDelta.getAsString(StructuredName.GIVEN_NAME);
+ final String familyName = nameDelta.getAsString(StructuredName.FAMILY_NAME);
+ final boolean hasGiven = !TextUtils.isEmpty(givenName);
+ final boolean hasFamily = !TextUtils.isEmpty(familyName);
+ if (hasGiven && hasFamily) {
+ return givenName + " " + familyName;
+ } else if (hasFamily) {
+ return familyName;
+ } else if (hasGiven) {
+ return givenName;
+ } else {
+ return null;
+ }
+ }
/** {@inheritDoc} */
public void onTabSelectionChanged(int tabIndex, boolean clicked) {
@@ -452,6 +487,7 @@
// state and returned to the last-visible tab.
final Bitmap photo = data.getParcelableExtra("data");
mEditor.setPhotoBitmap(photo);
+ bindHeader();
break;
}
}
@@ -708,6 +744,10 @@
doPickPhotoAction();
break;
}
+ case EditorListener.FIELD_CHANGED: {
+ bindHeader();
+ break;
+ }
}
}
diff --git a/src/com/android/contacts/ui/widget/ContactEditorView.java b/src/com/android/contacts/ui/widget/ContactEditorView.java
index cd94e52..245986b 100644
--- a/src/com/android/contacts/ui/widget/ContactEditorView.java
+++ b/src/com/android/contacts/ui/widget/ContactEditorView.java
@@ -22,6 +22,7 @@
import com.android.contacts.model.EntityModifier;
import com.android.contacts.model.ContactsSource.DataKind;
import com.android.contacts.model.ContactsSource.EditType;
+import com.android.contacts.model.Editor.EditorListener;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import android.content.Context;
@@ -34,6 +35,7 @@
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -173,8 +175,8 @@
EntityModifier.ensureKindExists(state, source, Photo.CONTENT_ITEM_TYPE);
mHasPhotoEditor = (source.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null);
mPhoto.setVisibility(mHasPhotoEditor ? View.VISIBLE : View.GONE);
- mPhoto.setEnabled(!source.readOnly);
- mName.setEnabled(!source.readOnly);
+ mPhoto.setEnabled(!source.readOnly);
+ mName.setEnabled(!source.readOnly);
mReadOnly.setVisibility(source.readOnly ? View.VISIBLE : View.GONE);
@@ -204,4 +206,11 @@
}
}
}
+
+ /**
+ * Sets the {@link EditorListener} on the name field
+ */
+ public void setNameEditorListener(EditorListener listener) {
+ mName.setEditorListener(listener);
+ }
}
diff --git a/src/com/android/contacts/ui/widget/GenericEditorView.java b/src/com/android/contacts/ui/widget/GenericEditorView.java
index 6387374..6c782f8 100644
--- a/src/com/android/contacts/ui/widget/GenericEditorView.java
+++ b/src/com/android/contacts/ui/widget/GenericEditorView.java
@@ -17,14 +17,13 @@
package com.android.contacts.ui.widget;
import com.android.contacts.R;
+import com.android.contacts.model.Editor;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityModifier;
import com.android.contacts.model.ContactsSource.DataKind;
import com.android.contacts.model.ContactsSource.EditField;
import com.android.contacts.model.ContactsSource.EditType;
import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.model.Editor;
-import com.android.contacts.model.Editor.EditorListener;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -152,6 +151,9 @@
public void onFieldChanged(String column, String value) {
// Field changes are saved directly
mEntry.put(column, value);
+ if (mListener != null) {
+ mListener.onRequest(EditorListener.FIELD_CHANGED);
+ }
}
private void rebuildValues() {