12ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey/*
22ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * Copyright (C) 2009 The Android Open Source Project
32ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey *
42ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
52ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * you may not use this file except in compliance with the License.
62ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * You may obtain a copy of the License at
72ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey *
82ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
92ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey *
102ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
112ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
122ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * See the License for the specific language governing permissions and
142ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * limitations under the License.
152ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey */
162ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor;
182ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
192ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.content.Context;
20e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikovimport android.database.Cursor;
21827b5d6611018497eb28a0776cb51226fb81ae23Yorke Leeimport android.os.Bundle;
22827b5d6611018497eb28a0776cb51226fb81ae23Yorke Leeimport android.os.Parcelable;
23e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
24043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Nickname;
257d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
267d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
272ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.provider.ContactsContract.Contacts;
282ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.provider.ContactsContract.Data;
295297c6af41f3fd2f08cff5b84105af4efd1ab79fJeff Hamiltonimport android.text.TextUtils;
30aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.util.AttributeSet;
312d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jangimport android.util.Pair;
32e731d426eda3692402f3cecdc29421fcf7f1fb54Jeff Sharkeyimport android.view.LayoutInflater;
332ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.view.View;
342ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.view.ViewGroup;
352ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkeyimport android.widget.TextView;
362ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
37e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.GroupMetaDataLoader;
38e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
39428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountType;
40428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountType.EditType;
41428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind;
42cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.RawContactDelta;
43738ff8623dc77dd91a1b9023861e924ba5e4c27eChiao Chengimport com.android.contacts.common.model.ValuesDelta;
44cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.RawContactModifier;
45daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
46ba09d4cc21d55181c1760e7994f0225939f4999dChiao Chengimport com.google.common.base.Objects;
47e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
48bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmannimport java.util.ArrayList;
49bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann
502ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey/**
512ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * Custom view that provides all the editor interaction for a specific
52851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * {@link Contacts} represented through an {@link RawContactDelta}. Callers can
532ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * reuse this view and quickly rebuild its contents through
54851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * {@link #setState(RawContactDelta, AccountType, ViewIdGenerator)}.
552ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * <p>
568d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey * Internal updates are performed against {@link ValuesDelta} so that the
57851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * source {@link RawContact} can be swapped out. Any state-based changes, such as
582ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey * adding {@link Data} rows or changing {@link EditType}, are performed through
59851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu * {@link RawContactModifier} to ensure that {@link AccountType} are enforced.
602ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey */
6172af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmannpublic class RawContactEditorView extends BaseRawContactEditorView {
62827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    private static final String KEY_SUPER_INSTANCE_STATE = "superInstanceState";
63827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee
64ea54a96ada15c83086e854619789ea025244f7a6Dmitri Plotnikov    private LayoutInflater mInflater;
65ea54a96ada15c83086e854619789ea025244f7a6Dmitri Plotnikov
665ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    private StructuredNameEditorView mName;
675ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    private PhoneticNameEditorView mPhoneticName;
68d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    private TextFieldsEditorView mNickName;
69d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
70e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov    private GroupMembershipView mGroupMembershipView;
712ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
72bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann    private ViewGroup mFields;
7314f61ab769f6e178a540a7579e446a010fb836daJeff Sharkey
74daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private View mAccountSelector;
75daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private TextView mAccountSelectorTypeTextView;
76daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private TextView mAccountSelectorNameTextView;
77daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
78daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private View mAccountHeader;
79daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private TextView mAccountHeaderTypeTextView;
80daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell    private TextView mAccountHeaderNameTextView;
812fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar
822fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar    private long mRawContactId = -1;
837d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    private boolean mAutoAddToDefaultGroup = true;
847d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    private Cursor mGroupMetaData;
857d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    private DataKind mGroupMembershipKind;
86851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    private RawContactDelta mState;
872fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar
8872af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann    public RawContactEditorView(Context context) {
89aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        super(context);
90aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
91aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
9272af89f9e497bb8ef54fe3deeec7e8477d192242Daniel Lehmann    public RawContactEditorView(Context context, AttributeSet attrs) {
93aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        super(context, attrs);
94aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
95aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
96aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    @Override
9702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    public void setEnabled(boolean enabled) {
9802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        super.setEnabled(enabled);
9902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
10002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        View view = getPhotoEditor();
10102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        if (view != null) {
1025ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            view.setEnabled(enabled);
10302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        }
10402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
10502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        if (mName != null) {
1065ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            mName.setEnabled(enabled);
1075ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        }
1085ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
1095ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        if (mPhoneticName != null) {
1105ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov            mPhoneticName.setEnabled(enabled);
11102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        }
11202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
11302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        if (mFields != null) {
11402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            int count = mFields.getChildCount();
11502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            for (int i = 0; i < count; i++) {
11602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov                mFields.getChildAt(i).setEnabled(enabled);
11702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            }
11802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        }
11902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
12002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        if (mGroupMembershipView != null) {
12102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            mGroupMembershipView.setEnabled(enabled);
12202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        }
12302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    }
12402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
12502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    @Override
126aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    protected void onFinishInflate() {
1276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        super.onFinishInflate();
1286f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
129bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann        mInflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
130aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
1315ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        mName = (StructuredNameEditorView)findViewById(R.id.edit_name);
132aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        mName.setDeletable(false);
133aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
1345ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        mPhoneticName = (PhoneticNameEditorView)findViewById(R.id.edit_phonetic_name);
1351ebbd5bbe71814123b80df702b474bcd7196cbb7Katherine Kuan        mPhoneticName.setDeletable(false);
1365ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
137d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        mNickName = (TextFieldsEditorView)findViewById(R.id.edit_nick_name);
1382ebade8924bb6d2734b603938f418959cc79e2adBrian Attwell
139bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann        mFields = (ViewGroup)findViewById(R.id.sect_fields);
140aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
141daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountHeader = findViewById(R.id.account_header_container);
142daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountHeaderTypeTextView = (TextView) findViewById(R.id.account_type);
143daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountHeaderNameTextView = (TextView) findViewById(R.id.account_name);
144daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
145daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelector = findViewById(R.id.account_selector_container);
146daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorTypeTextView = (TextView) findViewById(R.id.account_type_selector);
147daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorNameTextView = (TextView) findViewById(R.id.account_name_selector);
1482ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey    }
1492ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
150827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    @Override
151827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    protected Parcelable onSaveInstanceState() {
152827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        Bundle bundle = new Bundle();
153827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        // super implementation of onSaveInstanceState returns null
154827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        bundle.putParcelable(KEY_SUPER_INSTANCE_STATE, super.onSaveInstanceState());
155827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        return bundle;
156827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    }
157827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee
158827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    @Override
159827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    protected void onRestoreInstanceState(Parcelable state) {
160827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        if (state instanceof Bundle) {
161827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee            Bundle bundle = (Bundle) state;
162827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee            super.onRestoreInstanceState(bundle.getParcelable(KEY_SUPER_INSTANCE_STATE));
163827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee            return;
164827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        }
165827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee        super.onRestoreInstanceState(state);
166827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee    }
167827b5d6611018497eb28a0776cb51226fb81ae23Yorke Lee
1682ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey    /**
1692ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey     * Set the internal state for this view, given a current
170851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu     * {@link RawContactDelta} state and the {@link AccountType} that
1712ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey     * apply to that state.
1722ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey     */
1734bef56bdbde4c6bd439ed2d528d4b99974359e18Jeff Hamilton    @Override
174851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    public void setState(RawContactDelta state, AccountType type, ViewIdGenerator vig,
175681f36cc7cc49be781eedc4685eda2d1b2c0444cIsaac Katzenelson            boolean isProfile) {
1763fa75acf99f5245eae00c77086ff130b3552ceecKatherine Kuan
1777d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        mState = state;
1787d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
1792ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey        // Remove any existing sections
180bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann        mFields.removeAllViews();
1812ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
18269f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov        // Bail if invalid state or account type
18369f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov        if (state == null || type == null) return;
184d046a039e41deab0635c3327cd40c3896e39acadJeff Sharkey
1854b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki        setId(vig.getId(state, null, null, ViewIdGenerator.NO_VIEW_INDEX));
1864b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki
187043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        // Make sure we have a StructuredName
188851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        RawContactModifier.ensureKindExists(state, type, StructuredName.CONTENT_ITEM_TYPE);
189aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
190851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        mRawContactId = state.getRawContactId();
1912fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar
192a7c3d4d726b91f645431af14d8cceadd2245f4ceKatherine Kuan        // Fill in the account info
1932d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang        final Pair<String,String> accountInfo = EditorUiUtils.getAccountInfo(getContext(),
194c4cecc7e7534c7f5d887222d9e6f1a43364f7665Walter Jang                isProfile, state.getAccountName(), type);
1952d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang        if (accountInfo == null) {
1962d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang            // Hide this view so the other text view will be centered vertically
1972d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang            mAccountHeaderNameTextView.setVisibility(View.GONE);
1982d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang        } else {
1992d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang            if (accountInfo.first == null) {
200daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                mAccountHeaderNameTextView.setVisibility(View.GONE);
201681f36cc7cc49be781eedc4685eda2d1b2c0444cIsaac Katzenelson            } else {
202daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                mAccountHeaderNameTextView.setVisibility(View.VISIBLE);
2032d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang                mAccountHeaderNameTextView.setText(accountInfo.first);
204681f36cc7cc49be781eedc4685eda2d1b2c0444cIsaac Katzenelson            }
2052d3f31c210ffc617e82e3b41fc32b54ec2a5011aWalter Jang            mAccountHeaderTypeTextView.setText(accountInfo.second);
206769e5fed7af619d538da66adb926eeccdc159cd9Daisuke Miyakawa        }
207daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        updateAccountHeaderContentDescription();
208daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell
209daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        // The account selector and header are both used to display the same information.
210daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorTypeTextView.setText(mAccountHeaderTypeTextView.getText());
211daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorTypeTextView.setVisibility(mAccountHeaderTypeTextView.getVisibility());
212daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorNameTextView.setText(mAccountHeaderNameTextView.getText());
213daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountSelectorNameTextView.setVisibility(mAccountHeaderNameTextView.getVisibility());
214daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        // Showing the account header at the same time as the account selector drop down is
215daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        // confusing. They should be mutually exclusive.
216daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell        mAccountHeader.setVisibility(mAccountSelector.getVisibility() == View.GONE
217daa2058979fda84a0ce22e21edd53aa049e80aa0Brian Attwell                ? View.VISIBLE : View.GONE);
218769e5fed7af619d538da66adb926eeccdc159cd9Daisuke Miyakawa
2196f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey        // Show photo editor when supported
220851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
22169f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov        setHasPhotoEditor((type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null));
22202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        getPhotoEditor().setEnabled(isEnabled());
22302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        mName.setEnabled(isEnabled());
2246f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
2255ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        mPhoneticName.setEnabled(isEnabled());
2265ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
2271fb6275a57318261cb6dba511954cb754cd17fa2Jeff Hamilton        // Show and hide the appropriate views
228bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann        mFields.setVisibility(View.VISIBLE);
229bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann        mName.setVisibility(View.VISIBLE);
2305ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        mPhoneticName.setVisibility(View.VISIBLE);
2312fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar
23269f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov        mGroupMembershipKind = type.getKindForMimetype(GroupMembership.CONTENT_ITEM_TYPE);
2337d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        if (mGroupMembershipKind != null) {
234e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov            mGroupMembershipView = (GroupMembershipView)mInflater.inflate(
235e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov                    R.layout.item_group_membership, mFields, false);
2367d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            mGroupMembershipView.setKind(mGroupMembershipKind);
23702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            mGroupMembershipView.setEnabled(isEnabled());
238e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov        }
239e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov
2402ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey        // Create editor sections for each possible data kind
24169f9e6f0cd9b5401da55f251e9bd98e69643d7dfDmitri Plotnikov        for (DataKind kind : type.getSortedDataKinds()) {
2422ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            // Skip kind of not editable
2432ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            if (!kind.editable) continue;
2442ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey
2452ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            final String mimeType = kind.mimeType;
2462ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
2472ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey                // Handle special case editor for structured name
2488d9767d79f9fe2a09ee6e981b1fede7e9863d62aJeff Sharkey                final ValuesDelta primary = state.getPrimaryEntry(mimeType);
2495ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                mName.setValues(
2505ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME),
2515ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        primary, state, false, vig);
2525ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                mPhoneticName.setValues(
2535ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        type.getKindForMimetype(DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME),
2545ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov                        primary, state, false, vig);
2557c8012090926070dc6bde1691341a2969996518cBrian Attwell                // It is useful to use Nickname outside of a KindSectionView so that we can treat it
2567c8012090926070dc6bde1691341a2969996518cBrian Attwell                // as a part of StructuredName's fake KindSectionView, even though it uses a
2577c8012090926070dc6bde1691341a2969996518cBrian Attwell                // different CP2 mime-type. We do a bit of extra work below to make this possible.
2587c8012090926070dc6bde1691341a2969996518cBrian Attwell                final DataKind nickNameKind = type.getKindForMimetype(Nickname.CONTENT_ITEM_TYPE);
259099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                if (nickNameKind != null) {
260099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    ValuesDelta primaryNickNameEntry = state.getPrimaryEntry(nickNameKind.mimeType);
261099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    if (primaryNickNameEntry == null) {
262099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                        primaryNickNameEntry = RawContactModifier.insertChild(state, nickNameKind);
263099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    }
264099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    mNickName.setValues(nickNameKind, primaryNickNameEntry, state, false, vig);
265099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    mNickName.setDeletable(false);
266099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                } else {
267099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    mPhoneticName.setPadding(0, 0, 0, (int) getResources().getDimension(
268099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                            R.dimen.editor_padding_between_editor_views));
269099046cfb5ede3a56cff494796e79d194bf81da6Brian Attwell                    mNickName.setVisibility(View.GONE);
2707c8012090926070dc6bde1691341a2969996518cBrian Attwell                }
2712ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
2722ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey                // Handle special case editor for photos
2730b45a58fad48888fee36eb0edf50705e0aa00e30Jeff Sharkey                final ValuesDelta primary = state.getPrimaryEntry(mimeType);
274ea54a96ada15c83086e854619789ea025244f7a6Dmitri Plotnikov                getPhotoEditor().setValues(kind, primary, state, false, vig);
275e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov            } else if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
276e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov                if (mGroupMembershipView != null) {
277e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov                    mGroupMembershipView.setState(state);
278043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    mFields.addView(mGroupMembershipView);
279e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov                }
280043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            } else if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(mimeType)
281043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    || DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)
282043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    || Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
2832ebade8924bb6d2734b603938f418959cc79e2adBrian Attwell                // Don't create fields for each of these mime-types. They are handled specially.
284043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                continue;
285bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann            } else {
2862ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey                // Otherwise use generic section-based editors
2872ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey                if (kind.fieldList == null) continue;
288aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey                final KindSectionView section = (KindSectionView)mInflater.inflate(
289bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann                        R.layout.item_kind_section, mFields, false);
2904a9351db3c8385469bad037544d4b60d76504f5eWalter Jang                section.setShowOneEmptyEditor(true);
29102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov                section.setEnabled(isEnabled());
29288b0a8cc7c512c5f28dad958da276974c845355cWalter Jang                section.setState(kind, state, /* readOnly =*/ false, vig);
293bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmann                mFields.addView(section);
2942ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey            }
2952ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey        }
296e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov
2977d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        addToDefaultGroupIfNeeded();
298e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov    }
299e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov
300e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov    @Override
301e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov    public void setGroupMetaData(Cursor groupMetaData) {
3027d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        mGroupMetaData = groupMetaData;
3037d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        addToDefaultGroupIfNeeded();
304e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov        if (mGroupMembershipView != null) {
305e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov            mGroupMembershipView.setGroupMetaData(groupMetaData);
306e843f916942fff482ec162eee2a23914e32182cfDmitri Plotnikov        }
3072ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey    }
30847673e82f210e3b2d38d49652726b51770e71230Neel Parekh
3097d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    public void setAutoAddToDefaultGroup(boolean flag) {
3107d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        this.mAutoAddToDefaultGroup = flag;
3117d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    }
3127d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
3137d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    /**
3147d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * If automatic addition to the default group was requested (see
3157d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * {@link #setAutoAddToDefaultGroup}, checks if the raw contact is in any
3167d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * group and if it is not adds it to the default group (in case of Google
3177d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * contacts that's "My Contacts").
3187d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     */
3197d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    private void addToDefaultGroupIfNeeded() {
3207d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        if (!mAutoAddToDefaultGroup || mGroupMetaData == null || mGroupMetaData.isClosed()
3217d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                || mState == null) {
3227d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            return;
3237d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        }
3247d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
3257d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        boolean hasGroupMembership = false;
3267d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        ArrayList<ValuesDelta> entries = mState.getMimeEntries(GroupMembership.CONTENT_ITEM_TYPE);
3277d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        if (entries != null) {
3287d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            for (ValuesDelta values : entries) {
329851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                Long id = values.getGroupRowId();
3307d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                if (id != null && id.longValue() != 0) {
3317d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                    hasGroupMembership = true;
3327d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                    break;
3337d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                }
3347d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            }
3357d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        }
3367d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
3377d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        if (!hasGroupMembership) {
3387d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            long defaultGroupId = getDefaultGroupId();
3397d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            if (defaultGroupId != -1) {
340851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu                ValuesDelta entry = RawContactModifier.insertChild(mState, mGroupMembershipKind);
341a8c9337bf6ca808382d6c4401b05ddc79929e9f5Jay Shrauner                if (entry != null) {
342a8c9337bf6ca808382d6c4401b05ddc79929e9f5Jay Shrauner                    entry.setGroupRowId(defaultGroupId);
343a8c9337bf6ca808382d6c4401b05ddc79929e9f5Jay Shrauner                }
3447d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            }
3457d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        }
3467d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    }
3477d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
3487d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    /**
3497d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * Returns the default group (e.g. "My Contacts") for the current raw contact's
3507d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     * account.  Returns -1 if there is no such group.
3517d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov     */
3527d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    private long getDefaultGroupId() {
353851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String accountType = mState.getAccountType();
354851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String accountName = mState.getAccountName();
355851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu        String accountDataSet = mState.getDataSet();
3567d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        mGroupMetaData.moveToPosition(-1);
3577d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        while (mGroupMetaData.moveToNext()) {
3587d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            String name = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_NAME);
3597d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            String type = mGroupMetaData.getString(GroupMetaDataLoader.ACCOUNT_TYPE);
3602b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro            String dataSet = mGroupMetaData.getString(GroupMetaDataLoader.DATA_SET);
3612b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro            if (name.equals(accountName) && type.equals(accountType)
3622b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro                    && Objects.equal(dataSet, accountDataSet)) {
3637d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                long groupId = mGroupMetaData.getLong(GroupMetaDataLoader.GROUP_ID);
3647d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                if (!mGroupMetaData.isNull(GroupMetaDataLoader.AUTO_ADD)
3657d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                            && mGroupMetaData.getInt(GroupMetaDataLoader.AUTO_ADD) != 0) {
3667d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                    return groupId;
3677d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov                }
3687d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov            }
3697d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        }
3707d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov        return -1;
3717d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov    }
3727d901bb3d4118762e21f4db19e35fc937dcf96feDmitri Plotnikov
37344cfc56d1701629070384364416c1311b780535dChiao Cheng    public StructuredNameEditorView getNameEditor() {
374f491ae914769f1062a4d9c31fcbec5ff0e01e4e6Dmitri Plotnikov        return mName;
37547673e82f210e3b2d38d49652726b51770e71230Neel Parekh    }
3762fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar
3775ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    public TextFieldsEditorView getPhoneticNameEditor() {
3785ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov        return mPhoneticName;
3795ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov    }
3805ec40b04041818bc042c0671cb1a43b54f650e25Dmitri Plotnikov
381d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    public TextFieldsEditorView getNickNameEditor() {
382d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell        return mNickName;
383d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell    }
384d690dff231dd5a81b9bd7563838455f24e49c75cBrian Attwell
3854bef56bdbde4c6bd439ed2d528d4b99974359e18Jeff Hamilton    @Override
3862fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar    public long getRawContactId() {
3872fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar        return mRawContactId;
3882fb3db55d68ff8a8d9cf8e329de3ec8687d5ff29Evan Millar    }
3892ae666ec99ae9318936a9326e5243987e4e1c586Jeff Sharkey}
390