LabeledEditorView.java revision 2591436971bad3050c85929c8e0c5a8d48111f88
1392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann/*
2392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Copyright (C) 2010 The Android Open Source Project
3392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann *
4392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License");
5392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * you may not use this file except in compliance with the License.
6392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * You may obtain a copy of the License at
7392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann *
8392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann *      http://www.apache.org/licenses/LICENSE-2.0
9392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann *
10392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Unless required by applicable law or agreed to in writing, software
11392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS,
12392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * See the License for the specific language governing permissions and
14392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * limitations under the License.
15392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */
16392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
1718ffaa2561cc7dd2e3ef81737e6537931c0a9a11Dmitri Plotnikovpackage com.android.contacts.editor;
18392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
19392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.ContactsUtils;
20392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.R;
214597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.EditType;
22405671a7b42d97ebf7ae7c0eeb4721f881139673Daisuke Miyakawaimport com.android.contacts.model.DataKind;
23392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.model.EntityDelta;
24392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.model.EntityDelta.ValuesDelta;
25392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.model.EntityModifier;
26392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.util.DialogManager;
27392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport com.android.contacts.util.DialogManager.DialogShowingView;
28392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
29392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.app.AlertDialog;
30392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.app.Dialog;
31392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Context;
32392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.DialogInterface;
33392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Entity;
34392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.os.Bundle;
3579c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmannimport android.os.Handler;
3611bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikovimport android.text.TextUtils;
37392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.util.AttributeSet;
382fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.view.LayoutInflater;
39392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.View;
40392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.ViewGroup;
41392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.inputmethod.EditorInfo;
422fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.AdapterView;
432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.AdapterView.OnItemSelectedListener;
442fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.ArrayAdapter;
45392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.EditText;
46392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.ImageButton;
4763ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuanimport android.widget.LinearLayout;
482fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.Spinner;
492fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.TextView;
50392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
5114918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikovimport java.util.List;
5214918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov
53392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann/**
5463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan * Base class for editors that handles labels and values. Uses
5563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan * {@link ValuesDelta} to read any existing {@link Entity} values, and to
5663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan * correctly write any changes values.
57392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */
5863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuanpublic abstract class LabeledEditorView extends LinearLayout implements Editor, DialogShowingView {
59392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected static final String DIALOG_ID_KEY = "dialog_id";
60392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private static final int DIALOG_ID_CUSTOM = 1;
61392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
62392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private static final int INPUT_TYPE_CUSTOM = EditorInfo.TYPE_CLASS_TEXT
63392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
64392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
6563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    private TextView mTitle;
662fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    private Spinner mLabel;
672fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    private EditTypeAdapter mEditTypeAdapter;
6863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    private View mDeleteContainer;
69392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private ImageButton mDelete;
70392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
71392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private DataKind mKind;
72392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private ValuesDelta mEntry;
73392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private EntityDelta mState;
74392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private boolean mReadOnly;
752591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan    private boolean mWasEmpty = true;
76392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
77392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private EditType mType;
78392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
79392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private ViewIdGenerator mViewIdGenerator;
80392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private DialogManager mDialogManager = null;
81392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private EditorListener mListener;
8291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    protected int mMinLineItemHeight;
83392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
842fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    /**
852fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov     * A marker in the spinner adapter of the currently selected custom type.
862fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov     */
872fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    public static final EditType CUSTOM_SELECTION = new EditType(0, 0);
882fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
892fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    private OnItemSelectedListener mSpinnerListener = new OnItemSelectedListener() {
902fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
912fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        @Override
922fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public void onItemSelected(
932fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                AdapterView<?> parent, View view, int position, long id) {
942fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            onTypeSelectionChange(position);
952fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
962fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
972fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        @Override
982fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public void onNothingSelected(AdapterView<?> parent) {
992fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
1002fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    };
1012fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
102392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public LabeledEditorView(Context context) {
103392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        super(context);
10491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov        init(context);
105392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
106392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
107392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public LabeledEditorView(Context context, AttributeSet attrs) {
108392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        super(context, attrs);
10991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov        init(context);
110392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
111392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
112392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public LabeledEditorView(Context context, AttributeSet attrs, int defStyle) {
113392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        super(context, attrs, defStyle);
11491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov        init(context);
11591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    }
11691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
11791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    private void init(Context context) {
11891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov        mMinLineItemHeight = context.getResources().getDimensionPixelSize(
11991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov                R.dimen.editor_min_line_item_height);
120392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
121392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
12263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    /** {@inheritDoc} */
12363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    @Override
12463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    protected void onFinishInflate() {
12502bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov
12663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mTitle = (TextView) findViewById(R.id.title);
12791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
12863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mLabel = (Spinner) findViewById(R.id.spinner);
12963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mLabel.setOnItemSelectedListener(mSpinnerListener);
13091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
13163ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mDeleteContainer = findViewById(R.id.delete_button_container);
13263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mDelete = (ImageButton) findViewById(R.id.delete_button);
13363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mDelete.setOnClickListener(new OnClickListener() {
13463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            @Override
13563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            public void onClick(View v) {
13663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                // defer removal of this button so that the pressed state is visible shortly
13763ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                new Handler().post(new Runnable() {
13863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                    @Override
13963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                    public void run() {
14063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                        // Keep around in model, but mark as deleted
14163ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                        mEntry.markDeleted();
14263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
14363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                        ((ViewGroup) getParent()).removeView(LabeledEditorView.this);
14463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
14563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                        if (mListener != null) {
14663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                            // Notify listener when present
14763ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                            mListener.onDeleted(LabeledEditorView.this);
14863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                        }
14963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                    }
15063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                });
15191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov            }
15263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        });
15391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    }
15491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
15563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    public boolean isReadOnly() {
15663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        return mReadOnly;
15791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov    }
15891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov
15963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan    public int getBaseline(int row) {
16063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        if (row == 0 && mLabel != null) {
16163ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            return mLabel.getBaseline();
162392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
16363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        return -1;
164392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
165392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
166392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
167392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Creates or removes the type/label button. Doesn't do anything if already correctly configured
168392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
169392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private void setupLabelButton(boolean shouldExist) {
17063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        if (shouldExist) {
17102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            mLabel.setEnabled(!mReadOnly && isEnabled());
17263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mLabel.setVisibility(View.VISIBLE);
17363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
17463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            // Since there's a spinner for this editor, use this as the title
17563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            // instead of the title TextView.
17663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mTitle.setVisibility(View.GONE);
17763ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        } else {
17863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mLabel.setVisibility(View.GONE);
179392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
180392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
181392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
182392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
183392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Creates or removes the remove button. Doesn't do anything if already correctly configured
184392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
185392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private void setupDeleteButton(boolean shouldExist) {
18663ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        if (shouldExist) {
18763ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mDeleteContainer.setVisibility(View.VISIBLE);
18802bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov            mDelete.setEnabled(!mReadOnly && isEnabled());
18963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        } else {
19063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mDeleteContainer.setVisibility(View.GONE);
191392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
192392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
193392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
194392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected void onOptionalFieldVisibilityChange() {
195392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (mListener != null) {
196392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            mListener.onRequest(EditorListener.EDITOR_FORM_CHANGED);
197392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
198392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
199392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
200392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
201392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public void setEditorListener(EditorListener listener) {
202392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mListener = listener;
203392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
204392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
205392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
206392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public void setDeletable(boolean deletable) {
207392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        setupDeleteButton(deletable);
208392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
209392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
210392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
211392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public void setEnabled(boolean enabled) {
21202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov        super.setEnabled(enabled);
21363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mLabel.setEnabled(!mReadOnly && enabled);
21463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mDelete.setEnabled(!mReadOnly && enabled);
215392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
216392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
2172fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    public Spinner getLabel() {
218392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mLabel;
219392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
220392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
221392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public ImageButton getDelete() {
222392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mDelete;
223392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
224392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
225392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected DataKind getKind() {
226392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mKind;
227392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
228392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
229392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected ValuesDelta getEntry() {
230392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mEntry;
231392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
232392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
233392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected EditType getType() {
234392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mType;
235392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
236392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
237392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
238392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Build the current label state based on selected {@link EditType} and
239392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * possible custom label string.
240392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
241392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private void rebuildLabel() {
2422fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        mEditTypeAdapter = new EditTypeAdapter(mContext);
2432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        mLabel.setAdapter(mEditTypeAdapter);
2442fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        if (mEditTypeAdapter.hasCustomSelection()) {
2452fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            mLabel.setSelection(mEditTypeAdapter.getPosition(CUSTOM_SELECTION));
2462fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        } else {
2472fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            mLabel.setSelection(mEditTypeAdapter.getPosition(mType));
248392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
249392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
250392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
251392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
252392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public void onFieldChanged(String column, String value) {
25311bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov        if (!isFieldChanged(column, value)) {
2547d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov            return;
2557d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov        }
2567d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov
257392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        // Field changes are saved directly
258392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mEntry.put(column, value);
259392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (mListener != null) {
260392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            mListener.onRequest(EditorListener.FIELD_CHANGED);
261392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
2622591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan
2632591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        boolean isEmpty = isEmpty();
2642591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        if (mWasEmpty != isEmpty) {
2652591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            if (isEmpty) {
2662591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan                mListener.onRequest(EditorListener.FIELD_TURNED_EMPTY);
2672591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            } else {
2682591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan                mListener.onRequest(EditorListener.FIELD_TURNED_NON_EMPTY);
2692591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            }
2702591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan            mWasEmpty = isEmpty;
2712591436971bad3050c85929c8e0c5a8d48111f88Katherine Kuan        }
272392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
273392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
27411bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov    protected boolean isFieldChanged(String column, String value) {
27560b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        final String dbValue = mEntry.getAsString(column);
27660b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        // nullable fields (e.g. Middle Name) are usually represented as empty columns,
27760b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        // so lets treat null and empty space equivalently here
27860b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        final String dbValueNoNull = dbValue == null ? "" : dbValue;
27960b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        final String valueNoNull = value == null ? "" : value;
28060b239c24c05233bbf3f7cb45697252e15ec76ccDaniel Lehmann        return !TextUtils.equals(dbValueNoNull, valueNoNull);
28111bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov    }
28211bb73bcdf4290ced99e3e06b1f76d4c37357aeaDmitri Plotnikov
283392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected void rebuildValues() {
284392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        setValues(mKind, mEntry, mState, mReadOnly, mViewIdGenerator);
285392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
286392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
287392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
288392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Prepare this editor using the given {@link DataKind} for defining
289392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * structure and {@link ValuesDelta} describing the content to edit.
290392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
291392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
292392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly,
293392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            ViewIdGenerator vig) {
294392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mKind = kind;
295392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mEntry = entry;
296392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mState = state;
297392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mReadOnly = readOnly;
298392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        mViewIdGenerator = vig;
299392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        setId(vig.getId(state, kind, entry, ViewIdGenerator.NO_VIEW_INDEX));
300392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
301392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (!entry.isVisible()) {
302392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            // Hide ourselves entirely if deleted
303392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            setVisibility(View.GONE);
304392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            return;
305392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
306392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        setVisibility(View.VISIBLE);
307392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
30863ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        // TODO: handle resources from remote packages
30963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        String titleString = (kind.titleRes == -1 || kind.titleRes == 0)
31063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                ? ""
31163ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                : getResources().getString(kind.titleRes);
31263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
31363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        // Setup title (may not be shown if there is a Spinner setup later).
31463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mTitle.setText(titleString.toUpperCase());
31563ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan
316392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        // Display label selector if multiple types available
317392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        final boolean hasTypes = EntityModifier.hasEditTypes(kind);
318392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        setupLabelButton(hasTypes);
31963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        mLabel.setEnabled(!readOnly && isEnabled());
320392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (hasTypes) {
321392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            mType = EntityModifier.getCurrentType(entry, kind);
322392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            rebuildLabel();
323392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
324392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
325392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
326392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public ValuesDelta getValues() {
327392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mEntry;
328392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
329392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
330392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
331392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Prepare dialog for entering a custom label. The input value is trimmed: white spaces before
332392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * and after the input text is removed.
333392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * <p>
334392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * If the final value is empty, this change request is ignored;
335392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * no empty text is allowed in any custom label.
336392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
337392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private Dialog createCustomDialog() {
338392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        final EditText customType = new EditText(mContext);
339cb08f1b2a3f2e6e21aa5d993cf44d04658316cccDmitri Plotnikov        customType.setId(R.id.custom_dialog_content);
340392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        customType.setInputType(INPUT_TYPE_CUSTOM);
34114918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov        customType.setSaveEnabled(true);
342392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        customType.requestFocus();
343392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
344392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
345392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        builder.setTitle(R.string.customLabelPickerTitle);
346392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        builder.setView(customType);
347392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
348392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
349392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            @Override
350392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            public void onClick(DialogInterface dialog, int which) {
351392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                final String customText = customType.getText().toString().trim();
352392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                if (ContactsUtils.isGraphic(customText)) {
35314918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                    final List<EditType> allTypes =
35414918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                            EntityModifier.getValidTypes(mState, mKind, null);
35514918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                    mType = null;
35614918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                    for (EditType editType : allTypes) {
35714918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                        if (editType.customColumn != null) {
35814918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                            mType = editType;
35914918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                            break;
36014918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                        }
36114918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                    }
36214918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov                    if (mType == null) return;
36314918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov
364392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                    mEntry.put(mKind.typeColumn, mType.rawValue);
365392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                    mEntry.put(mType.customColumn, customText);
366392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                    rebuildLabel();
367392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                    requestFocusForFirstEditField();
368392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                    onLabelRebuilt();
369392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                }
370392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            }
371392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        });
372392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
373392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        builder.setNegativeButton(android.R.string.cancel, null);
374392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
375392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return builder.create();
376392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
377392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
378392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /**
379392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     * Called after the label has changed (either chosen from the list or entered in the Dialog)
380392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann     */
381392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected void onLabelRebuilt() {
382392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
383392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
3842fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    protected void onTypeSelectionChange(int position) {
3852fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        EditType selected = mEditTypeAdapter.getItem(position);
3862fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        // See if the selection has in fact changed
3872fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        if (mEditTypeAdapter.hasCustomSelection() && selected == CUSTOM_SELECTION) {
3882fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return;
389392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
390392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
3912fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        if (mType == selected && mType.customColumn == null) {
3922fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return;
3932fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
394392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
3952fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        if (selected.customColumn != null) {
3962fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            showDialog(DIALOG_ID_CUSTOM);
3972fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        } else {
3982fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            // User picked type, and we're sure it's ok to actually write the entry.
3992fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            mType = selected;
4002fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            mEntry.put(mKind.typeColumn, mType.rawValue);
4012fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            rebuildLabel();
4022fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            requestFocusForFirstEditField();
4032fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            onLabelRebuilt();
4042fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
405392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
406392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
407392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    /* package */
408392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    void showDialog(int bundleDialogId) {
409392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        Bundle bundle = new Bundle();
410392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        bundle.putInt(DIALOG_ID_KEY, bundleDialogId);
411392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        getDialogManager().showDialogInView(this, bundle);
412392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
413392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
414392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    private DialogManager getDialogManager() {
415392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (mDialogManager == null) {
416392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            Context context = getContext();
417392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            if (!(context instanceof DialogManager.DialogShowingViewActivity)) {
418392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                throw new IllegalStateException(
419392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                        "View must be hosted in an Activity that implements " +
420392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                        "DialogManager.DialogShowingViewActivity");
421392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            }
422392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            mDialogManager = ((DialogManager.DialogShowingViewActivity)context).getDialogManager();
423392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
424392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        return mDialogManager;
425392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
426392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
427392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    @Override
428392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    public Dialog createDialog(Bundle bundle) {
429392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        if (bundle == null) throw new IllegalArgumentException("bundle must not be null");
430392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        int dialogId = bundle.getInt(DIALOG_ID_KEY);
431392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        switch (dialogId) {
432392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            case DIALOG_ID_CUSTOM:
433392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                return createCustomDialog();
434392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann            default:
435392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann                throw new IllegalArgumentException("Invalid dialogId: " + dialogId);
436392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann        }
437392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    }
438392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann
439392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann    protected abstract void requestFocusForFirstEditField();
4402fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4412fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    private class EditTypeAdapter extends ArrayAdapter<EditType> {
4422fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        private final LayoutInflater mInflater;
4432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        private boolean mHasCustomSelection;
44463ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan        private int mTextSize;
4452fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4462fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public EditTypeAdapter(Context context) {
4472fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            super(context, 0);
4482fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
44963ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            mTextSize = getResources().getDimensionPixelSize(
45063ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan                    R.dimen.editor_field_spinner_text_size);
4512fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4524fa9cd0088de76d83803210b39f373cd980fd846Dmitri Plotnikov            if (mType != null && mType.customColumn != null) {
4532fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4542fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                // Use custom label string when present
4552fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                final String customText = mEntry.getAsString(mType.customColumn);
4562fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                if (customText != null) {
4572fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                    add(CUSTOM_SELECTION);
4582fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                    mHasCustomSelection = true;
4592fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                }
4602fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            }
4612fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4622fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            addAll(EntityModifier.getValidTypes(mState, mKind, mType));
4632fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
4642fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4652fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public boolean hasCustomSelection() {
4662fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return mHasCustomSelection;
4672fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
4682fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4692fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        @Override
4702fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public View getView(int position, View convertView, ViewGroup parent) {
4712fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return createViewFromResource(
4722fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                    position, convertView, parent, android.R.layout.simple_spinner_item);
4732fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
4742fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4752fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        @Override
4762fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        public View getDropDownView(int position, View convertView, ViewGroup parent) {
4772fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return createViewFromResource(
4782fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                    position, convertView, parent, android.R.layout.simple_spinner_dropdown_item);
4792fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
4802fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4812fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        private View createViewFromResource(int position, View convertView, ViewGroup parent,
4822fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                int resource) {
4832fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            View view;
4842fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            TextView textView;
4852fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4862fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            if (convertView == null) {
4872fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                view = mInflater.inflate(resource, parent, false);
4882fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            } else {
4892fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                view = convertView;
4902fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            }
4912fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4922fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            textView = (TextView) view;
49363ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            textView.setTextSize(mTextSize);
4942fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov
4952fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            EditType type = getItem(position);
4962fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            String text;
4972fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            if (type == CUSTOM_SELECTION) {
4982fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                text = mEntry.getAsString(mType.customColumn);
4992fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            } else {
5002fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov                text = getContext().getString(type.labelRes);
5012fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            }
50263ffb90935d8aec295e4a8f62af6c77dafe1899fKatherine Kuan            textView.setText(text.toUpperCase());
5032fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov            return view;
5042fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov        }
5052fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov    }
506392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann}
507