Add message view menu items to MessageList

This commit is contained in:
cketti 2013-01-29 01:19:53 +01:00
parent 77b8e62d64
commit ad2a6d7a9b
5 changed files with 318 additions and 191 deletions

View File

@ -1,28 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!--
The comments preceding the (top level) menu items denote which part of the combined message
list/view activity the item belongs to. Either "MessageList", "MessageView", or "always" (as in:
always show this item, no matter what display mode we're in).
The comments are for informational purposes only. Please make sure to adjust the code in
MessageList.configureMenu() if you make any changes to this file.
-->
<!-- MessageList -->
<item
android:id="@+id/search"
android:icon="?attr/iconActionSearch"
android:showAsAction="always"
android:title="@string/search_action"/>
<!-- MessageList -->
<item
android:id="@+id/search_remote"
android:icon="?attr/iconActionRemoteSearch"
android:showAsAction="always"
android:title="@string/action_remote_search"
android:visible="false"
/>
android:visible="false"/>
<!-- MessageList -->
<item
android:id="@+id/check_mail"
android:alphabeticShortcut="r"
android:icon="?attr/iconActionRefresh"
android:showAsAction="always"
android:title="@string/check_mail_action"/>
<!-- MessageView -->
<item
android:id="@+id/delete"
android:alphabeticShortcut="q"
android:icon="?attr/iconActionDelete"
android:showAsAction="always"
android:title="@string/delete_action"/>
<!-- MessageView -->
<item
android:id="@+id/single_message_options"
android:icon="?attr/iconActionSingleMessageOptions"
android:showAsAction="ifRoom"
android:title="@string/single_message_options_action">
<menu>
<item
android:id="@+id/reply"
android:title="@string/reply_action"/>
<item
android:id="@+id/reply_all"
android:title="@string/reply_all_action"/>
<item
android:id="@+id/forward"
android:title="@string/forward_action"/>
<item
android:id="@+id/share"
android:title="@string/send_alternate_action"/>
</menu>
</item>
<!-- MessageView -->
<item
android:id="@+id/archive"
android:icon="?attr/iconActionArchive"
android:showAsAction="ifRoom"
android:title="@string/archive_action"/>
<!-- MessageView -->
<item
android:id="@+id/spam"
android:icon="?attr/iconActionSpam"
android:showAsAction="ifRoom"
android:title="@string/spam_action"/>
<!-- MessageView -->
<item
android:id="@+id/move"
android:icon="?attr/iconActionMoveOrCopy"
android:showAsAction="ifRoom"
android:title="@string/move_action"/>
<!-- MessageView -->
<item
android:id="@+id/copy"
android:title="@string/copy_action"/>
<!-- MessageView -->
<item
android:id="@+id/toggle_unread"
android:alphabeticShortcut="u"
android:showAsAction="never"
android:title="@string/mark_as_unread_action"/>
<!-- MessageList -->
<item
android:id="@+id/set_sort"
android:icon="?attr/iconActionSort"
android:showAsAction="always"
android:showAsAction="ifRoom"
android:title="@string/sort_by">
<menu>
<item
@ -50,27 +128,49 @@
android:title="@string/sort_by_attach"/>
</menu>
</item>
<!-- always -->
<item
android:id="@+id/compose"
android:alphabeticShortcut="c"
android:icon="?attr/iconActionCompose"
android:showAsAction="always"
android:showAsAction="ifRoom"
android:title="@string/compose_action"/>
<!-- MessageList -->
<item
android:id="@+id/select_all"
android:icon="?attr/iconMenuSelectAll"
android:showAsAction="never"
android:title="@string/batch_select_all"/>
<!-- MessageList -->
<item
android:id="@+id/send_messages"
android:alphabeticShortcut="r"
android:icon="?attr/iconActionRefresh"
android:showAsAction="never"
android:title="@string/send_messages_action"/>
<!-- MessageList -->
<item
android:id="@+id/expunge"
android:showAsAction="never"
android:title="@string/expunge_action"/>
<!-- MessageView -->
<item
android:id="@+id/select_text"
android:showAsAction="never"
android:title="@string/select_text_action"/>
<!-- MessageView -->
<item
android:id="@+id/toggle_message_view_theme"
android:showAsAction="never"
android:title="@string/message_view_theme_action_dark"/>
<!-- always -->
<item
android:id="@+id/settings"
android:icon="?attr/iconMenuPreferences"

View File

@ -3,6 +3,7 @@ package com.fsck.k9.activity;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
@ -584,6 +585,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
mMessageListFragment.onCompose();
return true;
}
case R.id.toggle_message_view_theme: {
onToggleTheme();
return true;
}
// MessageList
case R.id.check_mail: {
mMessageListFragment.checkMail();
return true;
@ -636,6 +642,51 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
mMessageListFragment.onRemoteSearch();
return true;
}
// MessageView
case R.id.delete: {
mMessageViewFragment.onDelete();
return true;
}
case R.id.reply: {
mMessageViewFragment.onReply();
return true;
}
case R.id.reply_all: {
mMessageViewFragment.onReplyAll();
return true;
}
case R.id.forward: {
mMessageViewFragment.onForward();
return true;
}
case R.id.share: {
mMessageViewFragment.onSendAlternate();
return true;
}
case R.id.toggle_unread: {
mMessageViewFragment.onToggleRead();
return true;
}
case R.id.archive: {
mMessageViewFragment.onArchive();
return true;
}
case R.id.spam: {
mMessageViewFragment.onSpam();
return true;
}
case R.id.move: {
mMessageViewFragment.onMove();
return true;
}
case R.id.copy: {
mMessageViewFragment.onCopy();
return true;
}
case R.id.select_text: {
mMessageViewFragment.onSelectText();
return true;
}
}
if (!mSingleFolderMode) {
@ -679,53 +730,115 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
return true;
}
/**
* Hide menu items not appropriate for the current context.
*
* <p><strong>Note:</strong>
* Please adjust the comments in {@code res/menu/message_list_option.xml} if you change the
* visibility of a menu item in this method.
* </p>
*
* @param menu
* The {@link Menu} instance that should be modified. May be {@code null}; in that case
* the method does nothing and immediately returns.
*/
private void configureMenu(Menu menu) {
if (menu == null) {
return;
}
// Set visibility of account/folder settings menu items
if (mMessageListFragment == null) {
menu.findItem(R.id.account_settings).setVisible(false);
menu.findItem(R.id.folder_settings).setVisible(false);
} else {
menu.findItem(R.id.account_settings).setVisible(
mMessageListFragment.isSingleAccountMode());
menu.findItem(R.id.folder_settings).setVisible(
mMessageListFragment.isSingleFolderMode());
}
/*
* Set visibility of menu items related to the message view
*/
if (mMessageViewFragment == null) {
menu.findItem(R.id.delete).setVisible(false);
menu.findItem(R.id.single_message_options).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.copy).setVisible(false);
menu.findItem(R.id.toggle_unread).setVisible(false);
menu.findItem(R.id.select_text).setVisible(false);
menu.findItem(R.id.toggle_message_view_theme).setVisible(false);
} else {
// Set title of menu item to switch to dark/light theme
MenuItem toggleTheme = menu.findItem(R.id.toggle_message_view_theme);
if (K9.getK9MessageViewTheme() == K9.THEME_DARK) {
toggleTheme.setTitle(R.string.message_view_theme_action_light);
} else {
toggleTheme.setTitle(R.string.message_view_theme_action_dark);
}
toggleTheme.setVisible(true);
// Set title of menu item to toggle the read state of the currently displayed message
if (mMessageViewFragment.isMessageRead()) {
menu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_unread_action);
} else {
menu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_read_action);
}
menu.findItem(R.id.copy).setVisible(mMessageViewFragment.isCopyCapable());
if (mMessageViewFragment.isMoveCapable()) {
menu.findItem(R.id.move).setVisible(true);
menu.findItem(R.id.archive).setVisible(mMessageViewFragment.canMessageBeArchived());
menu.findItem(R.id.spam).setVisible(mMessageViewFragment.canMessageBeMovedToSpam());
} else {
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
}
}
/*
* Set visibility of menu items related to the message list
*/
// Hide both search menu items by default and enable one when appropriate
menu.findItem(R.id.search).setVisible(false);
menu.findItem(R.id.search_remote).setVisible(false);
if (mMessageListFragment == null) {
// Hide everything (except "compose") if no MessageListFragment instance is available
if (mDisplayMode == DisplayMode.MESSAGE_VIEW || mMessageListFragment == null) {
menu.findItem(R.id.check_mail).setVisible(false);
menu.findItem(R.id.set_sort).setVisible(false);
menu.findItem(R.id.select_all).setVisible(false);
menu.findItem(R.id.send_messages).setVisible(false);
menu.findItem(R.id.expunge).setVisible(false);
menu.findItem(R.id.settings).setVisible(false);
} else {
menu.findItem(R.id.set_sort).setVisible(true);
menu.findItem(R.id.select_all).setVisible(true);
menu.findItem(R.id.settings).setVisible(true);
if (!mSingleAccountMode) {
if (!mMessageListFragment.isSingleAccountMode()) {
menu.findItem(R.id.expunge).setVisible(false);
menu.findItem(R.id.check_mail).setVisible(false);
menu.findItem(R.id.send_messages).setVisible(false);
menu.findItem(R.id.folder_settings).setVisible(false);
menu.findItem(R.id.account_settings).setVisible(false);
} else {
menu.findItem(R.id.folder_settings).setVisible(mSingleFolderMode);
menu.findItem(R.id.account_settings).setVisible(true);
if (mMessageListFragment.isOutbox()) {
menu.findItem(R.id.send_messages).setVisible(true);
} else {
menu.findItem(R.id.send_messages).setVisible(false);
}
menu.findItem(R.id.send_messages).setVisible(mMessageListFragment.isOutbox());
if (mMessageListFragment.isRemoteFolder()) {
menu.findItem(R.id.check_mail).setVisible(true);
menu.findItem(R.id.expunge).setVisible(mMessageListFragment.isAccountExpungeCapable());
menu.findItem(R.id.expunge).setVisible(
mMessageListFragment.isAccountExpungeCapable());
} else {
menu.findItem(R.id.check_mail).setVisible(false);
menu.findItem(R.id.expunge).setVisible(false);
}
}
// If this is an explicit local search, show the option to search the cloud.
// If this is an explicit local search, show the option to search on the server
if (!mMessageListFragment.isRemoteSearch() &&
mMessageListFragment.isRemoteSearchAllowed()) {
menu.findItem(R.id.search_remote).setVisible(true);
@ -993,8 +1106,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
}
}
@Override
public void restartActivity() {
private void restartActivity() {
// restart the current activity, so that the theme change can be applied
if (Build.VERSION.SDK_INT < 11) {
Intent intent = getIntent();
@ -1069,4 +1181,35 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
mMessageListContainer.setVisibility(View.GONE);
mMessageViewContainer.setVisibility(View.VISIBLE);
}
@Override
public void updateMenu() {
configureMenu(mMenu);
}
@Override
public void disableDeleteAction() {
mMenu.findItem(R.id.delete).setEnabled(false);
}
private void onToggleTheme() {
if (K9.getK9MessageViewTheme() == K9.THEME_DARK) {
K9.setK9MessageViewTheme(K9.THEME_LIGHT);
} else {
K9.setK9MessageViewTheme(K9.THEME_DARK);
}
new Thread(new Runnable() {
@Override
public void run() {
Context appContext = getApplicationContext();
Preferences prefs = Preferences.getPreferences(appContext);
Editor editor = prefs.getPreferences().edit();
K9.save(editor);
editor.commit();
}
}).start();
restartActivity();
}
}

View File

@ -539,22 +539,6 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
public void onMount(String providerId) { /* no-op */ }
}
@Override
public void restartActivity() {
// restart the current activity, so that the theme change can be applied
if (Build.VERSION.SDK_INT < 11) {
Intent intent = getIntent();
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0); // disable animations to speed up the switch
startActivity(intent);
overridePendingTransition(0, 0);
} else {
recreate();
}
}
@Override
public void displayMessageSubject(String subject) {
setTitle(subject);
@ -577,4 +561,14 @@ public class MessageView extends K9FragmentActivity implements MessageViewFragme
MessageCompose.actionForward(this, mAccount, mMessage, mPgpData.getDecryptedData());
finish();
}
@Override
public void updateMenu() {
// TODO Auto-generated method stub
}
@Override
public void disableDeleteAction() {
// TODO Auto-generated method stub
}
}

