/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.googlecode.android_scripting.facade.ui; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.text.method.PasswordTransformationMethod; import android.widget.EditText; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.json.JSONArray; import org.json.JSONException; /** * Wrapper class for alert dialog running in separate thread. * */ class AlertDialogTask extends DialogTask { private final String mTitle; private final String mMessage; private final List mItems; private final Set mSelectedItems; private final Map mResultMap; private InputType mInputType; private int mEditInputType = 0; private String mPositiveButtonText; private String mNegativeButtonText; private String mNeutralButtonText; private EditText mEditText; private String mDefaultText; private enum InputType { DEFAULT, MENU, SINGLE_CHOICE, MULTI_CHOICE, PLAIN_TEXT, PASSWORD; } public AlertDialogTask(String title, String message) { mTitle = title; mMessage = message; mInputType = InputType.DEFAULT; mItems = new ArrayList(); mSelectedItems = new TreeSet(); mResultMap = new HashMap(); } public void setPositiveButtonText(String text) { mPositiveButtonText = text; } public void setNegativeButtonText(String text) { mNegativeButtonText = text; } public void setNeutralButtonText(String text) { mNeutralButtonText = text; } /** * Set list items. * * @param items */ public void setItems(JSONArray items) { mItems.clear(); for (int i = 0; i < items.length(); i++) { try { mItems.add(items.getString(i)); } catch (JSONException e) { throw new RuntimeException(e); } } mInputType = InputType.MENU; } /** * Set single choice items. * * @param items * a list of items as {@link String}s to display * @param selected * the index of the item that is selected by default */ public void setSingleChoiceItems(JSONArray items, int selected) { setItems(items); mSelectedItems.clear(); mSelectedItems.add(selected); mInputType = InputType.SINGLE_CHOICE; } /** * Set multi choice items. * * @param items * a list of items as {@link String}s to display * @param selected * a list of indices for items that should be selected by default * @throws JSONException */ public void setMultiChoiceItems(JSONArray items, JSONArray selected) throws JSONException { setItems(items); mSelectedItems.clear(); if (selected != null) { for (int i = 0; i < selected.length(); i++) { mSelectedItems.add(selected.getInt(i)); } } mInputType = InputType.MULTI_CHOICE; } /** * Returns the list of selected items. */ public Set getSelectedItems() { return mSelectedItems; } public void setTextInput(String defaultText) { mDefaultText = defaultText; mInputType = InputType.PLAIN_TEXT; setEditInputType("text"); } public void setEditInputType(String editInputType) { String[] list = editInputType.split("\\|"); Map types = ViewInflater.getInputTypes(); mEditInputType = 0; for (String flag : list) { Integer v = types.get(flag.trim()); if (v != null) { mEditInputType |= v; } } if (mEditInputType == 0) { mEditInputType = android.text.InputType.TYPE_CLASS_TEXT; } } public void setPasswordInput() { mInputType = InputType.PASSWORD; } @Override public void onCreate() { super.onCreate(); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); if (mTitle != null) { builder.setTitle(mTitle); } // Can't display both a message and items. We'll elect to show the items instead. if (mMessage != null && mItems.isEmpty()) { builder.setMessage(mMessage); } switch (mInputType) { // Add single choice menu items to dialog. case SINGLE_CHOICE: builder.setSingleChoiceItems(getItemsAsCharSequenceArray(), mSelectedItems.iterator().next(), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { mSelectedItems.clear(); mSelectedItems.add(item); } }); break; // Add multiple choice items to the dialog. case MULTI_CHOICE: boolean[] selectedItems = new boolean[mItems.size()]; for (int i : mSelectedItems) { selectedItems[i] = true; } builder.setMultiChoiceItems(getItemsAsCharSequenceArray(), selectedItems, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int item, boolean isChecked) { if (isChecked) { mSelectedItems.add(item); } else { mSelectedItems.remove(item); } } }); break; // Add standard, menu-like, items to dialog. case MENU: builder.setItems(getItemsAsCharSequenceArray(), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Map result = new HashMap(); result.put("item", item); dismissDialog(); setResult(result); } }); break; case PLAIN_TEXT: mEditText = new EditText(getActivity()); if (mDefaultText != null) { mEditText.setText(mDefaultText); } mEditText.setInputType(mEditInputType); builder.setView(mEditText); break; case PASSWORD: mEditText = new EditText(getActivity()); mEditText.setInputType(android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD); mEditText.setTransformationMethod(new PasswordTransformationMethod()); builder.setView(mEditText); break; default: // No input type specified. } configureButtons(builder, getActivity()); addOnCancelListener(builder, getActivity()); mDialog = builder.show(); mShowLatch.countDown(); } private CharSequence[] getItemsAsCharSequenceArray() { return mItems.toArray(new CharSequence[mItems.size()]); } private Builder addOnCancelListener(final AlertDialog.Builder builder, final Activity activity) { return builder.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { mResultMap.put("canceled", true); setResult(); } }); } private void configureButtons(final AlertDialog.Builder builder, final Activity activity) { DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { switch (which) { case DialogInterface.BUTTON_POSITIVE: mResultMap.put("which", "positive"); break; case DialogInterface.BUTTON_NEGATIVE: mResultMap.put("which", "negative"); break; case DialogInterface.BUTTON_NEUTRAL: mResultMap.put("which", "neutral"); break; } setResult(); } }; if (mNegativeButtonText != null) { builder.setNegativeButton(mNegativeButtonText, buttonListener); } if (mPositiveButtonText != null) { builder.setPositiveButton(mPositiveButtonText, buttonListener); } if (mNeutralButtonText != null) { builder.setNeutralButton(mNeutralButtonText, buttonListener); } } private void setResult() { dismissDialog(); if (mInputType == InputType.PLAIN_TEXT || mInputType == InputType.PASSWORD) { mResultMap.put("value", mEditText.getText().toString()); } setResult(mResultMap); } }