OSDN Git Service

Hookup building the contact header widget from deltas.
authorNeel Parekh <neel@google.com>
Mon, 21 Sep 2009 23:57:03 +0000 (16:57 -0700)
committerNeel Parekh <neel@google.com>
Wed, 30 Sep 2009 17:09:39 +0000 (10:09 -0700)
Bug: 2126659

src/com/android/contacts/model/Editor.java
src/com/android/contacts/model/EntityDelta.java
src/com/android/contacts/model/EntitySet.java
src/com/android/contacts/ui/EditContactActivity.java
src/com/android/contacts/ui/widget/ContactEditorView.java
src/com/android/contacts/ui/widget/GenericEditorView.java

index b7ae045..b3e8443 100644 (file)
@@ -42,6 +42,7 @@ public interface Editor {
         public void onRequest(int request);
 
         public static final int REQUEST_PICK_PHOTO = 1;
+        public static final int FIELD_CHANGED = 2;
     }
 
     /**
index 7ac0f5b..dfc4fc4 100644 (file)
@@ -162,6 +162,44 @@ public class EntityDelta implements Parcelable {
     }
 
     /**
+     * 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 @@ public class EntityDelta implements Parcelable {
             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));
         }
index 2137987..adc87ee 100644 (file)
 
 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 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
         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
index 450f4a9..9c0c69a 100644 (file)
@@ -33,6 +33,7 @@ import android.content.Entity;
 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.Contacts;
 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.google.android.collect.Lists;
 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 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         // 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 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         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 @@ public final class EditContactActivity extends Activity implements View.OnClickL
     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 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                 // state and returned to the last-visible tab.
                 final Bitmap photo = data.getParcelableExtra("data");
                 mEditor.setPhotoBitmap(photo);
+                bindHeader();
                 break;
             }
         }
@@ -708,6 +744,10 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                 doPickPhotoAction();
                 break;
             }
+            case EditorListener.FIELD_CHANGED: {
+                bindHeader();
+                break;
+            }
         }
     }
 
index cd94e52..245986b 100644 (file)
@@ -22,6 +22,7 @@ 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.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.Data;
 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 @@ public class ContactEditorView extends RelativeLayout implements OnClickListener
         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 @@ public class ContactEditorView extends RelativeLayout implements OnClickListener
             }
         }
     }
+
+    /**
+     * Sets the {@link EditorListener} on the name field
+     */
+    public void setNameEditorListener(EditorListener listener) {
+        mName.setEditorListener(listener);
+    }
 }
index 6387374..6c782f8 100644 (file)
 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 class GenericEditorView extends RelativeLayout implements Editor, View.On
     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() {