MultiFoldersSelectionDialog.java revision f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931
1f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira/*
2f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * Copyright (C) 2012 Google Inc.
3f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * Licensed to The Android Open Source Project.
4f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira *
5f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
6f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * you may not use this file except in compliance with the License.
7f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * You may obtain a copy of the License at
8f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira *
9f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira *      http://www.apache.org/licenses/LICENSE-2.0
10f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira *
11f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * Unless required by applicable law or agreed to in writing, software
12f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
13f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * See the License for the specific language governing permissions and
15f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira * limitations under the License.
16f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira */
17f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereirapackage com.android.mail.ui;
18f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
19f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.app.AlertDialog;
20f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.content.Context;
21f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.content.DialogInterface;
22f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.content.DialogInterface.OnClickListener;
23f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.content.DialogInterface.OnMultiChoiceClickListener;
24f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.database.Cursor;
25f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.database.MatrixCursor;
26f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.net.Uri;
27f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport android.provider.BaseColumns;
28f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
29f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport com.android.mail.R;
30f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport com.android.mail.providers.Account;
31f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport com.android.mail.providers.UIProvider;
32f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
33f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport java.util.ArrayList;
34f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport java.util.HashMap;
35f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport java.util.Set;
36f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereiraimport java.util.Map.Entry;
37f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
38f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereirapublic class FoldersSelectionDialog implements OnClickListener, OnMultiChoiceClickListener {
39f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final String CHECKED_COLUMN_NAME = "checked";
40f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    // We only need _id because MatrixCursor insists
41f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final String[] FOLDER_DIALOG_PROJECTION = new String[] {
42f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            BaseColumns._ID, UIProvider.FolderColumns.URI, UIProvider.FolderColumns.NAME,
43f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            CHECKED_COLUMN_NAME
44f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    };
45f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final int FOLDERS_CURSOR_ID = 0;
46f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final int FOLDERS_CURSOR_URI = 1;
47f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final int FOLDERS_CURSOR_NAME = 2;
48f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private static final int FOLDERS_CURSOR_CHECKED = 3;
49f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
50f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private int mCheckedItem;
51f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private AlertDialog mDialog;
52f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private CommitListener mCommitListener;
53f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private HashMap<String, Boolean> mCheckedState;
54f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private MatrixCursor mFolderDialogCursor;
55f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    private boolean mSingle = false;
56f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
57f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    public interface CommitListener {
58f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        public void onCommit(String uris);
59f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    }
60f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
61f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    public FoldersSelectionDialog(final Context context, Account account,
62f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            final CommitListener commitListener) {
63f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mCommitListener = commitListener;
64f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        // Mapping of a folder's uri to its checked state
65f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mCheckedState = new HashMap<String, Boolean>();
66f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        AlertDialog.Builder builder = new AlertDialog.Builder(context);
67f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        builder.setTitle("Change folders");
68f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        builder.setPositiveButton(R.string.ok, this);
69f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        builder.setNegativeButton(R.string.cancel, this);
70f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
71f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        // Get all of our folders
72f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        // TODO: Should only be folders that allow messages to be moved there!!
73f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        Cursor foldersCursor = context.getContentResolver().query(Uri.parse(account.folderListUri),
74f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                UIProvider.FOLDERS_PROJECTION, null, null, null);
75f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        // Get the id, name, and a placeholder for check information
76f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        Object[] columnValues = new Object[FOLDER_DIALOG_PROJECTION.length];
77f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mFolderDialogCursor = new MatrixCursor(FOLDER_DIALOG_PROJECTION);
78f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        int i = 0;
79f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        while (foldersCursor.moveToNext()) {
80f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            int flags = foldersCursor.getInt(UIProvider.FOLDER_CAPABILITIES_COLUMN);
81f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            if ((flags & UIProvider.FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES) == 0) {
82f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                continue;
83f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            }
84f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            String uri = foldersCursor.getString(UIProvider.FOLDER_URI_COLUMN);
85f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            columnValues[FOLDERS_CURSOR_ID] = i++;
86f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            columnValues[FOLDERS_CURSOR_URI] = uri;
87f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            columnValues[FOLDERS_CURSOR_NAME] = foldersCursor
88f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    .getString(UIProvider.FOLDER_NAME_COLUMN);
89f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            columnValues[FOLDERS_CURSOR_CHECKED] = 0; // 0 = unchecked
90f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mFolderDialogCursor.addRow(columnValues);
91f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mCheckedState.put(uri, false);
92f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        }
93f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        foldersCursor.close();
94f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
95f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        if (!account.supportsCapability(UIProvider.AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV)) {
96f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mSingle = true;
97f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            builder.setSingleChoiceItems(mFolderDialogCursor, mCheckedItem,
98f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    UIProvider.FolderColumns.NAME, this);
99f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        } else {
100f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            builder.setMultiChoiceItems(mFolderDialogCursor, CHECKED_COLUMN_NAME,
101f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    UIProvider.FolderColumns.NAME, this);
102f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        }
103f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mDialog = builder.create();
104f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    }
105f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
106f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    public void show() {
107f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mDialog.show();
108f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    }
109f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
110f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    @Override
111f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    public void onClick(DialogInterface dialog, int which) {
112f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        switch (which) {
113f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            case DialogInterface.BUTTON_POSITIVE:
114f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                ArrayList<String> checkedItems = new ArrayList<String>();
115f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                Set<Entry<String, Boolean>> states = mCheckedState.entrySet();
116f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                for (Entry<String, Boolean> entry : states) {
117f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    if (entry.getValue()) {
118f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                        checkedItems.add(entry.getKey());
119f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    }
120f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                }
121f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                StringBuilder folderUris = new StringBuilder();
122f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                boolean first = true;
123f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                for (String folderUri : checkedItems) {
124f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    if (first) {
125f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                        first = false;
126f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    } else {
127f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                        folderUris.append(',');
128f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    }
129f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    folderUris.append(folderUri);
130f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                }
131f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                if (mCommitListener != null) {
132f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                    mCommitListener.onCommit(folderUris.toString());
133f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                }
134f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                break;
135f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            case DialogInterface.BUTTON_NEGATIVE:
136f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                break;
137f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            default:
138f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                onClick(dialog, which, true);
139f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira                break;
140f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        }
141f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    }
142f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira
143f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    @Override
144f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
145f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        mFolderDialogCursor.moveToPosition(which);
146f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        if (mSingle) {
147f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mCheckedState.clear();
148f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mCheckedState.put(mFolderDialogCursor.getString(FOLDERS_CURSOR_URI), true);
149f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        } else {
150f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira            mCheckedState.put(mFolderDialogCursor.getString(FOLDERS_CURSOR_URI), isChecked);
151f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira        }
152f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira    }
153f3dfb15b47aabd56fa7b7c99685ba6fad1d7e931Mindy Pereira}
154