1 // Copyright 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.content.browser.input; 6 7 import android.app.AlertDialog; 8 import android.content.Context; 9 import android.content.DialogInterface; 10 import android.content.res.TypedArray; 11 import android.util.SparseBooleanArray; 12 import android.view.View; 13 import android.widget.AdapterView; 14 import android.widget.AdapterView.OnItemClickListener; 15 import android.widget.ListView; 16 17 import org.chromium.content.R; 18 import org.chromium.content.browser.ContentViewCore; 19 20 import java.util.List; 21 22 /** 23 * Handles the popup dialog for the <select> HTML tag support. 24 */ 25 public class SelectPopupDialog implements SelectPopup { 26 private static final int[] SELECT_DIALOG_ATTRS = { 27 R.attr.select_dialog_multichoice, 28 R.attr.select_dialog_singlechoice 29 }; 30 31 // The dialog hosting the popup list view. 32 private final AlertDialog mListBoxPopup; 33 private final ContentViewCore mContentViewCore; 34 private final Context mContext; 35 36 private boolean mSelectionNotified; 37 SelectPopupDialog(ContentViewCore contentViewCore, List<SelectPopupItem> items, boolean multiple, int[] selected)38 public SelectPopupDialog(ContentViewCore contentViewCore, List<SelectPopupItem> items, 39 boolean multiple, int[] selected) { 40 mContentViewCore = contentViewCore; 41 mContext = mContentViewCore.getContext(); 42 43 final ListView listView = new ListView(mContext); 44 listView.setCacheColorHint(0); 45 AlertDialog.Builder b = new AlertDialog.Builder(mContext) 46 .setView(listView) 47 .setCancelable(true) 48 .setInverseBackgroundForced(true); 49 50 if (multiple) { 51 b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 52 @Override 53 public void onClick(DialogInterface dialog, int which) { 54 notifySelection(getSelectedIndices(listView)); 55 } 56 }); 57 b.setNegativeButton(android.R.string.cancel, 58 new DialogInterface.OnClickListener() { 59 @Override 60 public void onClick(DialogInterface dialog, int which) { 61 notifySelection(null); 62 } 63 }); 64 } 65 mListBoxPopup = b.create(); 66 final SelectPopupAdapter adapter = new SelectPopupAdapter( 67 mContext, getSelectDialogLayout(multiple), items); 68 listView.setAdapter(adapter); 69 listView.setFocusableInTouchMode(true); 70 71 if (multiple) { 72 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 73 for (int i = 0; i < selected.length; ++i) { 74 listView.setItemChecked(selected[i], true); 75 } 76 } else { 77 listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 78 listView.setOnItemClickListener(new OnItemClickListener() { 79 @Override 80 public void onItemClick(AdapterView<?> parent, View v, 81 int position, long id) { 82 notifySelection(getSelectedIndices(listView)); 83 mListBoxPopup.dismiss(); 84 } 85 }); 86 if (selected.length > 0) { 87 listView.setSelection(selected[0]); 88 listView.setItemChecked(selected[0], true); 89 } 90 } 91 mListBoxPopup.setOnCancelListener(new DialogInterface.OnCancelListener() { 92 @Override 93 public void onCancel(DialogInterface dialog) { 94 notifySelection(null); 95 } 96 }); 97 } 98 getSelectDialogLayout(boolean isMultiChoice)99 private int getSelectDialogLayout(boolean isMultiChoice) { 100 int resourceId; 101 TypedArray styledAttributes = mContext.obtainStyledAttributes( 102 R.style.SelectPopupDialog, SELECT_DIALOG_ATTRS); 103 resourceId = styledAttributes.getResourceId(isMultiChoice ? 0 : 1, 0); 104 styledAttributes.recycle(); 105 return resourceId; 106 } 107 getSelectedIndices(ListView listView)108 private static int[] getSelectedIndices(ListView listView) { 109 SparseBooleanArray sparseArray = listView.getCheckedItemPositions(); 110 int selectedCount = 0; 111 for (int i = 0; i < sparseArray.size(); ++i) { 112 if (sparseArray.valueAt(i)) { 113 selectedCount++; 114 } 115 } 116 int[] indices = new int[selectedCount]; 117 for (int i = 0, j = 0; i < sparseArray.size(); ++i) { 118 if (sparseArray.valueAt(i)) { 119 indices[j++] = sparseArray.keyAt(i); 120 } 121 } 122 return indices; 123 } 124 notifySelection(int[] indicies)125 private void notifySelection(int[] indicies) { 126 if (mSelectionNotified) return; 127 mContentViewCore.selectPopupMenuItems(indicies); 128 mSelectionNotified = true; 129 } 130 131 @Override show()132 public void show() { 133 mListBoxPopup.show(); 134 } 135 136 @Override hide()137 public void hide() { 138 mListBoxPopup.cancel(); 139 notifySelection(null); 140 } 141 } 142