Show confirmation dialog before discarding drafts.

1. This CL implements the most common case, which is pressing the discard
  button on MessageCompose.

2. This CL doesn't change the discard on message list, which is much trickier.
   (We need to check the message type of all messages in the selection,
   as selection can contain any number of any kind of messges in "All Starred")

Bug 3072556

Change-Id: Ib270cae726f8fd5abf7e0e7dfc34ce97019d5301
This commit is contained in:
Makoto Onuki 2010-11-09 10:47:19 -08:00
parent 77303a483b
commit fd8ee7bc50
3 changed files with 119 additions and 2 deletions

View File

@ -370,6 +370,13 @@ save attachment.</string>
You have replied \"maybe\" to this invitation</string>
<!-- Toast shown following a meeting invite reply, declined -->
<string name="message_view_invite_toast_no">You have declined this invitation</string>
<!--Confirmation dialog title shown when user tries to delete messages. [CHAR LIMIT=16] -->
<string name="message_delete_dialog_title">Discard message</string>
<!--Confirmation dialog text shown when user tries to delete messages. [CHAR LIMIT=32] -->
<plurals name="message_delete_confirm">
<item quantity="one">Discard this message?</item>
<item quantity="other">Discard these messages?</item>
</plurals>
<!-- Toast shown briefly while deleting a message -->
<plurals name="message_deleted_toast">
<item quantity="one">Message deleted.</item>

View File

@ -0,0 +1,93 @@
/*
* Copyright (C) 2010 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.email.activity;
import com.android.email.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
/**
* Confirmation dialog for deleting messages.
*/
public class DeleteMessageConfirmationDialog extends DialogFragment
implements DialogInterface.OnClickListener {
private static final String COUNT_MESSAGES_ARG = "count_messages";
public interface Callback {
public void onDeleteMessageConfirmationDialogOkPressed();
}
/**
* Create a new dialog.
*
* @param countMessage the number of messages to be deleted
* @param callbackFragment fragment that implements {@link Callback}. Or null, in which case
* the parent activity must implement {@link Callback}.
*/
public static DeleteMessageConfirmationDialog newInstance(int countMessage,
Fragment callbackFragment) {
final DeleteMessageConfirmationDialog dialog = new DeleteMessageConfirmationDialog();
final Bundle args = new Bundle();
args.putInt(COUNT_MESSAGES_ARG, countMessage);
dialog.setArguments(args);
if (callbackFragment != null) {
dialog.setTargetFragment(callbackFragment, 0);
}
return dialog;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final int countMessages = getArguments().getInt(COUNT_MESSAGES_ARG);
final Context context = getActivity();
final Resources res = context.getResources();
final AlertDialog.Builder b = new AlertDialog.Builder(context);
b.setTitle(res.getString(R.string.message_delete_dialog_title))
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(res.getQuantityString(R.plurals.message_delete_confirm, countMessages))
.setPositiveButton(R.string.okay_action, this)
.setNegativeButton(R.string.cancel_action, null);
return b.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
getCallback().onDeleteMessageConfirmationDialogOkPressed();
break;
}
}
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();
}
}

View File

@ -36,11 +36,13 @@ import com.android.email.provider.EmailContent.MessageColumns;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
@ -84,7 +86,8 @@ import java.util.List;
* C: add cc/bcc
* N: add attachment
*/
public class MessageCompose extends Activity implements OnClickListener, OnFocusChangeListener {
public class MessageCompose extends Activity implements OnClickListener, OnFocusChangeListener,
DeleteMessageConfirmationDialog.Callback {
private static final String ACTION_REPLY = "com.android.email.intent.action.REPLY";
private static final String ACTION_REPLY_ALL = "com.android.email.intent.action.REPLY_ALL";
private static final String ACTION_FORWARD = "com.android.email.intent.action.FORWARD";
@ -1003,10 +1006,24 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
}
private void onDiscard() {
DeleteMessageConfirmationDialog.newInstance(1, null).show(getFragmentManager(), "dialog");
}
/**
* Called when ok on the "discard draft" dialog is pressed. Actually delete the draft.
*/
@Override
public void onDeleteMessageConfirmationDialogOkPressed() {
if (mDraft.mId > 0) {
// By the way, we can't pass the message ID from onDiscard() to here (using a
// dialog argument or whatever), because you can rotate the screen when the dialog is
// shown, and during rotation we save & restore the draft. If it's the
// first save, we give it an ID at this point for the first time (and last time).
// Which means it's possible for a draft to not have an ID in onDiscard(),
// but here.
mController.deleteMessage(mDraft.mId, mDraft.mAccountKey);
}
Toast.makeText(this, getString(R.string.message_discarded_toast), Toast.LENGTH_LONG).show();
Utility.showToast(MessageCompose.this, R.string.message_discarded_toast);
setDraftNeedsSaving(false);
finish();
}