View File

@ -3245,4 +3245,12 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
mAdapter.notifyDataSetChanged();
}
}
public boolean isSingleAccountMode() {
return mSingleAccountMode;
}
public boolean isSingleFolderMode() {
return mSingleFolderMode;
}
}

View File

@ -6,9 +6,7 @@ import java.util.Collections;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.DialogFragment;
@ -22,9 +20,6 @@ import android.view.ViewGroup;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.Preferences;
@ -75,7 +70,6 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
private SingleMessageView mMessageView;
private PgpData mPgpData;
private Menu mMenu;
private Account mAccount;
private MessageReference mMessageReference;
private Message mMessage;
@ -83,8 +77,6 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
private Listener mListener = new Listener();
private MessageViewHandler mHandler = new MessageViewHandler();
private MenuItem mToggleMessageViewMenu;
/** this variable is used to save the calling AttachmentView
* until the onActivityResult is called.
* => with this reference we can identity the caller
@ -254,7 +246,8 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
mMessageView.resetHeaderView();
mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
configureMenu(mMenu);
mFragmentListener.updateMenu();
}
/**
@ -272,7 +265,7 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
if (mMessage != null) {
// Disable the delete button after it's tapped (to try to prevent
// accidental clicks)
mMenu.findItem(R.id.delete).setEnabled(false);
mFragmentListener.disableDeleteAction();
Message messageToDelete = mMessage;
mFragmentListener.showNextMessageOrReturn();
mController.deleteMessages(Collections.singletonList(messageToDelete), null);
@ -368,26 +361,12 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
onRefile(mAccount.getArchiveFolderName());
}
private void onToggleColors() {
if (K9.getK9MessageViewTheme() == K9.THEME_DARK) {
K9.setK9MessageViewTheme(K9.THEME_LIGHT);
} else {
K9.setK9MessageViewTheme(K9.THEME_DARK);
}
public void onSpam() {
onRefile(mAccount.getSpamFolderName());
}
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
Context appContext = getActivity().getApplicationContext();
Preferences prefs = Preferences.getPreferences(appContext);
Editor editor = prefs.getPreferences().edit();
K9.save(editor);
editor.commit();
return null;
}
}.execute();
mFragmentListener.restartActivity();
public void onSelectText() {
mMessageView.beginSelectingText();
}
private void startRefileActivity(int activity) {
@ -451,7 +430,7 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
}
}
private void onSendAlternate() {
public void onSendAlternate() {
if (mMessage != null) {
mController.sendAlternate(getActivity(), mAccount, mMessage);
}
@ -464,7 +443,7 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
mMessageView.setHeaders(mMessage, mAccount);
String subject = mMessage.getSubject();
displayMessageSubject(subject);
updateUnreadToggleTitle();
mFragmentListener.updateMenu();
}
}
@ -490,125 +469,6 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
onDelete();
break;
case R.id.reply:
onReply();
break;
case R.id.reply_all:
onReplyAll();
break;
case R.id.forward:
onForward();
break;
case R.id.share:
onSendAlternate();
break;
case R.id.toggle_unread:
onToggleRead();
break;
case R.id.archive:
onRefile(mAccount.getArchiveFolderName());
break;
case R.id.spam:
onRefile(mAccount.getSpamFolderName());
break;
case R.id.move:
onMove();
break;
case R.id.copy:
onCopy();
break;
case R.id.select_text:
mMessageView.beginSelectingText();
break;
case R.id.toggle_message_view_theme:
onToggleColors();
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.message_view_fragment, menu);
mMenu = menu;
configureMenu(menu);
}
private void configureMenu(Menu menu) {
// In Android versions prior to 4.2 onCreateOptionsMenu() (which calls us) is called before
// onActivityCreated() when mAccount isn't initialized yet. In that case we do nothing and
// wait for displayMessage() to call us again.
if (menu == null || mAccount == null) {
return;
}
// enable them all
menu.findItem(R.id.copy).setVisible(true);
menu.findItem(R.id.move).setVisible(true);
menu.findItem(R.id.archive).setVisible(true);
menu.findItem(R.id.spam).setVisible(true);
mToggleMessageViewMenu = menu.findItem(R.id.toggle_message_view_theme);
if (K9.getK9MessageViewTheme() == K9.THEME_DARK) {
mToggleMessageViewMenu.setTitle(R.string.message_view_theme_action_light);
} else {
mToggleMessageViewMenu.setTitle(R.string.message_view_theme_action_dark);
}
toggleActionsState(menu, true);
updateUnreadToggleTitle();
// check message, folder capability
if (!mController.isCopyCapable(mAccount)) {
menu.findItem(R.id.copy).setVisible(false);
}
if (mController.isMoveCapable(mAccount)) {
menu.findItem(R.id.move).setVisible(true);
menu.findItem(R.id.archive).setVisible(
!mMessageReference.folderName.equals(mAccount.getArchiveFolderName())
&& mAccount.hasArchiveFolder());
menu.findItem(R.id.spam).setVisible(
!mMessageReference.folderName.equals(mAccount.getSpamFolderName())
&& mAccount.hasSpamFolder());
} else {
menu.findItem(R.id.copy).setVisible(false);
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
}
}
/**
* Set the title of the "Toggle Unread" menu item based upon the current read state of the message.
*/
public void updateUnreadToggleTitle() {
if (mMessage != null && mMenu != null) {
if (mMessage.isSet(Flag.SEEN)) {
mMenu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_unread_action);
} else {
mMenu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_read_action);
}
}
}
private void toggleActionsState(Menu menu, boolean state) {
for (int i = 0; i < menu.size(); ++i) {
menu.getItem(i).setEnabled(state);
}
}
private void setProgress(boolean enable) {
if (mFragmentListener != null) {
mFragmentListener.setProgress(enable);
@ -694,7 +554,7 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
mMessage = message;
mMessageView.setMessage(account, (LocalMessage) message, mPgpData,
mController, mListener);
updateUnreadToggleTitle();
mFragmentListener.updateMenu();
} catch (MessagingException e) {
Log.v(K9.LOG_TAG, "loadMessageForViewBodyAvailable", e);
@ -909,15 +769,37 @@ public class MessageViewFragment extends SherlockFragment implements OnClickList
return mMessageReference;
}
public boolean isMessageRead() {
return (mMessage != null) ? mMessage.isSet(Flag.SEEN) : false;
}
public boolean isCopyCapable() {
return mController.isCopyCapable(mAccount);
}
public boolean isMoveCapable() {
return mController.isMoveCapable(mAccount);
}
public boolean canMessageBeArchived() {
return (!mMessageReference.folderName.equals(mAccount.getArchiveFolderName())
&& mAccount.hasArchiveFolder());
}
public boolean canMessageBeMovedToSpam() {
return (!mMessageReference.folderName.equals(mAccount.getSpamFolderName())
&& mAccount.hasSpamFolder());
}
public interface MessageViewFragmentListener {
public void onForward(Message mMessage, PgpData mPgpData);
public void disableDeleteAction();
public void onReplyAll(Message mMessage, PgpData mPgpData);
public void onReply(Message mMessage, PgpData mPgpData);
public void displayMessageSubject(String title);
public void setProgress(boolean b);
public void restartActivity();
public void showNextMessageOrReturn();
public void messageHeaderViewAvailable(MessageHeader messageHeaderView);
public void updateMenu();
}
}