Long press to bring up default and copy options for contact detail.
-Displays option in ContextMenu to either set or clear default contact
method depending on if isPrimary is set or not
-Refactored copy text to clip to use new ClipData apis
-Displays checkbox next to item chosen as default
Bug: 4975755
Change-Id: Ibb18a9588a206d1c5f0801b970dee235b8a7e83d
diff --git a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
index 2de488d..22f0412 100644
--- a/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
+++ b/res/layout-sw580dp-w1000dp/contact_detail_list_item.xml
@@ -47,9 +47,24 @@
android:layout_height="wrap_content"
android:visibility="gone" />
- <TextView
- android:id="@+id/type"
- style="@style/ContactDetailItemType" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/type"
+ style="@style/ContactDetailItemType" />
+
+ <View
+ android:id="@+id/primary_indicator"
+ android:layout_width="16dip"
+ android:layout_height="16dip"
+ android:visibility="gone"
+ android:layout_gravity="center_vertical"
+ android:background="@drawable/ic_menu_mark" />
+
+ </LinearLayout>
</FrameLayout>
diff --git a/res/layout/contact_detail_list_item.xml b/res/layout/contact_detail_list_item.xml
index 2ea8425..e8c51ec 100644
--- a/res/layout/contact_detail_list_item.xml
+++ b/res/layout/contact_detail_list_item.xml
@@ -44,9 +44,24 @@
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
- <TextView
- android:id="@+id/type"
- style="@style/ContactDetailItemType" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/type"
+ style="@style/ContactDetailItemType" />
+
+ <View
+ android:id="@+id/primary_indicator"
+ android:layout_width="16dip"
+ android:layout_height="16dip"
+ android:visibility="gone"
+ android:layout_gravity="center_vertical"
+ android:background="@drawable/ic_menu_mark" />
+
+ </LinearLayout>
<TextView
android:id="@+id/footer"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9962f0f..d4d290f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1569,6 +1569,15 @@
<!-- Joined contact indicator displayed in the contact detail [CHAR LIMIT=64] -->
<string name="indicator_joined_contact">Joined contact</string>
+ <!-- Option displayed in context menu to copy long pressed item to clipboard [CHAR LIMIT=64] -->
+ <string name="copy_text">Copy to clipboard</string>
+
+ <!-- Option displayed in context menu to set long pressed item as default contact method [CHAR LIMIT=64] -->
+ <string name="set_default">Set default</string>
+
+ <!-- Option displayed in context menu to clear long pressed item as default contact method [CHAR LIMIT=64] -->
+ <string name="clear_default">Clear default</string>
+
<!-- Toast shown when text is copied to the clipboard [CHAR LIMIT=64] -->
<string name="toast_text_copied">Text copied</string>
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 17df4b4..c435a65 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -47,6 +47,7 @@
import android.app.Activity;
import android.app.Fragment;
import android.app.SearchManager;
+import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -87,15 +88,18 @@
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
@@ -111,12 +115,18 @@
import java.util.Map;
public class ContactDetailFragment extends Fragment implements FragmentKeyListener, FragmentOverlay,
- OnItemClickListener, OnItemLongClickListener, SelectAccountDialogFragment.Listener {
+ OnItemClickListener, SelectAccountDialogFragment.Listener {
private static final String TAG = "ContactDetailFragment";
private static final int LOADER_DETAILS = 1;
+ private interface ContextMenuIds {
+ static final int COPY_TEXT = 0;
+ static final int CLEAR_DEFAULT = 1;
+ static final int SET_DEFAULT = 2;
+ }
+
private static final String KEY_CONTACT_URI = "contactUri";
private static final String LOADER_ARG_CONTACT_URI = "contactUri";
@@ -253,7 +263,7 @@
mListView = (ListView) mView.findViewById(android.R.id.list);
mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
mListView.setOnItemClickListener(this);
- mListView.setOnItemLongClickListener(this);
+ registerForContextMenu(mListView);
mListView.setOnScrollListener(mVerticalScrollListener);
// Don't set it to mListView yet. We do so later when we bind the adapter.
@@ -1215,12 +1225,14 @@
public ImageView secondaryActionButton;
public View secondaryActionButtonContainer;
public View secondaryActionDivider;
+ public View primaryIndicator;
public DetailViewCache(View view, OnClickListener secondaryActionClickListener) {
kind = (TextView) view.findViewById(R.id.kind);
type = (TextView) view.findViewById(R.id.type);
data = (TextView) view.findViewById(R.id.data);
footer = (TextView) view.findViewById(R.id.footer);
+ primaryIndicator = view.findViewById(R.id.primary_indicator);
presenceIcon = (ImageView) view.findViewById(R.id.presence_icon);
secondaryActionButton = (ImageView) view.findViewById(
R.id.secondary_action_button);
@@ -1398,6 +1410,9 @@
views.footer.setVisibility(View.GONE);
}
+ // Set the default contact method
+ views.primaryIndicator.setVisibility(entry.isPrimary ? View.VISIBLE : View.GONE);
+
// Set the presence icon
final Drawable presenceIcon = ContactPresenceIconUtil.getPresenceIcon(
mContext, entry.presence);
@@ -1531,18 +1546,105 @@
}
@Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- if (mListener == null) return false;
- final DetailViewCache cache = (DetailViewCache) view.getTag();
- if (cache == null) return false;
- CharSequence text = cache.data.getText();
- if (TextUtils.isEmpty(text)) return false;
+ public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, view, menuInfo);
- ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(
+ AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
+ DetailViewEntry selectedEntry = (DetailViewEntry) mAllEntries.get(info.position);
+
+ menu.setHeaderTitle(selectedEntry.data);
+ menu.add(ContextMenu.NONE, ContextMenuIds.COPY_TEXT,
+ ContextMenu.NONE, getString(R.string.copy_text));
+
+ String selectedMimeType = selectedEntry.mimetype;
+
+ // Only allow primary support for Phone and Email content types
+ if (Phone.CONTENT_ITEM_TYPE.equals(selectedMimeType) ||
+ Email.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
+
+ // Used to determine if entry is the only mime type of its kind
+ boolean isUniqueMimeType = true;
+
+ // Checking for unique mime type
+ for (int positionCounter = 0; positionCounter < mAllEntries.size(); positionCounter++) {
+ final ViewEntry entry = mAllEntries.get(positionCounter);
+
+ // Ignoring cases where entry is not a detail entry
+ if (entry.getViewType() != ViewAdapter.VIEW_TYPE_DETAIL_ENTRY) continue;
+
+ final DetailViewEntry checkEntry = (DetailViewEntry) entry;
+ if (positionCounter != info.position &&
+ checkEntry.mimetype.equalsIgnoreCase(selectedMimeType)) {
+ isUniqueMimeType = false;
+ break;
+ }
+ }
+
+ // Checking for previously set default
+ if (selectedEntry.isPrimary) {
+ menu.add(ContextMenu.NONE, ContextMenuIds.CLEAR_DEFAULT,
+ ContextMenu.NONE, getString(R.string.clear_default));
+ } else if (!isUniqueMimeType) {
+ menu.add(ContextMenu.NONE, ContextMenuIds.SET_DEFAULT,
+ ContextMenu.NONE, getString(R.string.set_default));
+ }
+ }
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ AdapterView.AdapterContextMenuInfo menuInfo;
+ try {
+ menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+ } catch (ClassCastException e) {
+ Log.e(TAG, "bad menuInfo", e);
+ return false;
+ }
+
+ switch (item.getItemId()) {
+ case ContextMenuIds.COPY_TEXT:
+ copyToClipboard(menuInfo.position);
+ return true;
+ case ContextMenuIds.SET_DEFAULT:
+ setDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
+ return true;
+ case ContextMenuIds.CLEAR_DEFAULT:
+ clearDefaultContactMethod(mListView.getItemIdAtPosition(menuInfo.position));
+ return true;
+ default:
+ throw new IllegalArgumentException("Unknown menu option " + item.getItemId());
+ }
+ }
+
+ private void setDefaultContactMethod(long id) {
+ Intent setIntent = ContactSaveService.createSetSuperPrimaryIntent(mContext, id);
+ mContext.startService(setIntent);
+ }
+
+ private void clearDefaultContactMethod(long id) {
+ Intent clearIntent = ContactSaveService.createClearPrimaryIntent(mContext, id);
+ mContext.startService(clearIntent);
+ }
+
+ private void copyToClipboard(int viewEntryPosition) {
+ // Getting the text to copied
+ DetailViewEntry detailViewEntry = (DetailViewEntry) mAllEntries.get(viewEntryPosition);
+ CharSequence textToCopy = detailViewEntry.data;
+
+ // Checking for empty string
+ if (TextUtils.isEmpty(textToCopy)) return;
+
+ // Adding item to clipboard
+ ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(
Context.CLIPBOARD_SERVICE);
- cm.setText(text);
- Toast.makeText(getActivity(), R.string.toast_text_copied, Toast.LENGTH_SHORT).show();
- return true;
+ String[] mimeTypes = new String[]{detailViewEntry.mimetype};
+ ClipData.Item clipDataItem = new ClipData.Item(textToCopy);
+ ClipData cd = new ClipData(detailViewEntry.typeString, mimeTypes, clipDataItem);
+ clipboardManager.setPrimaryClip(cd);
+
+ // Display Confirmation Toast
+ String toastText = getString(R.string.toast_text_copied);
+ Toast.makeText(getActivity(), toastText, Toast.LENGTH_SHORT).show();
}
@Override