OSDN Git Service

Moving contact split functionality to contact Edit
authorDmitri Plotnikov <dplotnikov@google.com>
Thu, 1 Oct 2009 03:06:03 +0000 (20:06 -0700)
committerDmitri Plotnikov <dplotnikov@google.com>
Thu, 1 Oct 2009 03:14:07 +0000 (20:14 -0700)
Change-Id: I1172406d9eaed9b996d0376ff23413c8d7848d06

res/menu/edit.xml
src/com/android/contacts/model/EntitySet.java
src/com/android/contacts/ui/EditContactActivity.java

index 3a24f27..658a567 100644 (file)
         android:icon="@android:drawable/ic_menu_delete"
         android:title="@string/removePicture" />
 
+    <item
+        android:id="@+id/menu_split"
+        android:icon="@drawable/ic_menu_merge"
+        android:title="@string/menu_splitAggregate" />
+
+    <item
+        android:id="@+id/menu_join"
+        android:icon="@drawable/ic_menu_merge"
+        android:title="@string/menu_joinAggregate" />
 </menu>
index adc87ee..be2f70f 100644 (file)
@@ -43,6 +43,8 @@ import java.util.ArrayList;
  * and applying another {@link EntitySet} over it.
  */
 public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
+    private boolean mSplitRawContacts;
+
     private EntitySet() {
     }
 
@@ -128,15 +130,22 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
         }
 
         final int assertMark = diff.size();
+        int backRefs[] = new int[size()];
+
+        int rawContactIndex = 0;
 
         // Second pass builds actual operations
         for (EntityDelta delta : this) {
             final int firstBatch = diff.size();
+            backRefs[rawContactIndex++] = firstBatch;
             delta.buildDiff(diff);
 
             // Only create rules for inserts
             if (!delta.isContactInsert()) continue;
 
+            // If we are going to split all contacts, there is no point in first combining them
+            if (mSplitRawContacts) continue;
+
             if (rawContactId != -1) {
                 // Has existing contact, so bind to it strongly
                 final Builder builder = beginKeepTogether();
@@ -157,6 +166,10 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
             }
         }
 
+        if (mSplitRawContacts) {
+            buildSplitContactDiff(diff, backRefs);
+        }
+
         // No real changes if only left with asserts
         if (diff.size() == assertMark) {
             diff.clear();
@@ -177,6 +190,47 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
     }
 
     /**
+     * Builds {@link AggregationExceptions} to split all constituent raw contacts into
+     * separate contacts.
+     */
+    private void buildSplitContactDiff(final ArrayList<ContentProviderOperation> diff,
+            int[] backRefs) {
+        int count = size();
+        for (int i = 0; i < count; i++) {
+            for (int j = 0; j < count; j++) {
+                if (i != j) {
+                    buildSplitContactDiff(diff, i, j, backRefs);
+                }
+            }
+        }
+    }
+
+    /**
+     * Construct a {@link AggregationExceptions#TYPE_KEEP_SEPARATE}.
+     */
+    private void buildSplitContactDiff(ArrayList<ContentProviderOperation> diff, int index1,
+            int index2, int[] backRefs) {
+        Builder builder =
+                ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI);
+        builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_SEPARATE);
+
+        Long rawContactId1 = get(index1).getValues().getAsLong(RawContacts._ID);
+        if (rawContactId1 != null && rawContactId1 >= 0) {
+            builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
+        } else {
+            builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID1, backRefs[index1]);
+        }
+
+        Long rawContactId2 = get(index2).getValues().getAsLong(RawContacts._ID);
+        if (rawContactId2 != null && rawContactId2 >= 0) {
+            builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
+        } else {
+            builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, backRefs[index2]);
+        }
+        diff.add(builder.build());
+    }
+
+    /**
      * Search all contained {@link EntityDelta} for the first one with an
      * existing {@link RawContacts#_ID} value. Usually used when creating
      * {@link AggregationExceptions} during an update.
@@ -249,6 +303,10 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
         return randomEntry;
     }
 
+    public void splitRawContacts() {
+        mSplitRawContacts = true;
+    }
+
     /** {@inheritDoc} */
     public int describeContents() {
         // Nothing special about this parcel
index 9c0c69a..5e9959f 100644 (file)
@@ -96,6 +96,9 @@ public final class EditContactActivity extends Activity implements View.OnClickL
     private static final String KEY_EDIT_STATE = "state";
     private static final String KEY_SELECTED_RAW_CONTACT = "selected";
 
+    /** The result code when view activity should close after edit returns */
+    public static final int RESULT_CLOSE_VIEW_ACTIVITY = 777;
+
     private String mQuerySelection;
 
     private ScrollingTabWidget mTabWidget;
@@ -363,7 +366,7 @@ public final class EditContactActivity extends Activity implements View.OnClickL
             this.setSelectedRawContactId(selectedRawContactId);
         } else {
             // Nothing remains to edit, save and bail entirely
-            this.doSaveAction();
+            this.doSaveAction(RESULT_OK);
         }
 
         // Show editor now that we've loaded state
