OSDN Git Service

Disable delete for read only contacts such as facebook contacts.
authorMegha Joshi <mjoshi@google.com>
Tue, 22 Sep 2009 16:38:41 +0000 (09:38 -0700)
committerMegha Joshi <mjoshi@google.com>
Thu, 1 Oct 2009 03:34:36 +0000 (20:34 -0700)
Fixes bug 2121909.

res/values/ids.xml
res/values/strings.xml
src/com/android/contacts/ContactsListActivity.java
src/com/android/contacts/ViewContactActivity.java

index cf1d419..92b0eac 100644 (file)
     <item type="id" name="dialog_io_exception" />
     <item type="id" name="dialog_error_with_message" />
 
+    <!-- For ContactsListActivity -->
+    <item type="id" name="dialog_delete_contact_confirmation" />
+    <item type="id" name="dialog_cannot_delete_readonly_contact" />
+    <item type="id" name="dialog_multiple_contact_delete_confirmation" />
+    <item type="id" name="dialog_readonly_contact_delete_confirmation" />
+
     <!-- For ExportVCard -->
     <item type="id" name="dialog_export_confirmation" />
     <item type="id" name="dialog_fail_to_export_with_reason" />
index 4df8b7c..5bdc152 100644 (file)
     <!-- Confirmation dialog title after users selects to delete a contact. -->
     <string name="deleteConfirmation_title">Delete</string>
 
-    <!-- Confirmation dialog contents after users selects to delete a contact. -->
+    <!-- Warning dialog contents after users selects to delete a ReadOnly contact. -->
+    <string name="readOnlyContactWarning">You cannot delete contacts from read-only accounts.</string>
+
+    <!-- Warning dialog contents after users selects to delete a contact with ReadOnly and Writable sources. -->
+    <string name="readOnlyContactDeleteConfirmation">This contact contains information from multiple accounts. The information from read-only accounts will not be deleted.</string>
+
+    <!-- Warning dialog contents after users selects to delete a contact with multiple Writable sources. -->
+    <string name="multipleContactDeleteConfirmation">Deleting this contact will delete information from multiple accounts.</string>
+
+    <!-- Confirmation dialog contents after users selects to delete a Writable contact. -->
     <string name="deleteConfirmation">This contact will be deleted.</string>
 
     <!-- Menu item to indicate you are done editing a contact and want to save the changes you've made -->
index c7d06e2..9fcc8a6 100644 (file)
@@ -102,8 +102,11 @@ import android.widget.SectionIndexer;
 import android.widget.TextView;
 import android.widget.AbsListView.OnScrollListener;
 
+import com.android.contacts.model.ContactsSource;
+
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -306,6 +309,12 @@ public class ContactsListActivity extends ListActivity implements
         ContactMethods.DATA, //3
         People.DISPLAY_NAME, // 4
     };
+    static final String[] RAW_CONTACTS_PROJECTION = new String[] {
+        RawContacts._ID, //0
+        RawContacts.CONTACT_ID, //1
+        RawContacts.ACCOUNT_TYPE, //2
+    };
+
     static final int POSTAL_ID_COLUMN_INDEX = 0;
     static final int POSTAL_TYPE_COLUMN_INDEX = 1;
     static final int POSTAL_LABEL_COLUMN_INDEX = 2;
@@ -324,6 +333,7 @@ public class ContactsListActivity extends ListActivity implements
     private String mQuery;
     private boolean mJustCreated;
     private boolean mSyncEnabled;
+    private Uri mSelectedContactUri;
 
 //    private boolean mDisplayAll;
     private boolean mDisplayOnlyPhones;
@@ -332,6 +342,10 @@ public class ContactsListActivity extends ListActivity implements
 
     private long mQueryAggregateId;
 
+    private ArrayList<Long> mWritableRawContactIds = new ArrayList<Long>();
+    private int  mWritableSourcesCnt;
+    private int  mReadOnlySourcesCnt;
+
     /**
      * Used to keep track of the scroll state of the list.
      */
@@ -388,7 +402,15 @@ public class ContactsListActivity extends ListActivity implements
         }
 
         public void onClick(DialogInterface dialog, int which) {
-            getContentResolver().delete(mUri, null, null);
+           if (mReadOnlySourcesCnt > 0) {
+               for (long rawContactIdToDelete: mWritableRawContactIds) {
+                   final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+                            rawContactIdToDelete);
+                    getContentResolver().delete(rawContactUri, null, null);
+               }
+            } else {
+               getContentResolver().delete(mUri, null, null);
+            }
         }
     }
 
