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 195ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.content.Context; 205ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.text.TextUtils; 215ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikovimport android.util.AttributeSet; 225ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 23cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.RawContactDelta; 24738ff8623dc77dd91a1b9023861e924ba5e4c27eChiao Chengimport com.android.contacts.common.model.ValuesDelta; 25428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind; 26cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.dataitem.StructuredNameDataItem; 27cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.util.NameConverter; 28e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 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) { 64cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Lee StructuredNameDataItem dataItem = NameConverter.parsePhoneticName(value, null); 65851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mValues.setPhoneticFamilyName(dataItem.getPhoneticFamilyName()); 66851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mValues.setPhoneticMiddleName(dataItem.getPhoneticMiddleName()); 67851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu mValues.setPhoneticGivenName(dataItem.getPhoneticGivenName()); 685ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 695ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 705ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov private void buildPhoneticName() { 71851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String family = mValues.getPhoneticFamilyName(); 72851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String middle = mValues.getPhoneticMiddleName(); 73851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String given = mValues.getPhoneticGivenName(); 74cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Lee mPhoneticName = NameConverter.buildPhoneticName(family, middle, given); 755ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 765ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 775ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov @Override 785ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public Long getId() { 795ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov return mValues.getId(); 805ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 815ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 825ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov @Override 835ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public boolean isVisible() { 845ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov return mValues.isVisible(); 855ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 865ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 875ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 881a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan public static boolean isUnstructuredPhoneticNameColumn(String column) { 891a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan return DataKind.PSEUDO_COLUMN_PHONETIC_NAME.equals(column); 901a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan } 911a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan 925ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public PhoneticNameEditorView(Context context) { 935ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov super(context); 945ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 955ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 965ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public PhoneticNameEditorView(Context context, AttributeSet attrs) { 975ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov super(context, attrs); 985ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 995ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 1005ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public PhoneticNameEditorView(Context context, AttributeSet attrs, int defStyle) { 1015ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov super(context, attrs, defStyle); 1025ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 1035ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 1045ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov @Override 105851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void setValues(DataKind kind, ValuesDelta entry, RawContactDelta state, boolean readOnly, 1065ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov ViewIdGenerator vig) { 1075ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov if (!(entry instanceof PhoneticValuesDelta)) { 1085ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov entry = new PhoneticValuesDelta(entry); 1095ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 1105ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov super.setValues(kind, entry, state, readOnly, vig); 1118f9d84fffbc32b50cf3133b2340b18d0510a6c6eBrian Attwell updateEmptiness(); 1125ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 1135ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 1141a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan @Override 1151a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan public void onFieldChanged(String column, String value) { 1161a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan if (!isFieldChanged(column, value)) { 1171a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan return; 1181a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan } 1191a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan 1201a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan if (hasShortAndLongForms()) { 1211a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan PhoneticValuesDelta entry = (PhoneticValuesDelta) getEntry(); 1221a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan 1231a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // Determine whether the user is modifying the structured or unstructured phonetic 1241a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // name field. See a similar approach in {@link StructuredNameEditor#onFieldChanged}. 1251a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // This is because on device rotation, a hidden TextView's onRestoreInstanceState() will 1261a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // be called and incorrectly restore a null value for the hidden field, which ultimately 1271a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // modifies the underlying phonetic name. Hence, ignore onFieldChanged() update requests 1281a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // from fields that aren't visible. 1291a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan boolean isEditingUnstructuredPhoneticName = !areOptionalFieldsVisible(); 1301a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan 1311a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan if (isEditingUnstructuredPhoneticName == isUnstructuredPhoneticNameColumn(column)) { 1321a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // Call into the superclass to update the field and rebuild the underlying 1331a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan // phonetic name. 1341a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan super.onFieldChanged(column, value); 1351a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan } 136223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan } else { 137223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan // All fields are always visible, so we don't have to worry about blocking updates 138223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan // from onRestoreInstanceState() from hidden fields. Always call into the superclass 139223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan // to update the field and rebuild the underlying phonetic name. 140223dea3e59ebd7ec41db5583a9c911d2298e8dc4Katherine Kuan super.onFieldChanged(column, value); 1411a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan } 1421a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan } 1431a7f42494dbde3c268bc0763ebd62d55d43027aeKatherine Kuan 1445ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov public boolean hasData() { 1455ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov ValuesDelta entry = getEntry(); 1465ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 147851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String family = entry.getPhoneticFamilyName(); 148851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String middle = entry.getPhoneticMiddleName(); 149851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu String given = entry.getPhoneticGivenName(); 1505ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov 1515ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov return !TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle) 1525ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov || !TextUtils.isEmpty(given); 1535ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov } 154bf63a6d6a888b3e1b5fb91accf2dadaab4384539Walter Jang 155bf63a6d6a888b3e1b5fb91accf2dadaab4384539Walter Jang public String getPhoneticName() { 156bf63a6d6a888b3e1b5fb91accf2dadaab4384539Walter Jang return getEntry().getAsString(DataKind.PSEUDO_COLUMN_PHONETIC_NAME); 157bf63a6d6a888b3e1b5fb91accf2dadaab4384539Walter Jang } 1585ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov} 159