SelectPopupDialog.java revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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
5package org.chromium.content.browser.input;
6
7import android.app.AlertDialog;
8import android.content.Context;
9import android.content.DialogInterface;
10import android.content.res.TypedArray;
11import android.util.SparseBooleanArray;
12import android.view.View;
13import android.widget.AdapterView;
14import android.widget.AdapterView.OnItemClickListener;
15import android.widget.ListView;
16
17import org.chromium.content.R;
18import org.chromium.content.browser.ContentViewCore;
19
20import java.util.List;
21
22/**
23 * Handles the popup dialog for the <select> HTML tag support.
24 */
25public 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
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
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
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
125    private void notifySelection(int[] indicies) {
126        if (mSelectionNotified) return;
127        mContentViewCore.selectPopupMenuItems(indicies);
128        mSelectionNotified = true;
129    }
130
131    @Override
132    public void show() {
133        mListBoxPopup.show();
134    }
135
136    @Override
137    public void hide() {
138        mListBoxPopup.cancel();
139        notifySelection(null);
140    }
141}
142