@@ -461,7 +464,7 @@ public final class EditContactActivity extends Activity implements View.OnClickL
     public void onClick(View view) {
         switch (view.getId()) {
             case R.id.btn_done:
-                doSaveAction();
+                doSaveAction(RESULT_OK);
                 break;
             case R.id.btn_discard:
                 doRevertAction();
@@ -472,7 +475,7 @@ public final class EditContactActivity extends Activity implements View.OnClickL
     /** {@inheritDoc} */
     @Override
     public void onBackPressed() {
-        doSaveAction();
+        doSaveAction(RESULT_OK);
     }
 
     /** {@inheritDoc} */
@@ -519,7 +522,7 @@ public final class EditContactActivity extends Activity implements View.OnClickL
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.menu_done:
-                return doSaveAction();
+                return doSaveAction(RESULT_OK);
             case R.id.menu_discard:
                 return doRevertAction();
             case R.id.menu_add:
@@ -530,6 +533,10 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                 return doPickPhotoAction();
             case R.id.menu_photo_remove:
                 return doRemovePhotoAction();
+            case R.id.menu_split:
+                return doSplitContactAction();
+            case R.id.menu_join:
+                return doJoinContactAction();
         }
         return false;
     }
@@ -552,8 +559,11 @@ public final class EditContactActivity extends Activity implements View.OnClickL
 
         private WeakReference<ProgressDialog> progress;
 
-        public PersistTask(EditContactActivity target) {
+        private final int mResultCode;
+
+        public PersistTask(EditContactActivity target, int resultCode) {
             super(target);
+            mResultCode = resultCode;
         }
 
         /** {@inheritDoc} */
@@ -599,7 +609,7 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                          final Uri contactLookupUri = RawContacts.getContactLookupUri(resolver,
                                  rawContactUri);
                          intent.setData(contactLookupUri);
-                         target.setResult(RESULT_OK, intent);
+                         target.setResult(mResultCode, intent);
                          target.finish();
                     }
                     result = (diff.size() > 0) ? RESULT_SUCCESS : RESULT_UNCHANGED;
@@ -665,10 +675,10 @@ public final class EditContactActivity extends Activity implements View.OnClickL
      * Saves or creates the contact based on the mode, and if successful
      * finishes the activity.
      */
-    private boolean doSaveAction() {
+    private boolean doSaveAction(int resultCode) {
         if (!hasValidState()) return false;
 
-        final PersistTask task = new PersistTask(this);
+        final PersistTask task = new PersistTask(this, resultCode);
         task.execute(mState);
 
         return true;
@@ -751,6 +761,16 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         }
     }
 
+    private boolean doSplitContactAction() {
+        mState.splitRawContacts();
+        return doSaveAction(RESULT_CLOSE_VIEW_ACTIVITY);
+    }
+
+    private boolean doJoinContactAction() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+