Merge "Fix "move to" dialog."

This commit is contained in:
Makoto Onuki 2011-04-27 12:44:23 -07:00 committed by Android (Google) Code Review
commit 567442bcf8
7 changed files with 72 additions and 52 deletions

View File

@ -75,6 +75,8 @@ import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Pattern;
@ -902,6 +904,8 @@ public class Utility {
}
public static long[] toPrimitiveLongArray(Collection<Long> collection) {
// Need to do this manually because we're converting to a primitive long array, not
// a Long array.
final int size = collection.size();
final long[] ret = new long[size];
// Collection doesn't have get(i). (Iterable doesn't have size())
@ -912,6 +916,17 @@ public class Utility {
return ret;
}
public static Set<Long> toLongSet(long[] array) {
// Need to do this manually because we're converting from a primitive long array, not
// a Long array.
final int size = array.length;
HashSet<Long> ret = new HashSet<Long>(size);
for (int i = 0; i < size; i++) {
ret.add(array[i]);
}
return ret;
}
/**
* Workaround for the {@link ListView#smoothScrollToPosition} randomly scroll the view bug
* if it's called right after {@link ListView#setAdapter}.

View File

@ -736,7 +736,7 @@ public class MessageListFragment extends ListFragment
}
}
private void moveMessages(Set<Long> selectedSet) {
private void showMoveMessagesDialog(Set<Long> selectedSet) {
long[] messageIds = Utility.toPrimitiveLongArray(selectedSet);
MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(messageIds, this);
dialog.show(getFragmentManager(), "dialog");
@ -744,6 +744,7 @@ public class MessageListFragment extends ListFragment
@Override
public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
mCallback.onAdvancingOpAccepted(Utility.toLongSet(messageIds));
ActivityHelper.moveMessages(getActivity(), newMailboxId, messageIds);
// Move is async, so we can't refresh now. Instead, just clear the selection.
@ -1378,8 +1379,7 @@ public class MessageListFragment extends ListFragment
deleteMessages(selectedConversations);
break;
case R.id.move:
mCallback.onAdvancingOpAccepted(selectedConversations);
moveMessages(selectedConversations);
showMoveMessagesDialog(selectedConversations);
break;
}
return true;

View File

@ -49,7 +49,6 @@ import java.util.Set;
* TODO Refine "move to".
*/
class MessageListXLFragmentManager implements
MoveMessageToDialog.Callback,
MailboxFinder.Callback,
ThreePaneLayout.Callback,
MailboxListFragment.Callback,
@ -178,13 +177,6 @@ class MessageListXLFragmentManager implements
Log.e(Logging.LOG_TAG, "unable to find mailbox");
}
// MoveMessageToDialog$Callback
@Override
public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
ActivityHelper.moveMessages(mActivity, newMailboxId, messageIds);
onCurrentMessageGone();
}
// ThreePaneLayoutCallback
@Override
public void onVisiblePanesChanged(int previousVisiblePanes) {
@ -258,6 +250,11 @@ class MessageListXLFragmentManager implements
*/
@Override
public void onAdvancingOpAccepted(Set<Long> affectedMessages) {
if (!isMessageSelected()) {
// Do nothing if message view is not visible.
return;
}
int autoAdvanceDir = Preferences.getPreferences(mActivity).getAutoAdvanceDirection();
if ((autoAdvanceDir == Preferences.AUTO_ADVANCE_MESSAGE_LIST) || (mOrderManager == null)) {
if (affectedMessages.contains(getMessageId())) {
@ -346,17 +343,10 @@ class MessageListXLFragmentManager implements
}
@Override
public void onBeforeMessageDelete() {
public void onBeforeMessageGone() {
onCurrentMessageGone();
}
@Override
public void onMoveMessage() {
long messageId = getMessageId();
MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(new long[] {messageId}, null);
dialog.show(mActivity.getFragmentManager(), "dialog");
}
@Override
public void onForward() {
MessageCompose.actionForward(mActivity, getMessageId());

View File

@ -368,12 +368,7 @@ public class MessageView extends MessageViewBase implements View.OnClickListener
}
@Override
public void onBeforeMessageDelete() {
// TODO Implement this
}
@Override
public void onMoveMessage() {
public void onBeforeMessageGone() {
// TODO Implement this
}
}

View File

@ -50,7 +50,7 @@ import java.security.InvalidParameterException;
* See {@link MessageViewBase} for the class relation diagram.
*/
public class MessageViewFragment extends MessageViewFragmentBase
implements CheckBox.OnCheckedChangeListener {
implements CheckBox.OnCheckedChangeListener, MoveMessageToDialog.Callback {
/** Argument name(s) */
private static final String ARG_MESSAGE_ID = "messageId";
@ -107,13 +107,12 @@ public class MessageViewFragment extends MessageViewFragmentBase
public void onMessageSetUnread();
/**
* Called right before the current message will be deleted.
* Callees don't have to delete messages. The fragment does.
* Called right before the current message will be deleted or moved to another mailbox.
*
* Callees will usually close the fragment.
*/
public void onBeforeMessageDelete();
public void onBeforeMessageGone();
/** Called when the move button is pressed. */
public void onMoveMessage();
/** Called when the forward button is pressed. */
public void onForward();
/** Called when the reply button is pressed. */
@ -130,8 +129,7 @@ public class MessageViewFragment extends MessageViewFragmentBase
@Override public void onCalendarLinkClicked(long epochEventStartTime) { }
@Override public void onMessageSetUnread() { }
@Override public void onRespondedToInvite(int response) { }
@Override public void onBeforeMessageDelete() { }
@Override public void onMoveMessage() { }
@Override public void onBeforeMessageGone() { }
@Override public void onForward() { }
@Override public void onReply() { }
@Override public void onReplyAll() { }
@ -415,11 +413,22 @@ public class MessageViewFragment extends MessageViewFragmentBase
}
private void onMove() {
mCallback.onMoveMessage();
// STOPSHIP mCurrentMessageId is not a good one to use here. See b/4346486
// (We use it for now just to keep it consistent with onDelete)
MoveMessageToDialog dialog = MoveMessageToDialog.newInstance(new long[] {mCurrentMessageId},
this);
dialog.show(getFragmentManager(), "dialog");
}
// MoveMessageToDialog$Callback
@Override
public void onMoveToMailboxSelected(long newMailboxId, long[] messageIds) {
mCallback.onBeforeMessageGone();
ActivityHelper.moveMessages(mContext, newMailboxId, messageIds);
}
private void onDelete() {
mCallback.onBeforeMessageDelete();
mCallback.onBeforeMessageGone();
ActivityHelper.deleteMessage(mContext, mCurrentMessageId);
}

View File

@ -16,7 +16,9 @@
package com.android.email.activity;
import com.android.email.Email;
import com.android.email.R;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Mailbox;
import com.android.emailcommon.provider.EmailContent.Message;
@ -35,6 +37,7 @@ import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.security.InvalidParameterException;
@ -68,25 +71,29 @@ public class MoveMessageToDialog extends DialogFragment implements DialogInterfa
*
* @param messageIds IDs of the messages to be moved.
* @param callbackFragment Fragment that gets a callback. The fragment must implement
* {@link Callback}. If null is passed, then the owner activity is used instead, in which case
* it must implement {@link Callback} instead.
* {@link Callback}.
*/
public static MoveMessageToDialog newInstance(long[] messageIds, Fragment callbackFragment) {
public static <T extends Fragment & Callback> MoveMessageToDialog newInstance(long[] messageIds,
T callbackFragment) {
if (messageIds.length == 0) {
throw new InvalidParameterException();
}
if (callbackFragment == null) {
throw new IllegalArgumentException(); // fail fast
}
MoveMessageToDialog dialog = new MoveMessageToDialog();
Bundle args = new Bundle();
args.putLongArray(BUNDLE_MESSAGE_IDS, messageIds);
dialog.setArguments(args);
if (callbackFragment != null) {
dialog.setTargetFragment(callbackFragment, 0);
}
dialog.setTargetFragment(callbackFragment, 0);
return dialog;
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, "" + this + " onCreate target=" + getTargetFragment());
}
super.onCreate(savedInstanceState);
mMessageIds = getArguments().getLongArray(BUNDLE_MESSAGE_IDS);
setStyle(STYLE_NORMAL, android.R.style.Theme_Holo_Light);
@ -121,20 +128,10 @@ public class MoveMessageToDialog extends DialogFragment implements DialogInterfa
public void onClick(DialogInterface dialog, int position) {
final long mailboxId = mAdapter.getItemId(position);
getCallback().onMoveToMailboxSelected(mailboxId, mMessageIds);
((Callback) getTargetFragment()).onMoveToMailboxSelected(mailboxId, mMessageIds);
dismiss();
}
private Callback getCallback() {
Fragment targetFragment = getTargetFragment();
if (targetFragment != null) {
// If a target is set, it MUST implement Callback.
return (Callback) targetFragment;
}
// If not the parent activity MUST implement Callback.
return (Callback) getActivity();
}
/**
* Delay-call {@link #dismissAllowingStateLoss()} using a {@link Handler}. Calling
* {@link #dismissAllowingStateLoss()} from {@link LoaderManager.LoaderCallbacks#onLoadFinished}

View File

@ -334,6 +334,19 @@ public class UtilityUnitTests extends AndroidTestCase {
assertEquals(4, two[1]);
}
public void testToLongSet() {
assertEquals(0, Utility.toLongSet(new long[] {}).size());
final Set<Long> one = Utility.toLongSet(new long[] {1});
assertEquals(1, one.size());
assertTrue(one.contains(1L));
final Set<Long> two = Utility.toLongSet(new long[] {1, 2});
assertEquals(2, two.size());
assertTrue(two.contains(1L));
assertTrue(two.contains(2L));
}
public void testGetContentFileName() throws Exception {
Context providerContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(
mContext);
@ -359,6 +372,7 @@ public class UtilityUnitTests extends AndroidTestCase {
assertEquals(lastPathSegment, Utility.getContentFileName(providerContext, notExistUri));
}
// used by testToPrimitiveLongArray
private static Collection<Long> createLongCollection(long... values) {
ArrayList<Long> ret = new ArrayList<Long>();
for (long value : values) {