1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 package org.mozilla.gecko; 7 8 import java.util.ArrayList; 9 import java.util.List; 10 11 import org.mozilla.gecko.db.RemoteClient; 12 13 import android.app.AlertDialog; 14 import android.app.AlertDialog.Builder; 15 import android.app.Dialog; 16 import android.content.DialogInterface; 17 import android.os.Bundle; 18 import android.support.v4.app.DialogFragment; 19 import android.support.v4.app.Fragment; 20 import android.util.SparseBooleanArray; 21 22 /** 23 * A dialog fragment that displays a list of remote clients. 24 * <p> 25 * The dialog allows both single (one tap) and multiple (checkbox) selection. 26 * The dialog's results are communicated via the {@link RemoteClientsListener} 27 * interface. Either the dialog fragment's <i>target fragment</i> (see 28 * {@link Fragment#setTargetFragment(Fragment, int)}), or the containing 29 * <i>activity</i>, must implement that interface. See 30 * {@link #notifyListener(List)} for details. 31 */ 32 public class RemoteClientsDialogFragment extends DialogFragment { 33 private static final String KEY_TITLE = "title"; 34 private static final String KEY_CHOICE_MODE = "choice_mode"; 35 private static final String KEY_POSITIVE_BUTTON_TEXT = "positive_button_text"; 36 private static final String KEY_CLIENTS = "clients"; 37 38 public interface RemoteClientsListener { 39 // Always called on the main UI thread. onClients(List<RemoteClient> clients)40 public void onClients(List<RemoteClient> clients); 41 } 42 43 public enum ChoiceMode { 44 SINGLE, 45 MULTIPLE, 46 } 47 newInstance(String title, String positiveButtonText, ChoiceMode choiceMode, ArrayList<RemoteClient> clients)48 public static RemoteClientsDialogFragment newInstance(String title, String positiveButtonText, ChoiceMode choiceMode, ArrayList<RemoteClient> clients) { 49 final RemoteClientsDialogFragment dialog = new RemoteClientsDialogFragment(); 50 final Bundle args = new Bundle(); 51 args.putString(KEY_TITLE, title); 52 args.putString(KEY_POSITIVE_BUTTON_TEXT, positiveButtonText); 53 args.putInt(KEY_CHOICE_MODE, choiceMode.ordinal()); 54 args.putParcelableArrayList(KEY_CLIENTS, clients); 55 dialog.setArguments(args); 56 return dialog; 57 } 58 RemoteClientsDialogFragment()59 public RemoteClientsDialogFragment() { 60 // Empty constructor is required for DialogFragment. 61 } 62 63 @Override onDestroy()64 public void onDestroy() { 65 super.onDestroy(); 66 67 GeckoApplication.watchReference(getActivity(), this); 68 } 69 notifyListener(List<RemoteClient> clients)70 protected void notifyListener(List<RemoteClient> clients) { 71 RemoteClientsListener listener; 72 try { 73 listener = (RemoteClientsListener) getTargetFragment(); 74 } catch (ClassCastException e) { 75 try { 76 listener = (RemoteClientsListener) getActivity(); 77 } catch (ClassCastException f) { 78 throw new ClassCastException(getTargetFragment() + " or " + getActivity() 79 + " must implement RemoteClientsListener"); 80 } 81 } 82 listener.onClients(clients); 83 } 84 85 @Override onCreateDialog(Bundle savedInstanceState)86 public Dialog onCreateDialog(Bundle savedInstanceState) { 87 final String title = getArguments().getString(KEY_TITLE); 88 final String positiveButtonText = getArguments().getString(KEY_POSITIVE_BUTTON_TEXT); 89 final ChoiceMode choiceMode = ChoiceMode.values()[getArguments().getInt(KEY_CHOICE_MODE)]; 90 final ArrayList<RemoteClient> clients = getArguments().getParcelableArrayList(KEY_CLIENTS); 91 92 final Builder builder = new AlertDialog.Builder(getActivity()); 93 builder.setTitle(title); 94 95 final String[] clientNames = new String[clients.size()]; 96 for (int i = 0; i < clients.size(); i++) { 97 clientNames[i] = clients.get(i).name; 98 } 99 100 if (choiceMode == ChoiceMode.MULTIPLE) { 101 builder.setMultiChoiceItems(clientNames, null, null); 102 builder.setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { 103 @Override 104 public void onClick(DialogInterface dialogInterface, int which) { 105 if (which != Dialog.BUTTON_POSITIVE) { 106 return; 107 } 108 109 final AlertDialog dialog = (AlertDialog) dialogInterface; 110 final SparseBooleanArray checkedItemPositions = dialog.getListView().getCheckedItemPositions(); 111 final ArrayList<RemoteClient> checked = new ArrayList<RemoteClient>(); 112 for (int i = 0; i < clients.size(); i++) { 113 if (checkedItemPositions.get(i)) { 114 checked.add(clients.get(i)); 115 } 116 } 117 notifyListener(checked); 118 } 119 }); 120 } else { 121 builder.setItems(clientNames, new DialogInterface.OnClickListener() { 122 @Override 123 public void onClick(DialogInterface dialog, int index) { 124 final ArrayList<RemoteClient> checked = new ArrayList<RemoteClient>(); 125 checked.add(clients.get(index)); 126 notifyListener(checked); 127 } 128 }); 129 } 130 131 return builder.create(); 132 } 133 } 134