summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/RemoteClientsDialogFragment.java
blob: b4aee9370a4f9511ffd5e4b329631f8fb85426c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.gecko;

import java.util.ArrayList;
import java.util.List;

import org.mozilla.gecko.db.RemoteClient;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.util.SparseBooleanArray;

/**
 * A dialog fragment that displays a list of remote clients.
 * <p>
 * The dialog allows both single (one tap) and multiple (checkbox) selection.
 * The dialog's results are communicated via the {@link RemoteClientsListener}
 * interface. Either the dialog fragment's <i>target fragment</i> (see
 * {@link Fragment#setTargetFragment(Fragment, int)}), or the containing
 * <i>activity</i>, must implement that interface. See
 * {@link #notifyListener(List)} for details.
 */
public class RemoteClientsDialogFragment extends DialogFragment {
    private static final String KEY_TITLE = "title";
    private static final String KEY_CHOICE_MODE = "choice_mode";
    private static final String KEY_POSITIVE_BUTTON_TEXT = "positive_button_text";
    private static final String KEY_CLIENTS = "clients";

    public interface RemoteClientsListener {
        // Always called on the main UI thread.
        public void onClients(List<RemoteClient> clients);
    }

    public enum ChoiceMode {
        SINGLE,
        MULTIPLE,
    }

    public static RemoteClientsDialogFragment newInstance(String title, String positiveButtonText, ChoiceMode choiceMode, ArrayList<RemoteClient> clients) {
        final RemoteClientsDialogFragment dialog = new RemoteClientsDialogFragment();
        final Bundle args = new Bundle();
        args.putString(KEY_TITLE, title);
        args.putString(KEY_POSITIVE_BUTTON_TEXT, positiveButtonText);
        args.putInt(KEY_CHOICE_MODE, choiceMode.ordinal());
        args.putParcelableArrayList(KEY_CLIENTS, clients);
        dialog.setArguments(args);
        return dialog;
    }

    public RemoteClientsDialogFragment() {
        // Empty constructor is required for DialogFragment.
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        GeckoApplication.watchReference(getActivity(), this);
    }

    protected void notifyListener(List<RemoteClient> clients) {
        RemoteClientsListener listener;
        try {
            listener = (RemoteClientsListener) getTargetFragment();
        } catch (ClassCastException e) {
            try {
                listener = (RemoteClientsListener) getActivity();
            } catch (ClassCastException f) {
                throw new ClassCastException(getTargetFragment() + " or " + getActivity()
                        + " must implement RemoteClientsListener");
            }
        }
        listener.onClients(clients);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final String title = getArguments().getString(KEY_TITLE);
        final String positiveButtonText = getArguments().getString(KEY_POSITIVE_BUTTON_TEXT);
        final ChoiceMode choiceMode = ChoiceMode.values()[getArguments().getInt(KEY_CHOICE_MODE)];
        final ArrayList<RemoteClient> clients = getArguments().getParcelableArrayList(KEY_CLIENTS);

        final Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(title);

        final String[] clientNames = new String[clients.size()];
        for (int i = 0; i < clients.size(); i++) {
            clientNames[i] = clients.get(i).name;
        }

        if (choiceMode == ChoiceMode.MULTIPLE) {
            builder.setMultiChoiceItems(clientNames, null, null);
            builder.setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int which) {
                    if (which != Dialog.BUTTON_POSITIVE) {
                        return;
                    }

                    final AlertDialog dialog = (AlertDialog) dialogInterface;
                    final SparseBooleanArray checkedItemPositions = dialog.getListView().getCheckedItemPositions();
                    final ArrayList<RemoteClient> checked = new ArrayList<RemoteClient>();
                    for (int i = 0; i < clients.size(); i++) {
                        if (checkedItemPositions.get(i)) {
                            checked.add(clients.get(i));
                        }
                    }
                    notifyListener(checked);
                }
            });
        } else {
            builder.setItems(clientNames, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int index) {
                    final ArrayList<RemoteClient> checked = new ArrayList<RemoteClient>();
                    checked.add(clients.get(index));
                    notifyListener(checked);
                }
            });
        }

        return builder.create();
    }
}