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