Bug 920170 - Break out some pieces of prompts into their own methods. r=margaret
authorWes Johnston <wjohnston@mozilla.com>
Tue, 15 Oct 2013 00:11:27 -0700
changeset 164645 c5cc4233220fc27b0660fdf3c125482be0f06291
parent 164549 23bd0deec3597094677bf4865fa129e178c31013
child 164646 7b367ca427b63d7530dd69c62112dbee2dc7cae1
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmargaret
bugs920170
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 920170 - Break out some pieces of prompts into their own methods. r=margaret
mobile/android/base/prompts/Prompt.java
--- a/mobile/android/base/prompts/Prompt.java
+++ b/mobile/android/base/prompts/Prompt.java
@@ -30,16 +30,17 @@ import android.text.InputType;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.CheckBox;
 import android.widget.CheckedTextView;
 import android.widget.DatePicker;
 import android.widget.EditText;
 import android.widget.LinearLayout;
@@ -111,99 +112,40 @@ public class Prompt implements OnClickLi
         view.setPadding(mInputPaddingSize, 0, mInputPaddingSize, 0);
         return view;
     }
 
     public void show(JSONObject message) {
         processMessage(message);
     }
 
-    public void show(String aTitle, String aText, PromptListItem[] aMenuList, boolean aMultipleSelection) {
+    public void show(String title, String text, PromptListItem[] listItems, boolean multipleSelection) {
         ThreadUtils.assertOnUiThread();
 
         GeckoAppShell.getLayerView().abortPanning();
 
         AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
-        if (!TextUtils.isEmpty(aTitle)) {
-            builder.setTitle(aTitle);
+        if (!TextUtils.isEmpty(title)) {
+            builder.setTitle(title);
         }
 
-        if (!TextUtils.isEmpty(aText)) {
-            builder.setMessage(aText);
+        if (!TextUtils.isEmpty(text)) {
+            builder.setMessage(text);
         }
 
-        int length = mInputs == null ? 0 : mInputs.length;
-        if (aMenuList != null && aMenuList.length > 0) {
-            int resourceId = android.R.layout.simple_list_item_1;
-            if (mSelected != null && mSelected.length > 0) {
-                if (aMultipleSelection) {
-                    resourceId = R.layout.select_dialog_multichoice;
-                } else {
-                    resourceId = R.layout.select_dialog_singlechoice;
-                }
-            }
-            PromptListAdapter adapter = new PromptListAdapter(mContext, resourceId, aMenuList);
-            if (mSelected != null && mSelected.length > 0) {
-                if (aMultipleSelection) {
-                    adapter.listView = (ListView) mInflater.inflate(R.layout.select_dialog_list, null);
-                    adapter.listView.setOnItemClickListener(this);
-                    builder.setInverseBackgroundForced(true);
-                    adapter.listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
-                    adapter.listView.setAdapter(adapter);
-                    builder.setView(adapter.listView);
-                } else {
-                    int selectedIndex = -1;
-                    for (int i = 0; i < mSelected.length; i++) {
-                        if (mSelected[i]) {
-                            selectedIndex = i;
-                            break;
-                        }
-                    }
-                    mSelected = null;
-                    builder.setSingleChoiceItems(adapter, selectedIndex, this);
-                }
-            } else {
-                builder.setAdapter(adapter, this);
-                mSelected = null;
-            }
-        } else if (length == 1) {
-            try {
-                ScrollView view = new ScrollView(mContext);
-                view.addView(mInputs[0].getView(mContext));
-                builder.setView(applyInputStyle(view));
-            } catch(UnsupportedOperationException ex) {
-                // We cannot display these input widgets with this sdk version,
-                // do not display any dialog and finish the prompt now.
-                try {
-                    finishDialog(new JSONObject("{\"button\": -1}"));
-                } catch(JSONException e) { }
-                return;
-            }
-        } else if (length > 1) {
-            try {
-                LinearLayout linearLayout = new LinearLayout(mContext);
-                linearLayout.setOrientation(LinearLayout.VERTICAL);
-                for (int i = 0; i < length; i++) {
-                    View content = mInputs[i].getView(mContext);
-                    linearLayout.addView(content);
-                }
-                ScrollView view = new ScrollView(mContext);
-                view.addView(linearLayout);
-                builder.setView(applyInputStyle(view));
-            } catch(UnsupportedOperationException ex) {
-                // We cannot display these input widgets with this sdk version,
-                // do not display any dialog and finish the prompt now.
-                try {
-                    finishDialog(new JSONObject("{\"button\": -1}"));
-                } catch(JSONException e) { }
-                return;
-            }
+        // Because lists are currently added through the normal Android AlertBuilder interface, they're
+        // incompatible with also adding additional input elements to a dialog.
+        if (listItems != null && listItems.length > 0) {
+            addlistItems(builder, listItems, multipleSelection);
+        } else if (!addInputs(builder)) {
+            // If we failed to add any requested input elements, don't show the dialog
+            return;
         }
 
-        length = mButtons == null ? 0 : mButtons.length;
+        int length = mButtons == null ? 0 : mButtons.length;
         if (length > 0) {
             builder.setPositiveButton(mButtons[0], this);
             if (length > 1) {
                 builder.setNeutralButton(mButtons[1], this);
                 if (length > 2) {
                     builder.setNegativeButton(mButtons[2], this);
                 }
             }
@@ -259,16 +201,138 @@ public class Prompt implements OnClickLi
 
         if (mDialog != null) {
             mDialog.dismiss();
         }
 
         finishDialog(ret);
     }
 
+    /* Adds a set of list items to the prompt. This can be used for either context menu type dialogs, checked lists,
+     * or multiple selection lists. If mSelected is set in the prompt before addlistItems is called, the items will be
+     * shown with "checkmarks" on their left side.
+     *
+     * @param builder
+     *        The alert builder currently building this dialog.
+     * @param listItems
+     *        The items to add.
+     * @param multipleSelection
+     *        If true, and mSelected is defined to be a non-zero-length list, the list will show checkmarks on the
+     *        left and allow multiple selection. 
+    */
+    private void addlistItems(AlertDialog.Builder builder, PromptListItem[] listItems, boolean multipleSelection) {
+        if (mSelected != null && mSelected.length > 0) {
+            if (multipleSelection) {
+                addMultiSelectList(builder, listItems);
+            } else {
+                addSingleSelectList(builder, listItems);
+            }
+        } else {
+            addMenuList(builder, listItems);
+        }
+    }
+
+    /* Shows a multi-select list with checkmarks on the side. Android doesn't support using an adapter for
+     * multi-choice lists by default so instead we insert our own custom list so that we can do fancy things
+     * to the rows like disabling/indenting them.
+     *
+     * @param builder
+     *        The alert builder currently building this dialog.
+     * @param listItems
+     *        The items to add.
+     */
+    private void addMultiSelectList(AlertDialog.Builder builder, PromptListItem[] listItems) {
+        PromptListAdapter adapter = new PromptListAdapter(mContext, R.layout.select_dialog_multichoice, listItems);
+        adapter.listView = (ListView) mInflater.inflate(R.layout.select_dialog_list, null);
+        adapter.listView.setOnItemClickListener(this);
+        builder.setInverseBackgroundForced(true);
+        adapter.listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        adapter.listView.setAdapter(adapter);
+        builder.setView(adapter.listView);
+    }
+
+    /* Shows a single-select list with radio boxes on the side.
+     *
+     * @param builder
+     *        the alert builder currently building this dialog.
+     * @param listItems
+     *        The items to add.
+     */
+    private void addSingleSelectList(AlertDialog.Builder builder, PromptListItem[] listItems) {
+        PromptListAdapter adapter = new PromptListAdapter(mContext, R.layout.select_dialog_singlechoice, listItems);
+        // For single select, we only maintain a single index of the selected row
+        int selectedIndex = -1;
+        for (int i = 0; i < mSelected.length; i++) {
+            if (mSelected[i]) {
+                selectedIndex = i;
+                break;
+            }
+        }
+        mSelected = null;
+
+        builder.setSingleChoiceItems(adapter, selectedIndex, this);
+    }
+
+    /* Shows a single-select list.
+     *
+     * @param builder
+     *        the alert builder currently building this dialog.
+     * @param listItems
+     *        The items to add.
+     */
+    private void addMenuList(AlertDialog.Builder builder, PromptListItem[] listItems) {
+        PromptListAdapter adapter = new PromptListAdapter(mContext, android.R.layout.simple_list_item_1, listItems);
+        builder.setAdapter(adapter, this);
+        mSelected = null;
+    }
+
+    /* Add the requested input elements to the dialog.
+     *
+     * @param builder
+     *        the alert builder currently building this dialog.
+     * @return
+     *        returns true if the inputs were added successfully. They may fail
+     *        if the requested input is incompatible with this Android version
+     */
+    private boolean addInputs(AlertDialog.Builder builder) {
+        int length = mInputs == null ? 0 : mInputs.length;
+        if (length == 0) {
+            return true;
+        }
+
+        try {
+            if (length == 1) {
+                ScrollView view = new ScrollView(mContext);
+                view.addView(mInputs[0].getView(mContext));
+                builder.setView(applyInputStyle(view));
+            } else if (length > 1) {
+                LinearLayout linearLayout = new LinearLayout(mContext);
+                linearLayout.setOrientation(LinearLayout.VERTICAL);
+                for (int i = 0; i < length; i++) {
+                    View content = mInputs[i].getView(mContext);
+                    linearLayout.addView(content);
+                }
+                ScrollView view = new ScrollView(mContext);
+                view.addView(linearLayout);
+                builder.setView(applyInputStyle(view));
+            }
+        } catch(Exception ex) {
+            Log.e(LOGTAG, "Error showing prompt inputs", ex);
+            // We cannot display these input widgets with this sdk version,
+            // do not display any dialog and finish the prompt now.
+            try {
+                finishDialog(new JSONObject("{\"button\": -1}"));
+            } catch(JSONException e) { }
+
+            return false;
+        }
+
+        return true;
+    }
+
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         ThreadUtils.assertOnUiThread();
         mSelected[position] = !mSelected[position];
     }
 
     @Override
     public void onCancel(DialogInterface aDialog) {