KindSectionView.java revision 88b0a8cc7c512c5f28dad958da276974c845355c
1aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey/*
2aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * Copyright (C) 2009 The Android Open Source Project
3aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey *
4aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * you may not use this file except in compliance with the License.
6aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * You may obtain a copy of the License at
7aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey *
8aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey *
10aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * Unless required by applicable law or agreed to in writing, software
11aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * See the License for the specific language governing permissions and
14aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * limitations under the License.
15aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey */
16aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor;
18aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
19aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.content.Context;
20043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.graphics.drawable.Drawable;
21043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.Contacts.GroupMembership;
22043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Email;
23043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Event;
24043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Im;
25043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Note;
26043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Organization;
27043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Phone;
28043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Photo;
29043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Relation;
30043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
31043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
32043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.provider.ContactsContract.CommonDataKinds.Website;
33ca87e9c598929b5b6a62da9b80d2114168e24274Daniel Lehmannimport android.provider.ContactsContract.Data;
343e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmannimport android.text.TextUtils;
35aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.util.AttributeSet;
3663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuanimport android.view.LayoutInflater;
37aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.view.View;
38aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.view.ViewGroup;
39043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwellimport android.widget.ImageView;
40aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkeyimport android.widget.LinearLayout;
41aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
42e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
43e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.editor.Editor.EditorListener;
44cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.RawContactModifier;
45cd321f65f1e50409812976380ad1f0fdb3fa35cbYorke Leeimport com.android.contacts.common.model.RawContactDelta;
46738ff8623dc77dd91a1b9023861e924ba5e4c27eChiao Chengimport com.android.contacts.common.model.ValuesDelta;
47428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.dataitem.DataKind;
48e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
4962bab31374dd66462643cbc04ebb2acece4b9b39Dmitri Plotnikovimport java.util.ArrayList;
501b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuanimport java.util.List;
5162bab31374dd66462643cbc04ebb2acece4b9b39Dmitri Plotnikov
52aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey/**
53aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * Custom view for an entire section of data as segmented by
54aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * {@link DataKind} around a {@link Data#MIMETYPE}. This view shows a
55aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey * section header and a trigger for adding new {@link Data} rows.
56aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey */
57bb556954e29ae0700b729f128d8cd09ecdd91ee3Daniel Lehmannpublic class KindSectionView extends LinearLayout implements EditorListener {
58aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
59aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    private ViewGroup mEditors;
60043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    private ImageView mIcon;
61aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
62aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    private DataKind mKind;
63851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu    private RawContactDelta mState;
6492525ff51e2cb06531447a7dcde5e22334669c8eMegha Joshi    private boolean mReadOnly;
656f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
664b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki    private ViewIdGenerator mViewIdGenerator;
674b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki
6863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    private LayoutInflater mInflater;
6991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
70aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    public KindSectionView(Context context) {
7191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov        this(context, null);
72aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
73aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
74aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    public KindSectionView(Context context, AttributeSet attrs) {
75aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        super(context, attrs);
76aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
77aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
7802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    @Override
7902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    public void setEnabled(boolean enabled) {
8002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        super.setEnabled(enabled);
8102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        if (mEditors != null) {
8202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            int childCount = mEditors.getChildCount();
8302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            for (int i = 0; i < childCount; i++) {
8402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov                mEditors.getChildAt(i).setEnabled(enabled);
8502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            }
8602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        }
8702bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
88043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        updateEmptyEditors(/* shouldAnimate = */ true);
8991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    }
9091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
9102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    public boolean isReadOnly() {
9202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        return mReadOnly;
9302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov    }
9402bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
95aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    /** {@inheritDoc} */
96aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    @Override
97aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    protected void onFinishInflate() {
98aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        setDrawingCacheEnabled(true);
99aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        setAlwaysDrawnWithCacheEnabled(true);
100aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
101f140227beb6d9e78955a7676dc0dd3f793f72017Brian Attwell        mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
10263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
103a94859f61c216d4e137a631995026d3ddefbbf70Katherine Kuan        mEditors = (ViewGroup) findViewById(R.id.kind_editors);
104043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        mIcon = (ImageView) findViewById(R.id.kind_icon);
105aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
106aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
10779c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann    @Override
1082293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan    public void onDeleteRequested(Editor editor) {
1092293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan        // If there is only 1 editor in the section, then don't allow the user to delete it.
1102293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan        // Just clear the fields in the editor.
1112293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan        if (getEditorCount() == 1) {
1122293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan            editor.clearAllFields();
1132293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan        } else {
1142293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan            // Otherwise it's okay to delete this {@link Editor}
1152293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan            editor.deleteEditor();
1162293e55d550fbc9974d1185960715e59acb14a85Katherine Kuan        }
117aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
118aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
11979c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann    @Override
1206f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    public void onRequest(int request) {
1212591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        // If a field has become empty or non-empty, then check if another row
1222591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        // can be added dynamically.
1232591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        if (request == FIELD_TURNED_EMPTY || request == FIELD_TURNED_NON_EMPTY) {
124043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            updateEmptyEditors(/* shouldAnimate = */ true);
1251b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan        }
1266f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey    }
1276f8d46b5fb96c2bead1317aae93a73fc89b093abJeff Sharkey
1281044645b9c2050436f4f0e0c7e5b8da2931879baWalter Jang    public void setState(DataKind kind, RawContactDelta state, boolean readOnly,
12988b0a8cc7c512c5f28dad958da276974c845355cWalter Jang            ViewIdGenerator vig) {
130aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        mKind = kind;
131aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        mState = state;
13292525ff51e2cb06531447a7dcde5e22334669c8eMegha Joshi        mReadOnly = readOnly;
1334b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki        mViewIdGenerator = vig;
1344b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki
1354b722a93f1ecdeb2890fb7e5db4c22794bccfdcdMakoto Onuki        setId(mViewIdGenerator.getId(state, kind, null, ViewIdGenerator.NO_VIEW_INDEX));
136aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
137aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        // TODO: handle resources from remote packages
138043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        final String titleString = (kind.titleRes == -1 || kind.titleRes == 0)
139f7ce5978a6a6314028fe9bbb1da99338b111750fDaniel Lehmann                ? ""
140cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann                : getResources().getString(kind.titleRes);
141043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        mIcon.setContentDescription(titleString);
142aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
143043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        mIcon.setImageDrawable(getMimeTypeDrawable(kind.mimeType));
1448c8cafb21cebbea33468c068efacea6c77635811Brian Attwell        if (mIcon.getDrawable() == null) {
1458c8cafb21cebbea33468c068efacea6c77635811Brian Attwell            mIcon.setContentDescription(null);
1468c8cafb21cebbea33468c068efacea6c77635811Brian Attwell        }
147aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
148043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        rebuildFromState();
149043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        updateEmptyEditors(/* shouldAnimate = */ false);
1503fa75acf99f5245eae00c77086ff130b3552ceecKatherine Kuan    }
1513fa75acf99f5245eae00c77086ff130b3552ceecKatherine Kuan
152aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    /**
153aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey     * Build editors for all current {@link #mState} rows.
154aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey     */
155043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    private void rebuildFromState() {
156aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        // Remove any existing editors
157aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        mEditors.removeAllViews();
158aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
159da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann        // Check if we are displaying anything here
160da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann        boolean hasEntries = mState.hasMimeEntries(mKind.mimeType);
161da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann
162da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann        if (hasEntries) {
163da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann            for (ValuesDelta entry : mState.getMimeEntries(mKind.mimeType)) {
164da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann                // Skip entries that aren't visible
165da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann                if (!entry.isVisible()) continue;
1663e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann                if (isEmptyNoop(entry)) continue;
167da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann
168634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann                createEditorView(entry);
169da5fd9039bd303f5e4634a31ed9a00d58d679b39Daniel Lehmann            }
170aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey        }
171aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
172aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey
173634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann
174634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann    /**
175634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann     * Creates an EditorView for the given entry. This function must be used while constructing
176634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann     * the views corresponding to the the object-model. The resulting EditorView is also added
177634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann     * to the end of mEditors
178634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann     */
179634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann    private View createEditorView(ValuesDelta entry) {
180634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        final View view;
181ddd4e821226395fd977d87b6692f761c90d59139Chiao Cheng        final int layoutResId = EditorUiUtils.getLayoutResourceId(mKind.mimeType);
18263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        try {
183ddd4e821226395fd977d87b6692f761c90d59139Chiao Cheng            view = mInflater.inflate(layoutResId, mEditors, false);
18463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        } catch (Exception e) {
18563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            throw new RuntimeException(
18663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                    "Cannot allocate editor with layout resource ID " +
187ddd4e821226395fd977d87b6692f761c90d59139Chiao Cheng                    layoutResId + " for MIME type " + mKind.mimeType +
1882591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan                    " with error " + e.toString());
189634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        }
1909f9d78e41f336b77012437c8622eafeaad4b2adcWalter Jang        // Hide the types drop downs until the associated edit field is focused
1919f9d78e41f336b77012437c8622eafeaad4b2adcWalter Jang        if (view instanceof LabeledEditorView) {
1929f9d78e41f336b77012437c8622eafeaad4b2adcWalter Jang            ((LabeledEditorView) view).setHideTypeInitially(true);
1939f9d78e41f336b77012437c8622eafeaad4b2adcWalter Jang        }
194634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann
19502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        view.setEnabled(isEnabled());
19602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
197634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        if (view instanceof Editor) {
198634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann            Editor editor = (Editor) view;
1995e330ed98f1c2711b4cd3b375a1c0f76bedaf3e1Katherine Kuan            editor.setDeletable(true);
200634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann            editor.setValues(mKind, entry, mState, mReadOnly, mViewIdGenerator);
201634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann            editor.setEditorListener(this);
202634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        }
203634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        mEditors.addView(view);
204634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann        return view;
205634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann    }
206634ab3baaf2bc69bd7977153fcdebf0e737e207dDaniel Lehmann
2079e83c84a7603eb6fca1b42631d894731d61f7a34Daniel Lehmann    /**
2083e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann     * Tests whether the given item has no changes (so it exists in the database) but is empty
2093e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann     */
2103e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann    private boolean isEmptyNoop(ValuesDelta item) {
2113e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann        if (!item.isNoop()) return false;
2123e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann        final int fieldCount = mKind.fieldList.size();
2133e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann        for (int i = 0; i < fieldCount; i++) {
2143e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann            final String column = mKind.fieldList.get(i).column;
2153e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann            final String value = item.getAsString(column);
2163e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann            if (!TextUtils.isEmpty(value)) return false;
2173e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann        }
2183e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann        return true;
2193e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann    }
2203e7436450f0fdd5ad939c3b46e7176e082c9ee11Daniel Lehmann
2211b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan    /**
2222591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan     * Updates the editors being displayed to the user removing extra empty
2232591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan     * {@link Editor}s, so there is only max 1 empty {@link Editor} view at a time.
2241b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan     */
225043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    private void updateEmptyEditors(boolean shouldAnimate) {
226043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell
227043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        final List<View> emptyEditors = getEmptyEditors();
2281b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan
2291b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan        // If there is more than 1 empty editor, then remove it from the list of editors.
2302591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        if (emptyEditors.size() > 1) {
231043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            for (final View emptyEditorView : emptyEditors) {
232043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                // If no child {@link View}s are being focused on within this {@link View}, then
233043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                // remove this empty editor. We can assume that at least one empty editor has focus.
234043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                // The only way to get two empty editors is by deleting characters from a non-empty
235043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                // editor, in which case this editor has focus.
2361b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan                if (emptyEditorView.findFocus() == null) {
237043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    final Editor editor = (Editor) emptyEditorView;
238043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    if (shouldAnimate) {
239043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                        editor.deleteEditor();
240043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    } else {
241043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                        mEditors.removeView(emptyEditorView);
242043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                    }
2431b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan                }
2441b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan            }
245043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        } else if (mKind == null) {
246043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            // There is nothing we can do.
247043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            return;
248043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        } else if (isReadOnly()) {
249043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            // We don't show empty editors for read only data kinds.
250043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            return;
251043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        } else if (mKind.typeOverallMax == getEditorCount() && mKind.typeOverallMax != 0) {
252043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            // We have already reached the maximum number of editors. Lets not add any more.
253043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            return;
254043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        } else if (emptyEditors.size() == 1) {
255043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            // We have already reached the maximum number of empty editors. Lets not add any more.
256043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            return;
25788b0a8cc7c512c5f28dad958da276974c845355cWalter Jang        } else {
258043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            final ValuesDelta values = RawContactModifier.insertChild(mState, mKind);
259043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            final View newField = createEditorView(values);
260043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            if (shouldAnimate) {
261043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                newField.setVisibility(View.GONE);
262043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                EditorAnimator.getInstance().showFieldFooter(newField);
263043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            }
2643f26e24c0cbc988b32d274b7a4e88c994355ef4fDaniel Lehmann        }
2651b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan    }
2661b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan
2671b22073590c1801c3e6c7bde2f4636632a049f6cKatherine Kuan    /**
268e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang     * Whether this section has any empty editors.
269e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang     */
270e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang    public boolean hasEmptyEditor() {
271e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang        return !getEmptyEditors().isEmpty();
272e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang    }
273e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang
274e720fdeb3ef0892834d7ab9af8cc44dd9eb9be17Walter Jang    /**
2752591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan     * Returns a list of empty editor views in this section.
2762591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan     */
2772591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan    private List<View> getEmptyEditors() {
2782591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        List<View> emptyEditorViews = new ArrayList<View>();
2792591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        for (int i = 0; i < mEditors.getChildCount(); i++) {
2802591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            View view = mEditors.getChildAt(i);
2812591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            if (((Editor) view).isEmpty()) {
2822591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan                emptyEditorViews.add(view);
2832591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            }
2842591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        }
2852591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        return emptyEditorViews;
2862591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan    }
2872591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan
288043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    public int getEditorCount() {
289043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        return mEditors.getChildCount();
29026918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus    }
29126918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus
292043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    public DataKind getKind() {
293043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        return mKind;
29426918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus    }
29526918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus
29626918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus    /**
297043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell     * Return an icon that represents {@param mimeType}.
29826918da1650c1ff7b6f92deb978ab976525c811aJosh Gargus     */
299043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell    private Drawable getMimeTypeDrawable(String mimeType) {
300043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell        switch (mimeType) {
301043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case StructuredPostal.CONTENT_ITEM_TYPE:
302043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_place_24dp);
303043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case SipAddress.CONTENT_ITEM_TYPE:
304043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_dialer_sip_black_24dp);
305043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Phone.CONTENT_ITEM_TYPE:
306043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_phone_24dp);
307043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Im.CONTENT_ITEM_TYPE:
308043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_message_24dp);
309043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Event.CONTENT_ITEM_TYPE:
310043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_event_24dp);
311043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Email.CONTENT_ITEM_TYPE:
312043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_email_24dp);
313043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Website.CONTENT_ITEM_TYPE:
314043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_public_black_24dp);
315043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Photo.CONTENT_ITEM_TYPE:
316043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_camera_alt_black_24dp);
317043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case GroupMembership.CONTENT_ITEM_TYPE:
318043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_people_black_24dp);
319043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Organization.CONTENT_ITEM_TYPE:
320043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_business_black_24dp);
321043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Note.CONTENT_ITEM_TYPE:
322043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_insert_comment_black_24dp);
323043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            case Relation.CONTENT_ITEM_TYPE:
324043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return getResources().getDrawable(R.drawable.ic_circles_extended_black_24dp);
325043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell            default:
326043fba637b421dcd554c634f769f0e883fb5ff8bBrian Attwell                return null;
32762bab31374dd66462643cbc04ebb2acece4b9b39Dmitri Plotnikov        }
328aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey    }
329aad8848282f51d73ad308e9ad3ebcef592fa153fJeff Sharkey}
330