LabeledEditorView.java revision 91d8e892d549bbeba721cb434163a83bc99330a9
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.DataKind; 224597c92d655d45447780b32c7572acef110b6ed1Dmitri Plotnikovimport com.android.contacts.model.AccountType.EditType; 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; 282fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport com.android.contacts.util.ThemeUtils; 29392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 30392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.app.AlertDialog; 31392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.app.Dialog; 32392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Context; 33392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.DialogInterface; 34392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.Entity; 35392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.content.res.Resources; 36392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.os.Bundle; 3779c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmannimport android.os.Handler; 38392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.util.AttributeSet; 392fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.view.LayoutInflater; 40392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.View; 41392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.ViewGroup; 42392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.view.inputmethod.EditorInfo; 432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.AdapterView; 442fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.AdapterView.OnItemSelectedListener; 452fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.ArrayAdapter; 46392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.EditText; 47392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannimport android.widget.ImageButton; 482fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.Spinner; 492fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikovimport android.widget.TextView; 50392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 5114918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikovimport java.util.List; 5214918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov 53392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann/** 54392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Base class for editors that handles labels and values. 55392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Uses {@link ValuesDelta} to read any existing 56392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * {@link Entity} values, and to correctly write any changes values. 57392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 58392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmannpublic abstract class LabeledEditorView extends ViewGroup 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 652fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private Spinner mLabel; 662fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private EditTypeAdapter mEditTypeAdapter; 67392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private ImageButton mDelete; 68392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 69392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private DataKind mKind; 70392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private ValuesDelta mEntry; 71392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private EntityDelta mState; 72392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private boolean mReadOnly; 73392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 74392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private EditType mType; 75392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 76392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private ViewIdGenerator mViewIdGenerator; 77392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private DialogManager mDialogManager = null; 78392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private EditorListener mListener; 7991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov protected int mMinLineItemHeight; 80392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 812fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov /** 822fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov * A marker in the spinner adapter of the currently selected custom type. 832fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov */ 842fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public static final EditType CUSTOM_SELECTION = new EditType(0, 0); 852fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 862fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private OnItemSelectedListener mSpinnerListener = new OnItemSelectedListener() { 872fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 882fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov @Override 892fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public void onItemSelected( 902fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov AdapterView<?> parent, View view, int position, long id) { 912fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov onTypeSelectionChange(position); 922fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 932fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 942fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov @Override 952fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public void onNothingSelected(AdapterView<?> parent) { 962fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 972fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov }; 982fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 99392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public LabeledEditorView(Context context) { 100392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context); 10191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov init(context); 102392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 103392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 104392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public LabeledEditorView(Context context, AttributeSet attrs) { 105392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context, attrs); 10691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov init(context); 107392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 108392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 109392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public LabeledEditorView(Context context, AttributeSet attrs, int defStyle) { 110392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann super(context, attrs, defStyle); 11191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov init(context); 11291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 11391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 11491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov private void init(Context context) { 11591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov mMinLineItemHeight = context.getResources().getDimensionPixelSize( 11691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov R.dimen.editor_min_line_item_height); 117392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 118392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 11902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov public boolean isReadOnly() { 12002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov return mReadOnly; 12102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov } 12202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov 12391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov public int getBaseline(int row) { 12491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov if (row == 0 && mLabel != null) { 12591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov return mLabel.getBaseline(); 12691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 12791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov return -1; 12891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 12991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 13091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov /** 13191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov * Returns the number of rows in this editor, including the invisible ones. 13291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov */ 13391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov protected int getLineItemCount() { 13491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov return 1; 13591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 13691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 13791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov protected boolean isLineItemVisible(int row) { 13891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov return true; 13991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 14091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 14191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov protected int getLineItemHeight(int row) { 14291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int fieldHeight = 0; 14391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int buttonHeight = 0; 14491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov if (row == 0) { 14591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov // summarize the EditText heights 14691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov if (mLabel != null) { 14791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov fieldHeight = mLabel.getMeasuredHeight(); 14891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 14991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 15091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov // Ensure there is enough space for the minus button 15191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov View deleteButton = getDelete(); 15291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov final int deleteHeight = (deleteButton != null) ? deleteButton.getMeasuredHeight() : 0; 15391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov buttonHeight += deleteHeight; 15491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 15591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 15691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov return Math.max(Math.max(buttonHeight, fieldHeight), mMinLineItemHeight); 15791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 15891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 15991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov @Override 16091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 16191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov measureChildren(widthMeasureSpec, heightMeasureSpec); 16291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 16391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int height = 0; 16491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov height += getPaddingTop() + getPaddingBottom(); 16591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 16691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int count = getLineItemCount(); 16791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov for (int i = 0; i < count; i++) { 16891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov if (isLineItemVisible(i)) { 16991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov height += getLineItemHeight(i); 17091d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 17191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 17291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 17391d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), 17491d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov resolveSize(height, heightMeasureSpec)); 17591d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov } 17691d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov 177392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 178392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void onLayout(boolean changed, int l, int t, int r, int b) { 179392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Subtract padding from the borders ==> x1 variables 180392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int t1 = getPaddingTop(); 181392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int r1 = getMeasuredWidth() - getPaddingRight(); 182392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int b1 = getMeasuredHeight() - getPaddingBottom(); 183392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 184cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann final int r2; 185cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann if (mDelete != null) { 186cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann r2 = r1 - mDelete.getMeasuredWidth(); 18791d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov // Vertically center the delete button in the first line item 18891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int height = mDelete.getMeasuredHeight(); 18991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int top = t1 + (mMinLineItemHeight - height) / 2; 190cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann mDelete.layout( 19191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov r2, top, 19291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov r1, top + height); 193cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann } else { 194cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann r2 = r1; 195cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann } 196392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 197cfb525b3f18d71d6cc5d4ef36d704b3ba9e9a6f3Daniel Lehmann if (mLabel != null) { 19891d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int baseline = getBaseline(0); 19991d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov int y = t1 + baseline - mLabel.getBaseline(); 200392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mLabel.layout( 20191d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov r2 - mLabel.getMeasuredWidth(), y, 20291d8e892d549bbeba721cb434163a83bc99330a9Dmitri Plotnikov r2, y + mLabel.getMeasuredHeight()); 203392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 204392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 205392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 206392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 207392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Creates or removes the type/label button. Doesn't do anything if already correctly configured 208392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 209392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private void setupLabelButton(boolean shouldExist) { 210392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (shouldExist && mLabel == null) { 2112fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mLabel = new Spinner(mContext); 212392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final int width = 213392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mContext.getResources().getDimensionPixelSize(R.dimen.editor_type_label_width); 214392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mLabel.setLayoutParams(new LayoutParams(width, LayoutParams.WRAP_CONTENT)); 2152fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mLabel.setOnItemSelectedListener(mSpinnerListener); 21602bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mLabel.setEnabled(!mReadOnly && isEnabled()); 217392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann addView(mLabel); 218392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } else if (!shouldExist && mLabel != null) { 219392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann removeView(mLabel); 220392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mLabel = null; 221392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 222392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 223392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 224392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 225392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Creates or removes the remove button. Doesn't do anything if already correctly configured 226392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 227392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private void setupDeleteButton(boolean shouldExist) { 228392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (shouldExist && mDelete == null) { 229392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete = new ImageButton(mContext); 230915ffc5ae1d10a7ed06d5541fe81da023fa3228fDaniel Lehmann mDelete.setImageResource(R.drawable.ic_menu_remove_field_holo_light); 23179c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann mDelete.setBackgroundResource( 23279c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann ThemeUtils.getSelectableItemBackground(mContext.getTheme())); 233392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final Resources resources = mContext.getResources(); 234392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete.setPadding( 235392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann resources.getDimensionPixelOffset(R.dimen.editor_round_button_padding_left), 236392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann resources.getDimensionPixelOffset(R.dimen.editor_round_button_padding_top), 237392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann resources.getDimensionPixelOffset(R.dimen.editor_round_button_padding_right), 238392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann resources.getDimensionPixelOffset(R.dimen.editor_round_button_padding_bottom)); 239392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete.setContentDescription( 240392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann getResources().getText(R.string.description_minus_button)); 241392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete.setLayoutParams( 242392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 243392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete.setOnClickListener(new OnClickListener() { 244392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 245392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void onClick(View v) { 24679c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann // defer removal of this button so that the pressed state is visible shortly 24779c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann new Handler().post(new Runnable() { 24879c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann @Override 24979c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann public void run() { 25079c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann // Keep around in model, but mark as deleted 25179c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann mEntry.markDeleted(); 25279c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann 25379c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann ((ViewGroup) getParent()).removeView(LabeledEditorView.this); 25479c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann 25579c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann if (mListener != null) { 25679c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann // Notify listener when present 25779c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann mListener.onDeleted(LabeledEditorView.this); 25879c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann } 25979c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann } 26079c9c5a8f849908d2b141c30af15923ea2b60f5bDaniel Lehmann }); 261392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 262392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann }); 26302bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov mDelete.setEnabled(!mReadOnly && isEnabled()); 264392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann addView(mDelete); 265392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } else if (!shouldExist && mDelete != null) { 266392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann removeView(mDelete); 267392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDelete = null; 268392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 269392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 270392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 271392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void onOptionalFieldVisibilityChange() { 272392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mListener != null) { 273392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mListener.onRequest(EditorListener.EDITOR_FORM_CHANGED); 274392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 275392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 276392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 277392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 278392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setEditorListener(EditorListener listener) { 279392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mListener = listener; 280392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 281392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 282392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 283392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setDeletable(boolean deletable) { 284392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setupDeleteButton(deletable); 285392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 286392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 287392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 288392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setEnabled(boolean enabled) { 28902bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov super.setEnabled(enabled); 29002bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mLabel != null) mLabel.setEnabled(!mReadOnly && enabled); 29102bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mDelete != null) mDelete.setEnabled(!mReadOnly && enabled); 292392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 293392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 2942fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public Spinner getLabel() { 295392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mLabel; 296392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 297392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 298392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public ImageButton getDelete() { 299392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mDelete; 300392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 301392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 302392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected DataKind getKind() { 303392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mKind; 304392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 305392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 306392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected ValuesDelta getEntry() { 307392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mEntry; 308392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 309392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 310392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected EditType getType() { 311392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mType; 312392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 313392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 314392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 315392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Build the current label state based on selected {@link EditType} and 316392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * possible custom label string. 317392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 318392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private void rebuildLabel() { 319392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mLabel == null) return; 3202fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mEditTypeAdapter = new EditTypeAdapter(mContext); 3212fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mLabel.setAdapter(mEditTypeAdapter); 3222fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (mEditTypeAdapter.hasCustomSelection()) { 3232fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mLabel.setSelection(mEditTypeAdapter.getPosition(CUSTOM_SELECTION)); 3242fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } else { 3252fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mLabel.setSelection(mEditTypeAdapter.getPosition(mType)); 326392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 327392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 328392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 329392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** {@inheritDoc} */ 330392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 331392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void onFieldChanged(String column, String value) { 3327d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov String oldValue = mEntry.getAsString(column); 3337d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov if (oldValue == null && value.equals("") || oldValue != null && oldValue.equals(value)) { 3347d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov return; 3357d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov } 3367d4a8dda946f5c013573e4d6601fc14c03156ba6Dmitri Plotnikov 337392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Field changes are saved directly 338392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mEntry.put(column, value); 339392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mListener != null) { 340392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mListener.onRequest(EditorListener.FIELD_CHANGED); 341392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 342392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 343392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 344392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void rebuildValues() { 345392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setValues(mKind, mEntry, mState, mReadOnly, mViewIdGenerator); 346392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 347392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 348392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 349392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Prepare this editor using the given {@link DataKind} for defining 350392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * structure and {@link ValuesDelta} describing the content to edit. 351392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 352392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 353392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void setValues(DataKind kind, ValuesDelta entry, EntityDelta state, boolean readOnly, 354392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann ViewIdGenerator vig) { 355392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mKind = kind; 356392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mEntry = entry; 357392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mState = state; 358392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mReadOnly = readOnly; 359392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mViewIdGenerator = vig; 360392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setId(vig.getId(state, kind, entry, ViewIdGenerator.NO_VIEW_INDEX)); 361392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 362392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (!entry.isVisible()) { 363392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Hide ourselves entirely if deleted 364392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setVisibility(View.GONE); 365392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return; 366392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 367392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setVisibility(View.VISIBLE); 368392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 369392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann // Display label selector if multiple types available 370392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final boolean hasTypes = EntityModifier.hasEditTypes(kind); 371392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann setupLabelButton(hasTypes); 37202bb1252aa990813fa9e86ad75c458acc15e6801Dmitri Plotnikov if (mLabel != null) mLabel.setEnabled(!readOnly && isEnabled()); 373392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (hasTypes) { 374392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mType = EntityModifier.getCurrentType(entry, kind); 375392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann rebuildLabel(); 376392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 377392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 378392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 379392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public ValuesDelta getValues() { 380392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mEntry; 381392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 382392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 383392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 384392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Prepare dialog for entering a custom label. The input value is trimmed: white spaces before 385392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * and after the input text is removed. 386392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * <p> 387392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * If the final value is empty, this change request is ignored; 388392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * no empty text is allowed in any custom label. 389392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 390392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private Dialog createCustomDialog() { 391392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final EditText customType = new EditText(mContext); 392392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann customType.setInputType(INPUT_TYPE_CUSTOM); 39314918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov customType.setSaveEnabled(true); 394392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann customType.requestFocus(); 395392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 396392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final AlertDialog.Builder builder = new AlertDialog.Builder(mContext); 397392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann builder.setTitle(R.string.customLabelPickerTitle); 398392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann builder.setView(customType); 399392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 400392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 401392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 402392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public void onClick(DialogInterface dialog, int which) { 403392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann final String customText = customType.getText().toString().trim(); 404392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (ContactsUtils.isGraphic(customText)) { 40514918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov final List<EditType> allTypes = 40614918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov EntityModifier.getValidTypes(mState, mKind, null); 40714918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov mType = null; 40814918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov for (EditType editType : allTypes) { 40914918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov if (editType.customColumn != null) { 41014918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov mType = editType; 41114918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov break; 41214918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov } 41314918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov } 41414918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov if (mType == null) return; 41514918c07e1cb3b5b190bec4cc9106db7adbba29fDmitri Plotnikov 416392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mEntry.put(mKind.typeColumn, mType.rawValue); 417392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mEntry.put(mType.customColumn, customText); 418392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann rebuildLabel(); 419392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann requestFocusForFirstEditField(); 420392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann onLabelRebuilt(); 421392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 422392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 423392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann }); 424392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 425392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann builder.setNegativeButton(android.R.string.cancel, null); 426392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 427392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return builder.create(); 428392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 429392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 430392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /** 431392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann * Called after the label has changed (either chosen from the list or entered in the Dialog) 432392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann */ 433392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected void onLabelRebuilt() { 434392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 435392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 4362fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov protected void onTypeSelectionChange(int position) { 4372fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov EditType selected = mEditTypeAdapter.getItem(position); 4382fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov // See if the selection has in fact changed 4392fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (mEditTypeAdapter.hasCustomSelection() && selected == CUSTOM_SELECTION) { 4402fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return; 441392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 442392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 4432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (mType == selected && mType.customColumn == null) { 4442fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return; 4452fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 446392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 4472fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (selected.customColumn != null) { 4482fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov showDialog(DIALOG_ID_CUSTOM); 4492fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } else { 4502fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov // User picked type, and we're sure it's ok to actually write the entry. 4512fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mType = selected; 4522fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mEntry.put(mKind.typeColumn, mType.rawValue); 4532fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov rebuildLabel(); 4542fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov requestFocusForFirstEditField(); 4552fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov onLabelRebuilt(); 4562fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 457392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 458392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 459392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann /* package */ 460392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann void showDialog(int bundleDialogId) { 461392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann Bundle bundle = new Bundle(); 462392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann bundle.putInt(DIALOG_ID_KEY, bundleDialogId); 463392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann getDialogManager().showDialogInView(this, bundle); 464392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 465392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 466392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann private DialogManager getDialogManager() { 467392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (mDialogManager == null) { 468392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann Context context = getContext(); 469392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (!(context instanceof DialogManager.DialogShowingViewActivity)) { 470392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann throw new IllegalStateException( 471392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann "View must be hosted in an Activity that implements " + 472392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann "DialogManager.DialogShowingViewActivity"); 473392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 474392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann mDialogManager = ((DialogManager.DialogShowingViewActivity)context).getDialogManager(); 475392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 476392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return mDialogManager; 477392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 478392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 479392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann @Override 480392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann public Dialog createDialog(Bundle bundle) { 481392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann if (bundle == null) throw new IllegalArgumentException("bundle must not be null"); 482392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann int dialogId = bundle.getInt(DIALOG_ID_KEY); 483392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann switch (dialogId) { 484392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann case DIALOG_ID_CUSTOM: 485392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann return createCustomDialog(); 486392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann default: 487392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann throw new IllegalArgumentException("Invalid dialogId: " + dialogId); 488392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 489392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann } 490392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann 491392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann protected abstract void requestFocusForFirstEditField(); 4922fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 4932fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private class EditTypeAdapter extends ArrayAdapter<EditType> { 4942fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private final LayoutInflater mInflater; 4952fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private boolean mHasCustomSelection; 4962fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 4972fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public EditTypeAdapter(Context context) { 4982fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov super(context, 0); 4992fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 5002fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5012fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (mType.customColumn != null) { 5022fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5032fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov // Use custom label string when present 5042fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov final String customText = mEntry.getAsString(mType.customColumn); 5052fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (customText != null) { 5062fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov add(CUSTOM_SELECTION); 5072fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov mHasCustomSelection = true; 5082fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5092fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5102fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5112fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov addAll(EntityModifier.getValidTypes(mState, mKind, mType)); 5122fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5132fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5142fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public boolean hasCustomSelection() { 5152fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return mHasCustomSelection; 5162fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5172fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5182fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov @Override 5192fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public View getView(int position, View convertView, ViewGroup parent) { 5202fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return createViewFromResource( 5212fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov position, convertView, parent, android.R.layout.simple_spinner_item); 5222fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5232fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5242fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov @Override 5252fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov public View getDropDownView(int position, View convertView, ViewGroup parent) { 5262fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return createViewFromResource( 5272fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov position, convertView, parent, android.R.layout.simple_spinner_dropdown_item); 5282fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5292fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5302fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov private View createViewFromResource(int position, View convertView, ViewGroup parent, 5312fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov int resource) { 5322fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov View view; 5332fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov TextView textView; 5342fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5352fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (convertView == null) { 5362fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov view = mInflater.inflate(resource, parent, false); 5372fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } else { 5382fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov view = convertView; 5392fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5402fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5412fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov textView = (TextView) view; 5422fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov 5432fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov EditType type = getItem(position); 5442fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov String text; 5452fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov if (type == CUSTOM_SELECTION) { 5462fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov text = mEntry.getAsString(mType.customColumn); 5472fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } else { 5482fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov text = getContext().getString(type.labelRes); 5492fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5502fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov textView.setText(text); 5512fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov return view; 5522fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 5532fcfa499dd44f62dc63636e363522354e13aa20dDmitri Plotnikov } 554392ccec3b56e8074a5a028af28106134b39f64bcDaniel Lehmann} 555