blob: 3fb378b8993042c26a856d7c3c13f06423ca970f [file] [log] [blame]
/*
* Copyright (C) 2012 Google Inc.
* Licensed to The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mail.ui;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import com.android.mail.R;
import com.android.mail.providers.Account;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.FolderType;
import com.android.mail.ui.FolderSelectorAdapter.FolderRow;
import com.android.mail.utils.Utils;
import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
/**
* Displays a folder selection dialog for the conversation provided. It allows
* the user to mark folders to assign that conversation to.
*/
public class MultiFoldersSelectionDialog extends FolderSelectionDialog {
private final boolean mSingle;
private final HashMap<Uri, FolderOperation> mOperations;
/**
* Create a new {@link MultiFoldersSelectionDialog}. It is displayed when
* the {@link #show()} method is called.
* @param context
* @param account the current account
* @param updater
* @param target conversations that are impacted
* @param isBatch whether the dialog is shown during Contextual Action Bar
* (CAB) mode
* @param currentFolder the current folder that the
* {@link FolderListFragment} is showing
*/
public MultiFoldersSelectionDialog(final Context context, final Account account,
final ConversationUpdater updater, final Collection<Conversation> target,
final boolean isBatch, final Folder currentFolder) {
super(context, account, updater, target, isBatch, currentFolder);
mSingle = !account
.supportsCapability(UIProvider.AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV);
mOperations = new HashMap<Uri, FolderOperation>();
mBuilder.setTitle(R.string.change_folders_selection_dialog_title);
mBuilder.setPositiveButton(R.string.ok, this);
}
@Override
protected void updateAdapterInBackground(Context context) {
Cursor foldersCursor = null;
try {
foldersCursor = context.getContentResolver().query(
!Utils.isEmpty(mAccount.fullFolderListUri) ? mAccount.fullFolderListUri
: mAccount.folderListUri, UIProvider.FOLDERS_PROJECTION, null, null,
null);
/** All the folders that this conversations is assigned to. */
final HashSet<String> checked = new HashSet<String>();
for (final Conversation conversation : mTarget) {
final List<Folder> rawFolders = conversation.getRawFolders();
if (rawFolders != null && rawFolders.size() > 0) {
// Parse the raw folders and get all the uris.
checked.addAll(Arrays.asList(Folder.getUriArray(rawFolders)));
} else {
// There are no folders for this conversation, so it must
// belong to the folder we are currently looking at.
checked.add(mCurrentFolder.folderUri.fullUri.toString());
}
}
// TODO(mindyp) : bring this back in UR8 when Email providers
// will have divided folder sections.
/* final String[] headers = mContext.getResources()
.getStringArray(R.array.moveto_folder_sections);
// Currently, the number of adapters are assumed to match the
// number of headers in the string array.
mAdapter.addSection(new SystemFolderSelectorAdapter(mContext,
foldersCursor, checked, R.layout.multi_folders_view, null));
// TODO(mindyp): we currently do not support frequently moved to
// folders, at headers[1]; need to define what that means.*/
mAdapter.addSection(new AddableFolderSelectorAdapter(context,
AddableFolderSelectorAdapter.filterFolders(foldersCursor,
ImmutableSet.of(FolderType.INBOX_SECTION)), checked,
R.layout.multi_folders_view, null));
mBuilder.setAdapter(mAdapter, MultiFoldersSelectionDialog.this);
} finally {
if (foldersCursor != null) {
foldersCursor.close();
}
}
}
@Override
protected void onListItemClick(int position) {
final Object item = mAdapter.getItem(position);
if (item instanceof FolderRow) {
update((FolderRow) item);
}
}
/**
* Call this to update the state of folders as a result of them being
* selected / de-selected.
*
* @param row The item being updated.
*/
private final void update(FolderSelectorAdapter.FolderRow row) {
final boolean add = !row.isPresent();
if (mSingle) {
if (!add) {
// This would remove the check on a single radio button, so just
// return.
return;
}
// Clear any other checked items.
for (int i = 0, size = mAdapter.getCount(); i < size; i++) {
final Object item = mAdapter.getItem(i);
if (item instanceof FolderRow) {
((FolderRow)item).setIsPresent(false);
final Folder folder = ((FolderRow)item).getFolder();
mOperations.put(folder.folderUri.fullUri,
new FolderOperation(folder, false));
}
}
}
row.setIsPresent(add);
mAdapter.notifyDataSetChanged();
final Folder folder = row.getFolder();
mOperations.put(folder.folderUri.fullUri, new FolderOperation(folder, add));
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
if (mUpdater != null) {
mUpdater.assignFolder(mOperations.values(), mTarget, mBatch,
true /* showUndo */, false /* isMoveTo */);
}
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
default:
break;
}
}
}