Merge change I1172406d into eclair
* changes:
Moving contact split functionality to contact Edit
diff --git a/res/menu/edit.xml b/res/menu/edit.xml
index 3a24f27..658a567 100644
--- a/res/menu/edit.xml
+++ b/res/menu/edit.xml
@@ -47,4 +47,13 @@
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>
diff --git a/src/com/android/contacts/model/EntitySet.java b/src/com/android/contacts/model/EntitySet.java
index adc87ee..be2f70f 100644
--- a/src/com/android/contacts/model/EntitySet.java
+++ b/src/com/android/contacts/model/EntitySet.java
@@ -43,6 +43,8 @@
* and applying another {@link EntitySet} over it.
*/
public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
+ private boolean mSplitRawContacts;
+
private EntitySet() {
}
@@ -128,15 +130,22 @@
}
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 @@
}
}
+ if (mSplitRawContacts) {
+ buildSplitContactDiff(diff, backRefs);
+ }
+
// No real changes if only left with asserts
if (diff.size() == assertMark) {
diff.clear();
@@ -177,6 +190,47 @@
}
/**
+ * 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 @@
return randomEntry;
}
+ public void splitRawContacts() {
+ mSplitRawContacts = true;
+ }
+
/** {@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 9c0c69a..5e9959f 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -96,6 +96,9 @@
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 @@
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 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 @@
/** {@inheritDoc} */
@Override
public void onBackPressed() {
- doSaveAction();
+ doSaveAction(RESULT_OK);
}
/** {@inheritDoc} */
@@ -519,7 +522,7 @@
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 @@
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 @@
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 @@
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 @@
* 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 @@
}
}
+ private boolean doSplitContactAction() {
+ mState.splitRawContacts();
+ return doSaveAction(RESULT_CLOSE_VIEW_ACTIVITY);
+ }
+
+ private boolean doJoinContactAction() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+