@@ -854,11 +876,44 @@ public class ContactsListActivity extends ListActivity implements
             }
             case R.id.dialog_sdcard_not_found: {
                 AlertDialog.Builder builder = new AlertDialog.Builder(this)
-                .setTitle(R.string.no_sdcard_title)
-                .setIcon(android.R.drawable.ic_dialog_alert)
-                .setMessage(R.string.no_sdcard_message)
-                .setPositiveButton(android.R.string.ok, null);
+                        .setTitle(R.string.no_sdcard_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.no_sdcard_message)
+                        .setPositiveButton(android.R.string.ok, null);
+               break;
+            }
+           case R.id.dialog_delete_contact_confirmation: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.deleteConfirmation)
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, new DeleteClickListener(mSelectedContactUri));
+                break;
+            }
+            case R.id.dialog_cannot_delete_readonly_contact: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.readOnlyContactWarning)
+                        .setPositiveButton(android.R.string.ok, null);
+               break;
             }
+            case R.id.dialog_readonly_contact_delete_confirmation: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.readOnlyContactDeleteConfirmation)
+                        .setPositiveButton(android.R.string.ok, new DeleteClickListener(mSelectedContactUri));
+                }
+           case R.id.dialog_multiple_contact_delete_confirmation: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.multipleContactDeleteConfirmation)
+                        .setPositiveButton(android.R.string.ok, new DeleteClickListener(mSelectedContactUri));
+                }
+
         }
         return super.onCreateDialog(id);
     }
@@ -1061,8 +1116,8 @@ public class ContactsListActivity extends ListActivity implements
             }
 
             case MENU_ITEM_DELETE: {
-                final Uri selectedUri = getContactUri(info.position);
-                doContactDelete(selectedUri);
+                mSelectedContactUri = getContactUri(info.position);
+                doContactDelete();
                 return true;
             }
         }
@@ -1082,8 +1137,8 @@ public class ContactsListActivity extends ListActivity implements
             case KeyEvent.KEYCODE_DEL: {
                 final int position = getListView().getSelectedItemPosition();
                 if (position != ListView.INVALID_POSITION) {
-                    final Uri selectedUri = getContactUri(position);
-                    doContactDelete(selectedUri);
+                    mSelectedContactUri = getContactUri(position);
+                    doContactDelete();
                     return true;
                 }
                 break;
@@ -1096,14 +1151,41 @@ public class ContactsListActivity extends ListActivity implements
     /**
      * Prompt the user before deleting the given {@link Contacts} entry.
      */
-    protected void doContactDelete(Uri contactUri) {
-        new AlertDialog.Builder(ContactsListActivity.this)
-            .setTitle(R.string.deleteConfirmation_title)
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(R.string.deleteConfirmation)
-            .setNegativeButton(android.R.string.cancel, null)
-            .setPositiveButton(android.R.string.ok, new DeleteClickListener(contactUri))
-            .show();
+    protected void doContactDelete() {
+        mReadOnlySourcesCnt = 0;
+       mWritableSourcesCnt = 0;
+        mWritableRawContactIds.clear();
+
+       if (mSelectedContactUri != null) {
+            Cursor c = getContentResolver().query(RawContacts.CONTENT_URI,
+                   RAW_CONTACTS_PROJECTION, RawContacts.CONTACT_ID + "="
+                   + ContentUris.parseId(mSelectedContactUri), null, null);
+            Sources sources = Sources.getInstance(ContactsListActivity.this);
+            if (c != null) {
+                while (c.moveToNext()) {
+                    final String accountType = c.getString(2);
+                   final long rawContactId = c.getLong(0);
+                    ContactsSource contactsSource = sources.getInflatedSource(accountType,
+                            ContactsSource.LEVEL_SUMMARY);
+                    if (contactsSource != null && contactsSource.readOnly) {
+                        mReadOnlySourcesCnt += 1;
+                    } else {
+                        mWritableSourcesCnt += 1;
+                       mWritableRawContactIds.add(rawContactId);
+                   }
+                 }
+            }
+            c.close();
+           if (mReadOnlySourcesCnt > 0 && mWritableSourcesCnt > 0) {
+               showDialog(R.id.dialog_readonly_contact_delete_confirmation);
+           } else if (mReadOnlySourcesCnt > 0 && mWritableSourcesCnt == 0) {
+               showDialog(R.id.dialog_cannot_delete_readonly_contact);
+           } else if (mReadOnlySourcesCnt == 0 && mWritableSourcesCnt > 1) {
+               showDialog(R.id.dialog_multiple_contact_delete_confirmation);
+            } else {
+               showDialog(R.id.dialog_delete_contact_confirmation);
+           }
+       }
     }
 
     @Override
index bec871f..0e03cf3 100644 (file)
@@ -99,6 +99,8 @@ public class ViewContactActivity extends Activity
     private static final boolean SHOW_SEPARATORS = false;
 
     private static final int DIALOG_CONFIRM_DELETE = 1;
+    private static final int DIALOG_CONFIRM_READONLY_DELETE = 2;
+    private static final int DIALOG_CONFIRM_MULTIPLE_DELETE = 3;
 
     private static final int REQUEST_JOIN_CONTACT = 1;
     private static final int REQUEST_EDIT_CONTACT = 2;
@@ -154,6 +156,9 @@ public class ViewContactActivity extends Activity
     private static final String SAVED_STATE_TABS_VISIBLE_KEY = "tabsVisibleKey";
 
     protected Long mSelectedRawContactId = null;
+    protected int mReadOnlySourcesCnt;
+    protected int mWritableSourcesCnt;
+    protected ArrayList<Long> mWritableRawContactIds = new ArrayList<Long>();
 
     private static final int TOKEN_QUERY = 0;
 
@@ -173,7 +178,15 @@ public class ViewContactActivity extends Activity
 
     public void onClick(DialogInterface dialog, int which) {
         closeCursor();
-        getContentResolver().delete(mLookupUri, null, null);
+       if (mReadOnlySourcesCnt > 0) {
+           for (long rawContactIdToDelete: mWritableRawContactIds) {
+               final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+                        rawContactIdToDelete);
+                getContentResolver().delete(rawContactUri, null, null);
+            }
+        } else {
+           getContentResolver().delete(mLookupUri, null, null);
+       }
         finish();
     }
 
@@ -297,6 +310,24 @@ public class ViewContactActivity extends Activity
                         .setPositiveButton(android.R.string.ok, this)
                         .setCancelable(false)
                         .create();
+            case DIALOG_CONFIRM_READONLY_DELETE:
+                return new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.readOnlyContactDeleteConfirmation)
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, this)
+                        .setCancelable(false)
+                        .create();
+            case DIALOG_CONFIRM_MULTIPLE_DELETE:
+                return new AlertDialog.Builder(this)
+                        .setTitle(R.string.deleteConfirmation_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.multipleContactDeleteConfirmation)
+                        .setNegativeButton(android.R.string.cancel, null)
+                        .setPositiveButton(android.R.string.ok, this)
+                        .setCancelable(false)
+                        .create();
         }
         return null;
     }
