Merge "Import translations. DO NOT MERGE ANYWHERE" into main
diff --git a/res/layout/contact_editor_fields.xml b/res/layout/contact_editor_fields.xml
index b9bda16..dd4e499 100644
--- a/res/layout/contact_editor_fields.xml
+++ b/res/layout/contact_editor_fields.xml
@@ -48,4 +48,29 @@
</LinearLayout>
+ <LinearLayout
+ android:id="@+id/legacy_fields_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:orientation="vertical"
+ android:visibility="gone">
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAllCaps="true"
+ android:layout_marginStart="16dp"
+ android:textAppearance="?attr/textAppearanceOverline"
+ android:singleLine="true"
+ android:layout_marginBottom="24dp"
+ android:textSize="11sp"
+ android:text="@string/editor_uneditable_section_title" />
+
+ <LinearLayout
+ android:id="@+id/legacy_section_views"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ </LinearLayout>
+
</merge>
\ No newline at end of file
diff --git a/res/values/ids.xml b/res/values/ids.xml
index a4b8b4b..f22eaba 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -44,6 +44,9 @@
<!-- An ID to be used for contents of a custom dialog so that its state be preserved -->
<item type="id" name="custom_dialog_content" />
+ <!-- An ID to be used for tagging text for copy in legacy fields. -->
+ <item name="text_to_copy" type="id"/>
+
<!-- Menu group ID for settings and help & feedback -->
<item type="id" name="nav_misc" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b608e12..fc24b10 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -425,6 +425,9 @@
<!-- The button to add an label field to a contact in the Raw Contact Editor [CHAR LIMIT=15] -->
<string name="group_edit_field_hint_text">Label</string>
+ <!-- Editor section title to show below shown editor fields are not editable. Users are only allowed to delete them. [CHAR LIMIT=NONE] -->
+ <string name="editor_uneditable_section_title">Can’t update this info</string>
+
<!-- Content description for a cancel button. [CHAR LIMIT=NONE] -->
<string name="cancel_button_content_description">Cancel</string>
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index c02816a..6ab06bd 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -114,4 +114,10 @@
*/
public void editNewlyAddedField();
+ /**
+ * Marks the Editor field as a legacy field. Legacy fields are deprecated MIME types
+ * which are not fully supported in the editor.
+ * Adding or editing legacy field are not supported.
+ */
+ void setLegacyField(boolean isLegacyField);
}
diff --git a/src/com/android/contacts/editor/EditorUiUtils.java b/src/com/android/contacts/editor/EditorUiUtils.java
index 35f107e..3dac5bb 100644
--- a/src/com/android/contacts/editor/EditorUiUtils.java
+++ b/src/com/android/contacts/editor/EditorUiUtils.java
@@ -57,6 +57,7 @@
import com.android.contacts.util.MaterialColorMapUtils.MaterialPalette;
import com.android.contacts.widget.QuickContactImageView;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import java.io.FileNotFoundException;
@@ -95,6 +96,9 @@
mimetypeLayoutMap.put(Event.CONTENT_ITEM_TYPE, R.layout.event_field_editor_view);
}
+ public static final ImmutableList<String> LEGACY_MIME_TYPE =
+ ImmutableList.of(Im.CONTENT_ITEM_TYPE, SipAddress.CONTENT_ITEM_TYPE);
+
/**
* Fetches a layout for a given mimetype.
*
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index 5d49064..28eeaf2 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -48,6 +48,13 @@
*/
public class KindSectionView extends LinearLayout {
+ /** Callbacks for hosts of {@link KindSectionView}s. */
+ public interface Listener {
+
+ /** Invoked when all fields in a legacy {@link KindSectionView} are removed. */
+ void onEmptyLegacyKindSectionView();
+ }
+
/**
* Marks a name as super primary when it is changed.
*
@@ -58,21 +65,21 @@
private final ValuesDelta mValuesDelta;
private final long mRawContactId;
- private final RawContactEditorView.Listener mListener;
+ private final RawContactEditorView.Listener mEditorViewListener;
public StructuredNameEditorListener(ValuesDelta valuesDelta, long rawContactId,
- RawContactEditorView.Listener listener) {
+ RawContactEditorView.Listener editorViewListener) {
mValuesDelta = valuesDelta;
mRawContactId = rawContactId;
- mListener = listener;
+ mEditorViewListener = editorViewListener;
}
@Override
public void onRequest(int request) {
if (request == Editor.EditorListener.FIELD_CHANGED) {
mValuesDelta.setSuperPrimary(true);
- if (mListener != null) {
- mListener.onNameFieldChanged(mRawContactId, mValuesDelta);
+ if (mEditorViewListener != null) {
+ mEditorViewListener.onNameFieldChanged(mRawContactId, mValuesDelta);
}
} else if (request == Editor.EditorListener.FIELD_TURNED_EMPTY) {
mValuesDelta.setSuperPrimary(false);
@@ -119,6 +126,11 @@
@Override
public void onDeleteRequested(Editor editor) {
+ if (mIsLegacyField && mEditors.getChildCount() == 1) {
+ editor.deleteEditor();
+ mListener.onEmptyLegacyKindSectionView();
+ return;
+ }
if (mShowOneEmptyEditor && mEditors.getChildCount() == 1) {
// If there is only 1 editor in the section, then don't allow the user to
// delete it. Just clear the fields in the editor.
@@ -152,11 +164,13 @@
private KindSectionData mKindSectionData;
private ViewIdGenerator mViewIdGenerator;
- private RawContactEditorView.Listener mListener;
+ private RawContactEditorView.Listener mEditorViewListener;
+ private Listener mListener;
private boolean mIsUserProfile;
private boolean mShowOneEmptyEditor = false;
private boolean mHideIfEmpty = true;
+ private boolean mIsLegacyField = false;
private LayoutInflater mLayoutInflater;
private ViewGroup mEditors;
@@ -227,6 +241,13 @@
}
/**
+ * When {@code isLegacyField} is true, prevent users from editing the field.
+ */
+ void setLegacyField(boolean isLegacyField) {
+ this.mIsLegacyField = isLegacyField;
+ }
+
+ /**
* Whether this is a name kind section view and all name fields (structured, phonetic,
* and nicknames) are empty.
*/
@@ -277,10 +298,14 @@
* Empty name editors are never added and at least one structured name editor is always
* displayed, even if it is empty.
*/
- public void setState(KindSectionData kindSectionData,
- ViewIdGenerator viewIdGenerator, RawContactEditorView.Listener listener) {
+ public void setState(
+ KindSectionData kindSectionData,
+ ViewIdGenerator viewIdGenerator,
+ RawContactEditorView.Listener editorViewListener,
+ Listener listener) {
mKindSectionData = kindSectionData;
mViewIdGenerator = viewIdGenerator;
+ mEditorViewListener = editorViewListener;
mListener = listener;
// Set the icon using the DataKind
@@ -292,6 +317,9 @@
mIcon.setContentDescription(dataKind.titleRes == -1 || dataKind.titleRes == 0
? "" : getResources().getString(dataKind.titleRes));
}
+ if (mIsLegacyField) {
+ mIcon.setEnabled(false);
+ }
}
rebuildFromState();
@@ -359,7 +387,7 @@
if (!mIsUserProfile) {
// Don't set super primary for the me contact
nameView.setEditorListener(new StructuredNameEditorListener(
- nameValuesDelta, rawContactDelta.getRawContactId(), mListener));
+ nameValuesDelta, rawContactDelta.getRawContactId(), mEditorViewListener));
}
nameView.setDeletable(false);
nameView.setValues(accountType.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_NAME),
@@ -414,6 +442,7 @@
view.setEnabled(isEnabled());
if (view instanceof Editor) {
final Editor editor = (Editor) view;
+ editor.setLegacyField(mIsLegacyField);
editor.setDeletable(true);
editor.setEditorListener(editorListener);
editor.setValues(dataKind, valuesDelta, rawContactDelta, !dataKind.editable,
@@ -593,4 +622,8 @@
}
return emptyEditors;
}
+
+ public boolean isEditorEmpty() {
+ return mKindSectionData.getVisibleValuesDeltas().isEmpty();
+ }
}
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index df4c5f9..3df3222 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -81,6 +81,8 @@
private boolean mIsDeletable = true;
private boolean mIsAttachedToWindow;
+ protected boolean mIsLegacyField;
+
private EditType mType;
private ViewIdGenerator mViewIdGenerator;
@@ -264,8 +266,8 @@
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
- mLabel.setEnabled(!mReadOnly && enabled);
- mDelete.setEnabled(!mReadOnly && enabled);
+ mLabel.setEnabled(!mReadOnly && enabled && !mIsLegacyField);
+ mDelete.setEnabled((!mReadOnly && enabled) || mIsLegacyField);
}
public Spinner getLabel() {
@@ -342,6 +344,10 @@
return "";
}
+ public void setLegacyField(boolean mIsLegacyField) {
+ this.mIsLegacyField = mIsLegacyField;
+ }
+
protected void saveValue(String column, String value) {
mEntry.put(column, value);
}
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 19da5bc..755800a 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -50,6 +50,7 @@
import android.widget.ListPopupWindow;
import android.widget.TextView;
+import com.android.contacts.editor.KindSectionView;
import com.android.contacts.GeoUtil;
import com.android.contacts.R;
import com.android.contacts.compat.PhoneNumberUtilsCompat;
@@ -80,7 +81,8 @@
/**
* View to display information from multiple {@link RawContactDelta}s grouped together.
*/
-public class RawContactEditorView extends LinearLayout implements View.OnClickListener {
+public class RawContactEditorView extends LinearLayout implements View.OnClickListener,
+ KindSectionView.Listener {
static final String TAG = "RawContactEditorView";
@@ -218,6 +220,8 @@
private PhotoEditorView mPhotoView;
private ViewGroup mKindSectionViews;
+ private LinearLayout mLegacySectionLinearLayout;
+ private ViewGroup mLegacyKindSectionViews;
private Map<String, KindSectionView> mKindSectionViewMap = new HashMap<>();
private View mMoreFields;
@@ -259,6 +263,8 @@
mPhotoView = (PhotoEditorView) findViewById(R.id.photo_editor);
mKindSectionViews = (LinearLayout) findViewById(R.id.kind_section_views);
+ mLegacySectionLinearLayout = (LinearLayout) findViewById(R.id.legacy_fields_container);
+ mLegacyKindSectionViews = (LinearLayout) findViewById(R.id.legacy_section_views);
mMoreFields = findViewById(R.id.more_fields);
mMoreFields.setOnClickListener(this);
}
@@ -277,6 +283,10 @@
for (int i = 0; i < childCount; i++) {
mKindSectionViews.getChildAt(i).setEnabled(enabled);
}
+ final int legacyChildCount = mLegacyKindSectionViews.getChildCount();
+ for (int i = 0; i < legacyChildCount; i++) {
+ mLegacyKindSectionViews.getChildAt(i).setEnabled(false);
+ }
}
@Override
@@ -447,6 +457,8 @@
mKindSectionViewMap.clear();
mKindSectionViews.removeAllViews();
+ mLegacySectionLinearLayout.setVisibility(View.GONE);
+ mLegacyKindSectionViews.removeAllViews();
mMoreFields.setVisibility(View.VISIBLE);
mMaterialPalette = materialPalette;
@@ -531,7 +543,7 @@
addKindSectionViews();
mMoreFields.setVisibility(hasMoreFields() ? View.VISIBLE : View.GONE);
-
+ addLegacyKindSectionViews();
if (mIsExpanded) showAllFields();
}
@@ -874,6 +886,9 @@
int i = -1;
for (String mimeType : mSortedMimetypes) {
+ if(EditorUiUtils.LEGACY_MIME_TYPE.contains(mimeType)) {
+ continue;
+ }
i++;
// Ignore mime types that we've already handled
if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
@@ -910,7 +925,7 @@
// they will be the only types you add new values to initially for new contacts
kindSectionView.setShowOneEmptyEditor(true);
- kindSectionView.setState(kindSectionData, mViewIdGenerator, mListener);
+ kindSectionView.setState(kindSectionData, mViewIdGenerator, mListener, this);
return kindSectionView;
}
@@ -938,6 +953,55 @@
return false;
}
+ private void addLegacyKindSectionViews() {
+ boolean hasLegacyData = false;
+ for (String mimeType : EditorUiUtils.LEGACY_MIME_TYPE) {
+
+ KindSectionData kindSectionData = mKindSectionDataMap.get(mimeType);
+ if (kindSectionData != null && !kindSectionData.getVisibleValuesDeltas().isEmpty()) {
+ hasLegacyData = true;
+ KindSectionView kindSectionView =
+ inflateLegacyKindSectionView(mKindSectionViews, kindSectionData);
+ mLegacyKindSectionViews.addView(kindSectionView);
+
+ // Keep a pointer to the KindSectionView for each mimeType
+ mKindSectionViewMap.put(mimeType, kindSectionView);
+ }
+ }
+
+ if (hasLegacyData) {
+ mLegacySectionLinearLayout.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private KindSectionView inflateLegacyKindSectionView(
+ ViewGroup viewGroup, KindSectionData kindSectionData) {
+ KindSectionView kindSectionView =
+ (KindSectionView)
+ mLayoutInflater.inflate(
+ R.layout.item_kind_section, viewGroup, /* attachToRoot =*/ false);
+ kindSectionView.setLegacyField(true);
+
+ kindSectionView.setState(kindSectionData, mViewIdGenerator, mListener, this);
+
+ return kindSectionView;
+ }
+
+ @Override
+ public void onEmptyLegacyKindSectionView() {
+ for (int i = mLegacyKindSectionViews.getChildCount() - 1; i >= 0; i--) {
+ View childView = mLegacyKindSectionViews.getChildAt(i);
+ if (childView instanceof KindSectionView
+ && ((KindSectionView) childView).isEditorEmpty()) {
+ mLegacyKindSectionViews.removeViewAt(i);
+ }
+ }
+
+ if (mLegacyKindSectionViews.getChildCount() == 0) {
+ mLegacySectionLinearLayout.setVisibility(View.GONE);
+ }
+ }
+
private static void wlog(String message) {
if (Log.isLoggable(TAG, Log.WARN)) {
Log.w(TAG, message);
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 28fe87f..d7f9545 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -22,6 +22,8 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.text.Editable;
import android.text.InputType;
@@ -49,6 +51,7 @@
import com.android.contacts.model.account.AccountType.EditField;
import com.android.contacts.model.dataitem.DataKind;
import com.android.contacts.util.PhoneNumberFormatter;
+import com.android.contacts.ClipboardUtils;
/**
* Simple editor that handles labels and any {@link EditField} defined for the
@@ -57,7 +60,6 @@
*/
public class TextFieldsEditorView extends LabeledEditorView {
private static final String TAG = TextFieldsEditorView.class.getSimpleName();
-
private EditText[] mFieldEditTexts = null;
private ViewGroup mFields = null;
protected View mExpansionViewContainer;
@@ -75,6 +77,12 @@
private String mFixedDisplayName = "";
private boolean needInputInitialize;
+ private final OnLongClickListener mOnLongClickListener =
+ v -> {
+ ClipboardUtils.copyText(
+ getContext(), /* label= */ null, (CharSequence) v.getTag(R.id.text_to_copy), true);
+ return true;
+ };
public TextFieldsEditorView(Context context) {
super(context);
@@ -164,7 +172,15 @@
if (mFieldEditTexts != null) {
for (int index = 0; index < mFieldEditTexts.length; index++) {
- mFieldEditTexts[index].setEnabled(!isReadOnly() && enabled);
+ mFieldEditTexts[index].setEnabled(!isReadOnly() && enabled && !mIsLegacyField);
+ if (mIsLegacyField) {
+ mFieldEditTexts[index].setFocusable(false);
+ mFieldEditTexts[index].setClickable(false);
+ mFieldEditTexts[index].setLongClickable(false);
+ }
+ }
+ if (mIsLegacyField && mFieldEditTexts.length > 0) {
+ setOnLongClickListenerOnContainer();
}
}
if (mExpansionView != null) {
@@ -172,6 +188,18 @@
}
}
+ /**
+ * Attaches OnLongClickLister to fields LinearLayout that allow user copy the EditText text on
+ * long press.
+ */
+ private void setOnLongClickListenerOnContainer() {
+ mFields.setFocusable(true);
+ mFields.setLongClickable(true);
+ // Current legacy mimetypes support exactly 1 field
+ mFields.setTag(R.id.text_to_copy, mFieldEditTexts[0].getText().toString());
+ mFields.setOnLongClickListener(mOnLongClickListener);
+ }
+
private OnFocusChangeListener mTextFocusChangeListener = new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {