SingleFolderSelectionDialog.java revision 9eb1c9a76a400f84c002b58c831119119ebf4870
1/* 2 * Copyright (C) 2012 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mail.ui; 19 20import android.app.AlertDialog; 21import android.app.AlertDialog.Builder; 22import android.content.Context; 23import android.content.DialogInterface; 24import android.content.DialogInterface.OnClickListener; 25import android.database.Cursor; 26import android.os.AsyncTask; 27import android.view.View; 28import android.widget.AdapterView; 29 30import com.android.mail.R; 31import com.android.mail.providers.Account; 32import com.android.mail.providers.Conversation; 33import com.android.mail.providers.Folder; 34import com.android.mail.providers.UIProvider; 35import com.android.mail.ui.FolderSelectorAdapter.FolderRow; 36import com.android.mail.utils.Utils; 37 38import java.util.ArrayList; 39import java.util.Collection; 40 41/** 42 * Displays a folder selection dialog for the conversation provided. It allows 43 * the user to switch a conversation from one folder to another. 44 */ 45public class SingleFolderSelectionDialog extends FolderSelectionDialog implements OnClickListener { 46 private AlertDialog mDialog; 47 private ConversationUpdater mUpdater; 48 private SeparatedFolderListAdapter mAdapter; 49 private final Collection<Conversation> mTarget; 50 private boolean mBatch; 51 final QueryRunner mRunner; 52 private Folder mExcludeFolder; 53 private Builder mBuilder; 54 private Account mAccount; 55 56 public static SingleFolderSelectionDialog getInstance(final Context context, Account account, 57 final ConversationUpdater updater, Collection<Conversation> target, boolean isBatch, 58 Folder currentFolder) { 59 if (isShown()) { 60 return null; 61 } 62 return new SingleFolderSelectionDialog( 63 context, account, updater, target, isBatch, currentFolder); 64 } 65 66 /** 67 * Create a new {@link SingleFolderSelectionDialog}. It is displayed when 68 * the {@link #show()} method is called. 69 * @param context 70 * @param account the current account 71 * @param updater 72 * @param target conversations that are impacted 73 * @param isBatch whether the dialog is shown during Contextual Action Bar 74 * (CAB) mode 75 * @param currentFolder the current folder that the 76 * {@link FolderListFragment} is showing 77 */ 78 private SingleFolderSelectionDialog(final Context context, Account account, 79 final ConversationUpdater updater, Collection<Conversation> target, boolean isBatch, 80 Folder currentFolder) { 81 mUpdater = updater; 82 mTarget = target; 83 mBatch = isBatch; 84 mExcludeFolder = currentFolder; 85 mBuilder = new AlertDialog.Builder(context); 86 mBuilder.setTitle(R.string.folder_selection_dialog_title); 87 mBuilder.setNegativeButton(R.string.cancel, this); 88 mAccount = account; 89 mAdapter = new SeparatedFolderListAdapter(context); 90 mRunner = new QueryRunner(context); 91 } 92 93 /** 94 * Class to query the Folder list database in the background and update the adapter with an 95 * open cursor. 96 */ 97 private final class QueryRunner extends AsyncTask<Void, Void, Void> { 98 private final Context mContext; 99 100 private QueryRunner(final Context context){ 101 mContext = context; 102 } 103 104 @Override 105 protected Void doInBackground(Void... v) { 106 Cursor foldersCursor = null; 107 try { 108 foldersCursor = mContext.getContentResolver().query( 109 !Utils.isEmpty(mAccount.fullFolderListUri) ? mAccount.fullFolderListUri 110 : mAccount.folderListUri, UIProvider.FOLDERS_PROJECTION, null, 111 null, null); 112 // TODO(mindyp) : bring this back in UR8 when Email providers 113 // will have divided folder sections. 114 final String[] headers = mContext.getResources().getStringArray( 115 R.array.moveto_folder_sections); 116 // Currently, the number of adapters are assumed to match the 117 // number of headers in the string array. 118 mAdapter.addSection(new SystemFolderSelectorAdapter(mContext, foldersCursor, 119 R.layout.single_folders_view, null, mExcludeFolder)); 120 121 // TODO(mindyp): we currently do not support frequently moved to 122 // folders, at headers[1]; need to define what that means.*/ 123 mAdapter.addSection(new HierarchicalFolderSelectorAdapter(mContext, 124 AddableFolderSelectorAdapter.filterFolders(foldersCursor), 125 R.layout.single_folders_view, headers[2], mExcludeFolder)); 126 mBuilder.setAdapter(mAdapter, SingleFolderSelectionDialog.this); 127 } finally { 128 if (foldersCursor != null) { 129 foldersCursor.close(); 130 } 131 } 132 return null; 133 } 134 135 @Override 136 protected void onPostExecute(Void v) { 137 mDialog = mBuilder.create(); 138 showInternal(); 139 } 140 } 141 142 /** 143 * Shows the {@link SingleFolderSelectionDialog} dialog. 144 */ 145 @Override 146 public void show() { 147 super.show(); 148 mRunner.execute(); 149 } 150 151 /** 152 * Shows the dialog after a database query has occurred. 153 */ 154 private final void showInternal() { 155 mDialog.show(); 156 mDialog.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { 157 @Override 158 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 159 final Object item = mAdapter.getItem(position); 160 if (item instanceof FolderRow) { 161 final Folder folder = ((FolderRow) item).getFolder(); 162 ArrayList<FolderOperation> ops = new ArrayList<FolderOperation>(); 163 // Remove the current folder and add the new folder. 164 ops.add(new FolderOperation(mExcludeFolder, false)); 165 ops.add(new FolderOperation(folder, true)); 166 mUpdater.assignFolder(ops, mTarget, mBatch, true); 167 mDialog.dismiss(); 168 } 169 } 170 }); 171 mDialog.setOnDismissListener(this); 172 } 173 174 @Override 175 public void onClick(DialogInterface dialog, int which) { 176 // Do nothing. 177 } 178} 179