@@ -597,6 +628,10 @@ public class ViewContactActivity extends Activity
         final boolean hasRawContact = (mRawContactIds.size() > 0);
         menu.findItem(R.id.menu_edit).setEnabled(hasRawContact);
 
+        // Disable delete for readonly contact
+       if (mWritableSourcesCnt == 0) {
+            menu.findItem(R.id.menu_delete).setEnabled(false);
+        }
         return true;
     }
 
@@ -667,7 +702,13 @@ public class ViewContactActivity extends Activity
             }
             case R.id.menu_delete: {
                 // Get confirmation
-                showDialog(DIALOG_CONFIRM_DELETE);
+               if (mReadOnlySourcesCnt > 0 & mWritableSourcesCnt > 0) {
+                    showDialog(DIALOG_CONFIRM_READONLY_DELETE);
+               } else if (mWritableSourcesCnt > 1) {
+                   showDialog(DIALOG_CONFIRM_MULTIPLE_DELETE);
+               } else {
+                   showDialog(DIALOG_CONFIRM_DELETE);
+               }
                 return true;
             }
             case R.id.menu_join: {
@@ -857,7 +898,13 @@ public class ViewContactActivity extends Activity
             }
 
             case KeyEvent.KEYCODE_DEL: {
-                showDialog(DIALOG_CONFIRM_DELETE);
+               if (mReadOnlySourcesCnt > 0 & mWritableSourcesCnt > 0) {
+                    showDialog(DIALOG_CONFIRM_READONLY_DELETE);
+               } else if (mWritableSourcesCnt > 1) {
+                   showDialog(DIALOG_CONFIRM_MULTIPLE_DELETE);
+               } else {
+                   showDialog(DIALOG_CONFIRM_DELETE);
+               }
                 return true;
             }
         }
@@ -915,6 +962,9 @@ public class ViewContactActivity extends Activity
         }
 
         mRawContactIds.clear();
+        mReadOnlySourcesCnt = 0;
+       mWritableSourcesCnt = 0;
+        mWritableRawContactIds.clear();
 
         Sources sources = Sources.getInstance(this);
 
@@ -936,6 +986,12 @@ public class ViewContactActivity extends Activity
 
                 final ContactsSource source = sources.getInflatedSource(accountType,
                         ContactsSource.LEVEL_SUMMARY);
+               if (source.readOnly) {
+                   mReadOnlySourcesCnt += 1;
+               } else {
+                   mWritableSourcesCnt += 1;
+                    mWritableRawContactIds.add(rawContactId);
+               }
                 final String accountName = entValues.getAsString(RawContacts.ACCOUNT_NAME);
                 mAccountName.setText(getString(R.string.account_name_format,
                         source.getDisplayLabel(this), accountName));