15ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov/*
25ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
35ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov *
45ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
55ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * you may not use this file except in compliance with the License.
65ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * You may obtain a copy of the License at
75ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov *
85ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
95ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov *
105ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
115ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
125ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * See the License for the specific language governing permissions and
145ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * limitations under the License.
155ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov */
165ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
175ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovpackage com.android.contacts.editor;
185ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
19405671a7b42d97ebf7ae7c0eeb4721f881139673Daisuke Miyakawaimport com.android.contacts.model.DataKind;
205ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport com.android.contacts.model.EntityDelta;
215ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport com.android.contacts.model.EntityDelta.ValuesDelta;
225ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
23d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawaimport android.content.ContentValues;
245ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.content.Context;
255ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
265ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.text.TextUtils;
275ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.util.AttributeSet;
285ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
295ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov/**
305ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov * A dedicated editor for phonetic name. It is similar to {@link StructuredNameEditorView}.
315ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov */
325ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovpublic class PhoneticNameEditorView extends TextFieldsEditorView {
335ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
345ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    private static class PhoneticValuesDelta extends ValuesDelta {
355ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        private ValuesDelta mValues;
365ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        private String mPhoneticName;
375ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
385ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        public PhoneticValuesDelta(ValuesDelta values) {
395ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            mValues = values;
405ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            buildPhoneticName();
415ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
425ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
435ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        @Override
445ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        public void put(String key, String value) {
455ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            if (key.equals(DataKind.PSEUDO_COLUMN_PHONETIC_NAME)) {
465ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                mPhoneticName = value;
475ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                parsePhoneticName(value);
485ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            } else {
495ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                mValues.put(key, value);
505ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                buildPhoneticName();
515ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            }
525ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
535ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
545ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        @Override
555ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        public String getAsString(String key) {
565ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            if (key.equals(DataKind.PSEUDO_COLUMN_PHONETIC_NAME)) {
575ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                return mPhoneticName;
585ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            } else {
595ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                return mValues.getAsString(key);
605ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            }
615ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
625ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
635ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        private void parsePhoneticName(String value) {
64d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            ContentValues values = PhoneticNameEditorView.parsePhoneticName(value, null);
65d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            mValues.put(StructuredName.PHONETIC_FAMILY_NAME,
66d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    values.getAsString(StructuredName.PHONETIC_FAMILY_NAME));
67d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            mValues.put(StructuredName.PHONETIC_MIDDLE_NAME,
68d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    values.getAsString(StructuredName.PHONETIC_MIDDLE_NAME));
69d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            mValues.put(StructuredName.PHONETIC_GIVEN_NAME,
70d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    values.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
715ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
725ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
735ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        private void buildPhoneticName() {
745ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            String family = mValues.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
755ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            String middle = mValues.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
765ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            String given = mValues.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
77d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            mPhoneticName = PhoneticNameEditorView.buildPhoneticName(family, middle, given);
785ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
795ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
805ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        @Override
815ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        public Long getId() {
825ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            return mValues.getId();
835ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
845ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
855ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        @Override
865ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        public boolean isVisible() {
875ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            return mValues.isVisible();
885ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
895ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
905ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
91d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    /**
92d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues.
93d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Parsed data should be {@link StructuredName#PHONETIC_FAMILY_NAME},
94d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * {@link StructuredName#PHONETIC_MIDDLE_NAME}, and
95d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * {@link StructuredName#PHONETIC_GIVEN_NAME}.
96d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * If this method cannot parse given phoneticName, null values will be stored.
97d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     *
98d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param phoneticName Phonetic name to be parsed
99d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @param values ContentValues to be used for storing data. If null, new instance will be
100d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * created.
101d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * @return ContentValues with parsed data. Those data can be null.
102d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     */
103d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public static ContentValues parsePhoneticName(String phoneticName, ContentValues values) {
104d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        String family = null;
105d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        String middle = null;
106d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        String given = null;
107d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
108d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        if (!TextUtils.isEmpty(phoneticName)) {
109d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            String[] strings = phoneticName.split(" ", 3);
110d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            switch (strings.length) {
111d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                case 1:
112d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    family = strings[0];
113d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    break;
114d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                case 2:
115d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    family = strings[0];
116d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    given = strings[1];
117d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    break;
118d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                case 3:
119d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    family = strings[0];
120d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    middle = strings[1];
121d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    given = strings[2];
122d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                    break;
123d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
124d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        }
125d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
126d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        if (values == null) {
127d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            values = new ContentValues();
128d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        }
129d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        values.put(StructuredName.PHONETIC_FAMILY_NAME, family);
130d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        values.put(StructuredName.PHONETIC_MIDDLE_NAME, middle);
131d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        values.put(StructuredName.PHONETIC_GIVEN_NAME, given);
132d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        return values;
133d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
134d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
135d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    /**
136d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     * Constructs and returns a phonetic full name from given parts.
137d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa     */
138d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    public static String buildPhoneticName(String family, String middle, String given) {
139d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle)
140d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                || !TextUtils.isEmpty(given)) {
141d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            StringBuilder sb = new StringBuilder();
142d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            if (!TextUtils.isEmpty(family)) {
143d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                sb.append(family.trim()).append(' ');
144d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
145d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            if (!TextUtils.isEmpty(middle)) {
146d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                sb.append(middle.trim()).append(' ');
147d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
148d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            if (!TextUtils.isEmpty(given)) {
149d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa                sb.append(given.trim()).append(' ');
150d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            }
151d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            sb.setLength(sb.length() - 1);  // Yank the last space
152d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            return sb.toString();
153d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        } else {
154d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa            return null;
155d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa        }
156d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa    }
157d37a891cb44cd17083c06d7be693c469403d16dfDaisuke Miyakawa
1581a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan    public static boolean isUnstructuredPhoneticNameColumn(String column) {
1591a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan        return DataKind.PSEUDO_COLUMN_PHONETIC_NAME.equals(column);
1601a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan    }
1611a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan
1625ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public PhoneticNameEditorView(Context context) {
1635ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        super(context);
1645ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
1655ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
1665ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public PhoneticNameEditorView(Context context, AttributeSet attrs) {
1675ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        super(context, attrs);
1685ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
1695ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
1705ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public PhoneticNameEditorView(Context context, AttributeSet attrs, int defStyle) {
1715ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        super(context, attrs, defStyle);
1725ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
1735ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
1745ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    @Override
1755ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
1765ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            ViewIdGenerator vig) {
1775ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        if (!(entry instanceof PhoneticValuesDelta)) {
1785ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            entry = new PhoneticValuesDelta(entry);
1795ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
1805ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        super.setValues(kind, entry, state, readOnly, vig);
1815ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
1825ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
1831a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan    @Override
1841a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan    public void onFieldChanged(String column, String value) {
1851a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan        if (!isFieldChanged(column, value)) {
1861a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            return;
1871a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan        }
1881a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan
1891a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan        if (hasShortAndLongForms()) {
1901a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            PhoneticValuesDelta entry = (PhoneticValuesDelta) getEntry();
1911a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan
1921a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // Determine whether the user is modifying the structured or unstructured phonetic
1931a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // name field. See a similar approach in {@link StructuredNameEditor#onFieldChanged}.
1941a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // This is because on device rotation, a hidden TextView's onRestoreInstanceState() will
1951a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // be called and incorrectly restore a null value for the hidden field, which ultimately
1961a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // modifies the underlying phonetic name. Hence, ignore onFieldChanged() update requests
1971a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            // from fields that aren't visible.
1981a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            boolean isEditingUnstructuredPhoneticName = !areOptionalFieldsVisible();
1991a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan
2001a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            if (isEditingUnstructuredPhoneticName == isUnstructuredPhoneticNameColumn(column)) {
2011a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan                // Call into the superclass to update the field and rebuild the underlying
2021a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan                // phonetic name.
2031a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan                super.onFieldChanged(column, value);
2041a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan            }
205223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan        } else {
206223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan            // All fields are always visible, so we don't have to worry about blocking updates
207223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan            // from onRestoreInstanceState() from hidden fields. Always call into the superclass
208223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan            // to update the field and rebuild the underlying phonetic name.
209223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan            super.onFieldChanged(column, value);
2101a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan        }
2111a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan    }
2121a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan
2135ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public boolean hasData() {
2145ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        ValuesDelta entry = getEntry();
2155ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
2165ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        String family = entry.getAsString(StructuredName.PHONETIC_FAMILY_NAME);
2175ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        String middle = entry.getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
2185ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        String given = entry.getAsString(StructuredName.PHONETIC_GIVEN_NAME);
2195ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
2205ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        return !TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle)
2215ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                || !TextUtils.isEmpty(given);
2225ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
2235ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov}
224