* and applying another {@link EntitySet} over it.
*/
public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
+ private boolean mSplitRawContacts;
+
private EntitySet() {
}
}
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();
}
}
+ if (mSplitRawContacts) {
+ buildSplitContactDiff(diff, backRefs);
+ }
+
// No real changes if only left with asserts
if (diff.size() == assertMark) {
diff.clear();
}
/**
+ * 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.
return randomEntry;
}
+ public void splitRawContacts() {
+ mSplitRawContacts = true;
+ }
+
/** {@inheritDoc} */
public int describeContents() {
// Nothing special about this parcel
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;
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
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_done:
- doSaveAction();
+ doSaveAction(RESULT_OK);
break;
case R.id.btn_discard:
doRevertAction();
/** {@inheritDoc} */
@Override
public void onBackPressed() {
- doSaveAction();
+ doSaveAction(RESULT_OK);
}
/** {@inheritDoc} */
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:
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;
}
private WeakReference<ProgressDialog> progress;
- public PersistTask(EditContactActivity target) {
+ private final int mResultCode;
+
+ public PersistTask(EditContactActivity target, int resultCode) {
super(target);
+ mResultCode = resultCode;
}
/** {@inheritDoc} */
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;
* 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;
}
}
+ private boolean doSplitContactAction() {
+ mState.splitRawContacts();
+ return doSaveAction(RESULT_CLOSE_VIEW_ACTIVITY);
+ }
+
+ private boolean doJoinContactAction() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+