From af51eee9b1c3059c8c1b6ad26b9afab3a759272b Mon Sep 17 00:00:00 2001 From: cketti Date: Thu, 31 Jan 2013 04:34:23 +0100 Subject: [PATCH] Get rid of MessageView activity --- AndroidManifest.xml | 7 +- src/com/fsck/k9/activity/MessageList.java | 134 +++- src/com/fsck/k9/activity/MessageView.java | 574 ------------------ .../k9/controller/MessagingController.java | 3 +- 4 files changed, 127 insertions(+), 591 deletions(-) delete mode 100644 src/com/fsck/k9/activity/MessageView.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 14fcea034..df007da6c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -215,18 +215,13 @@ - - Note: + * This method has to be called after {@link #findFragments()} because the result depends on + * the availability of a {@link MessageViewFragment} instance. + *

+ * + * @param savedInstanceState + * The saved instance state that was passed to the activity as argument to + * {@link #onCreate(Bundle)}. May be {@code null}. + */ private void initializeDisplayMode(Bundle savedInstanceState) { if (savedInstanceState != null) { mDisplayMode = (DisplayMode) savedInstanceState.getSerializable(STATE_DISPLAY_MODE); } else { - mDisplayMode = DisplayMode.MESSAGE_LIST; + boolean displayMessage = (mMessageReference != null); + mDisplayMode = (displayMessage) ? DisplayMode.MESSAGE_VIEW : DisplayMode.MESSAGE_LIST; } switch (K9.getSplitViewMode()) { @@ -204,14 +279,15 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme break; } case NEVER: { - // Either use the restored setting or DisplayMode.MESSAGE_LIST set above + // Use the value set at the beginning of this method. break; } case WHEN_IN_LANDSCAPE: { int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_LANDSCAPE) { mDisplayMode = DisplayMode.SPLIT_VIEW; - } else if (mMessageViewFragment != null) { + } else if (mMessageViewFragment != null || + mDisplayMode == DisplayMode.MESSAGE_VIEW) { mDisplayMode = DisplayMode.MESSAGE_VIEW; } else { mDisplayMode = DisplayMode.MESSAGE_LIST; @@ -225,7 +301,9 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme mMessageListContainer = (ViewGroup) findViewById(R.id.message_list_container); mMessageViewContainer = (ViewGroup) findViewById(R.id.message_view_container); mMessageViewPlaceHolder = getLayoutInflater().inflate(R.layout.empty_message_view, null); + } + private void displayViews() { switch (mDisplayMode) { case MESSAGE_LIST: { showMessageList(); @@ -239,6 +317,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme findViewById(R.id.message_list_divider).setVisibility(View.VISIBLE); if (mMessageViewFragment == null) { showMessageViewPlaceHolder(); + } else { + MessageReference activeMessage = mMessageViewFragment.getMessageReference(); + if (activeMessage != null) { + mMessageListFragment.setActiveMessage(activeMessage); + } } break; } @@ -246,7 +329,23 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme } private void decodeExtras(Intent intent) { - if (ACTION_SHORTCUT.equals(intent.getAction())) { + String action = intent.getAction(); + if (Intent.ACTION_VIEW.equals(action)) { + Uri uri = intent.getData(); + List segmentList = uri.getPathSegments(); + + String accountId = segmentList.get(0); + Collection accounts = Preferences.getPreferences(this).getAvailableAccounts(); + for (Account account : accounts) { + if (String.valueOf(account.getAccountNumber()).equals(accountId)) { + mMessageReference = new MessageReference(); + mMessageReference.accountUuid = account.getUuid(); + mMessageReference.folderName = segmentList.get(1); + mMessageReference.uid = segmentList.get(2); + break; + } + } + } else if (ACTION_SHORTCUT.equals(action)) { // Handle shortcut intents String specialFolder = intent.getStringExtra(EXTRA_SPECIAL_FOLDER); if (SearchAccount.UNIFIED_INBOX.equals(specialFolder)) { @@ -268,7 +367,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme mSearch.or(new SearchCondition(Searchfield.SUBJECT, Attribute.CONTAINS, query)); mSearch.or(new SearchCondition(Searchfield.MESSAGE_CONTENTS, Attribute.CONTAINS, query)); - Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA); + Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA); if (appData != null) { mSearch.addAccountUuid(appData.getString(EXTRA_SEARCH_ACCOUNT)); // searches started from a folder list activity will provide an account, but no folder @@ -285,6 +384,16 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme mNoThreading = intent.getBooleanExtra(EXTRA_NO_THREADING, false); } + if (mMessageReference == null) { + mMessageReference = intent.getParcelableExtra(EXTRA_MESSAGE_REFERENCE); + } + + if (mMessageReference != null) { + mSearch = new LocalSearch(); + mSearch.addAccountUuid(mMessageReference.accountUuid); + mSearch.addAllowedFolder(mMessageReference.folderName); + } + String[] accountUuids = mSearch.getAccountUuids(); mSingleAccountMode = (accountUuids.length == 1 && !mSearch.searchAllAccounts()); mSingleFolderMode = mSingleAccountMode && (mSearch.getFolderNames().size() == 1); @@ -1060,6 +1169,13 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme } } + private void removeMessageListFragment() { + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + ft.remove(mMessageListFragment); + mMessageListFragment = null; + ft.commit(); + } + @Override public void remoteSearchStarted() { // Remove action button for remote search diff --git a/src/com/fsck/k9/activity/MessageView.java b/src/com/fsck/k9/activity/MessageView.java deleted file mode 100644 index ecb339751..000000000 --- a/src/com/fsck/k9/activity/MessageView.java +++ /dev/null @@ -1,574 +0,0 @@ -package com.fsck.k9.activity; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; -import com.actionbarsherlock.view.Window; -import com.fsck.k9.Account; -import com.fsck.k9.K9; -import com.fsck.k9.Preferences; -import com.fsck.k9.R; -import com.fsck.k9.activity.misc.SwipeGestureDetector; -import com.fsck.k9.activity.misc.SwipeGestureDetector.OnSwipeGestureListener; -import com.fsck.k9.controller.MessagingController; -import com.fsck.k9.crypto.PgpData; -import com.fsck.k9.fragment.MessageViewFragment; -import com.fsck.k9.fragment.MessageViewFragment.MessageViewFragmentListener; -import com.fsck.k9.mail.Message; -import com.fsck.k9.mail.store.StorageManager; -import com.fsck.k9.view.MessageHeader; -import com.fsck.k9.view.MessageTitleView; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Toast; - - -public class MessageView extends K9FragmentActivity implements MessageViewFragmentListener, - OnSwipeGestureListener { - - private static final String EXTRA_MESSAGE_REFERENCE = "com.fsck.k9.MessageView_messageReference"; - private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences"; - private static final String EXTRA_FROM_NOTIFICATION ="com.fsck.k9.MessageView_fromNotification"; - - /** - * @see #mLastDirection - */ - private static final int PREVIOUS = 1; - private static final int NEXT = 2; - - - public static Intent actionViewIntent(Context context, MessageReference messRef, - ArrayList messReferences) { - Intent i = new Intent(context, MessageView.class); - i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - i.putExtra(EXTRA_MESSAGE_REFERENCE, messRef); - i.putParcelableArrayListExtra(EXTRA_MESSAGE_REFERENCES, messReferences); - return i; - } - - public static Intent actionHandleNotificationIntent(Context context, MessageReference ref) { - Intent i = actionViewIntent(context, ref, null); - i.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); - i.putExtra(EXTRA_FROM_NOTIFICATION, true); - return i; - } - - private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation(); - private Account mAccount; - private MessageTitleView mTitleView; - private MessageReference mMessageReference; - private ArrayList mMessageReferences; - private int mLastDirection = (K9.messageViewShowNext()) ? NEXT : PREVIOUS; - private MessageReference mNextMessage; - private MessageReference mPreviousMessage; - private MessageViewFragment mMessageViewFragment; - private Menu mMenu; - - /** - * Used to detect right-to-left bezel swipes. - * - * @see #onSwipeRightToLeft(MotionEvent, MotionEvent) - */ - private int mRightBezelThreshold; - - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTheme(K9.getK9ThemeResourceId(K9.getK9MessageViewTheme())); - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - setContentView(R.layout.message_view); - - initializeActionBar(); - setTitle(""); - - int screenWidth = getResources().getDisplayMetrics().widthPixels; - mRightBezelThreshold = screenWidth - SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD; - - // Enable gesture detection for MessageViews - if (K9.gesturesEnabled()) { - setupGestureDetector(this); - } - - final Intent intent = getIntent(); - - Uri uri = intent.getData(); - if (savedInstanceState != null) { - mMessageReference = savedInstanceState.getParcelable(EXTRA_MESSAGE_REFERENCE); - mMessageReferences = savedInstanceState.getParcelableArrayList(EXTRA_MESSAGE_REFERENCES); - } else { - if (uri == null) { - mMessageReference = intent.getParcelableExtra(EXTRA_MESSAGE_REFERENCE); - mMessageReferences = intent.getParcelableArrayListExtra(EXTRA_MESSAGE_REFERENCES); - } else { - List segmentList = uri.getPathSegments(); - if (segmentList.size() != 3) { - //TODO: Use resource to externalize message - Toast.makeText(this, "Invalid intent uri: " + uri.toString(), Toast.LENGTH_LONG).show(); - return; - } - - String accountId = segmentList.get(0); - Collection accounts = Preferences.getPreferences(this).getAvailableAccounts(); - for (Account account : accounts) { - if (String.valueOf(account.getAccountNumber()).equals(accountId)) { - mMessageReference = new MessageReference(); - mMessageReference.accountUuid = account.getUuid(); - mMessageReference.folderName = segmentList.get(1); - mMessageReference.uid = segmentList.get(2); - mMessageReferences = new ArrayList(); - mAccount = account; - break; - } - } - - if (mMessageReference == null) { - //TODO: Use resource to externalize message - Toast.makeText(this, "Invalid account id: " + accountId, Toast.LENGTH_LONG).show(); - return; - } - } - } - - if (mAccount == null) { - Preferences preferences = Preferences.getPreferences(getApplicationContext()); - mAccount = preferences.getAccount(mMessageReference.accountUuid); - } - - findSurroundingMessagesUid(); - - - FragmentManager fragmentManager = getSupportFragmentManager(); - - mMessageViewFragment = (MessageViewFragment) fragmentManager.findFragmentById(R.id.message); - - if (mMessageViewFragment == null) { - FragmentTransaction ft = fragmentManager.beginTransaction(); - mMessageViewFragment = MessageViewFragment.newInstance(mMessageReference); - ft.add(R.id.message, mMessageViewFragment); - ft.commit(); - } - } - - @Override - public void onResume() { - super.onResume(); - if (!mAccount.isAvailable(this)) { - onAccountUnavailable(); - return; - } - if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) { - MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount); - } - StorageManager.getInstance(getApplication()).addListener(mStorageListener); - } - - @Override - protected void onPause() { - StorageManager.getInstance(getApplication()).removeListener(mStorageListener); - super.onPause(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putParcelable(EXTRA_MESSAGE_REFERENCE, mMessageReference); - outState.putParcelableArrayList(EXTRA_MESSAGE_REFERENCES, mMessageReferences); - } - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - - getSupportMenuInflater().inflate(R.menu.message_view_option, menu); - mMenu = menu; - configureMenu(menu); - - return true; - } - - private void configureMenu(Menu menu) { - if (menu == null) { - return; - } - - if (mNextMessage != null) { - menu.findItem(R.id.next_message).setEnabled(true); - menu.findItem(R.id.next_message).getIcon().setAlpha(255); - } else { - menu.findItem(R.id.next_message).getIcon().setAlpha(127); - menu.findItem(R.id.next_message).setEnabled(false); - } - - if (mPreviousMessage != null) { - menu.findItem(R.id.previous_message).setEnabled(true); - menu.findItem(R.id.previous_message).getIcon().setAlpha(255); - } else { - menu.findItem(R.id.previous_message).getIcon().setAlpha(127); - menu.findItem(R.id.previous_message).setEnabled(false); - } - } - - private void toggleActionsState(Menu menu, boolean state) { - for (int i = 0; i < menu.size(); ++i) { - menu.getItem(i).setEnabled(state); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: { - finish(); - break; - } - case R.id.next_message: { - onNext(); - break; - } - case R.id.previous_message: { - onPrevious(); - break; - } - default: { - return super.onOptionsItemSelected(item); - } - } - - return true; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - boolean ret = false; - if (KeyEvent.ACTION_DOWN == event.getAction()) { - ret = onCustomKeyDown(event.getKeyCode(), event); - } - if (!ret) { - ret = super.dispatchKeyEvent(event); - } - return ret; - } - - /** - * Handle hotkeys - * - *

- * This method is called by {@link #dispatchKeyEvent(KeyEvent)} before any view had the chance - * to consume this key event. - *

- * - * @param keyCode - * The value in {@code event.getKeyCode()}. - * @param event - * Description of the key event. - * - * @return {@code true} if this event was consumed. - */ - public boolean onCustomKeyDown(final int keyCode, final KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: { - if (K9.useVolumeKeysForNavigationEnabled()) { - onNext(); - return true; - } - break; - } - case KeyEvent.KEYCODE_VOLUME_DOWN: { - if (K9.useVolumeKeysForNavigationEnabled()) { - onPrevious(); - return true; - } - break; - } - case KeyEvent.KEYCODE_DEL: - case KeyEvent.KEYCODE_D: { - mMessageViewFragment.onDelete(); - return true; - } - case KeyEvent.KEYCODE_F: { - mMessageViewFragment.onForward(); - return true; - } - case KeyEvent.KEYCODE_A: { - mMessageViewFragment.onReplyAll(); - return true; - } - case KeyEvent.KEYCODE_R: { - mMessageViewFragment.onReply(); - return true; - } - case KeyEvent.KEYCODE_G: { - mMessageViewFragment.onToggleFlagged(); - return true; - } - case KeyEvent.KEYCODE_M: { - mMessageViewFragment.onMove(); - return true; - } - case KeyEvent.KEYCODE_S: { - mMessageViewFragment.onRefile(mAccount.getSpamFolderName()); - return true; - } - case KeyEvent.KEYCODE_V: { - mMessageViewFragment.onRefile(mAccount.getArchiveFolderName()); - return true; - } - case KeyEvent.KEYCODE_Y: { - mMessageViewFragment.onCopy(); - return true; - } - case KeyEvent.KEYCODE_J: - case KeyEvent.KEYCODE_P: { - onPrevious(); - return true; - } - case KeyEvent.KEYCODE_N: - case KeyEvent.KEYCODE_K: { - onNext(); - return true; - } - case KeyEvent.KEYCODE_Z: { - mMessageViewFragment.zoom(event); - return true; - } - case KeyEvent.KEYCODE_H: { - Toast toast = Toast.makeText(this, R.string.message_help_key, Toast.LENGTH_LONG); - toast.show(); - return true; - } - } - return false; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - // Swallow these events too to avoid the audible notification of a volume change - if (K9.useVolumeKeysForNavigationEnabled()) { - if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) { - if (K9.DEBUG) { - Log.v(K9.LOG_TAG, "Swallowed key up."); - } - return true; - } - } - return super.onKeyUp(keyCode, event); - } - - protected void onAccountUnavailable() { - finish(); - // TODO inform user about account unavailability using Toast - Accounts.listAccounts(this); - } - - private void initializeActionBar() { - final ActionBar actionBar = getSupportActionBar(); - - actionBar.setDisplayHomeAsUpEnabled(true); - actionBar.setDisplayShowCustomEnabled(true); - actionBar.setCustomView(R.layout.actionbar_message_view); - - final View customView = actionBar.getCustomView(); - mTitleView = (MessageTitleView) customView.findViewById(android.R.id.title); - } - - @Override - public void messageHeaderViewAvailable(MessageHeader header) { - mTitleView.setMessageHeader(header); - } - - /** - * Set the title of the view. - * - *

Since we're using a custom ActionBar view, the normal {@code setTitle()} doesn't do what - * we think. This version sets the text value into the proper ActionBar title view.

- * - * @param title - * Title to set. - */ - @Override - public void setTitle(CharSequence title) { - mTitleView.setText(title); - } - - @Override - public void setProgress(boolean enable) { - setSupportProgressBarIndeterminateVisibility(enable); - } - - /** - * Handle a right-to-left swipe starting at the edge of the screen as "move to next message." - */ - @Override - public void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) { - if ((int) e1.getRawX() > mRightBezelThreshold) { - onNext(); - } - } - - /** - * Handle a left-to-right swipe starting at the edge of the screen as - * "move to previous message." - */ - @Override - public void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) { - if ((int) e1.getRawX() < SwipeGestureDetector.BEZEL_SWIPE_THRESHOLD) { - onPrevious(); - } - } - - @Override - public void showNextMessageOrReturn() { - if (K9.messageViewReturnToList()) { - finish(); - } else { - showNextMessage(); - } - } - - private void showNextMessage() { - findSurroundingMessagesUid(); - if (mMessageReferences != null) { - mMessageReferences.remove(mMessageReference); - } - if (mLastDirection == NEXT && mNextMessage != null) { - onNext(); - } else if (mLastDirection == PREVIOUS && mPreviousMessage != null) { - onPrevious(); - } else if (mNextMessage != null) { - onNext(); - } else if (mPreviousMessage != null) { - onPrevious(); - } else { - finish(); - } - } - - protected void onNext() { - // Reset scroll percentage when we change messages - if (mNextMessage == null) { - Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show(); - return; - } - mLastDirection = NEXT; - toggleActionsState(mMenu, false); -// if (K9.showAnimations()) { -// mMessageView.startAnimation(outToLeftAnimation()); -// } - displayMessage(mNextMessage); - } - - protected void onPrevious() { - // Reset scroll percentage when we change messages - if (mPreviousMessage == null) { - Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show(); - return; - } - mLastDirection = PREVIOUS; - toggleActionsState(mMenu, false); -// if (K9.showAnimations()) { -// mMessageView.startAnimation(inFromRightAnimation()); -// } - displayMessage(mPreviousMessage); - } - - private void displayMessage(MessageReference reference) { - mMessageReference = reference; - findSurroundingMessagesUid(); - configureMenu(mMenu); - mMessageViewFragment.displayMessage(reference); - } - - - private void findSurroundingMessagesUid() { - mNextMessage = mPreviousMessage = null; - - if (mMessageReferences == null) { - return; - } - - int i = mMessageReferences.indexOf(mMessageReference); - if (i < 0) { - return; - } - - if (i != 0) { - mNextMessage = mMessageReferences.get(i - 1); - } - - if (i != (mMessageReferences.size() - 1)) { - mPreviousMessage = mMessageReferences.get(i + 1); - } - } - - - private final class StorageListenerImplementation implements StorageManager.StorageListener { - @Override - public void onUnmount(String providerId) { - if (!providerId.equals(mAccount.getLocalStorageProviderId())) { - return; - } - runOnUiThread(new Runnable() { - @Override - public void run() { - onAccountUnavailable(); - } - }); - } - - @Override - public void onMount(String providerId) { /* no-op */ } - } - - @Override - public void displayMessageSubject(String subject) { - setTitle(subject); - } - - @Override - public void onReply(Message message, PgpData pgpData) { - MessageCompose.actionReply(this, mAccount, message, false, pgpData.getDecryptedData()); - finish(); - } - - @Override - public void onReplyAll(Message message, PgpData pgpData) { - MessageCompose.actionReply(this, mAccount, message, true, pgpData.getDecryptedData()); - finish(); - } - - @Override - public void onForward(Message mMessage, PgpData mPgpData) { - 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 - } -} diff --git a/src/com/fsck/k9/controller/MessagingController.java b/src/com/fsck/k9/controller/MessagingController.java index bd041eaf8..d73522e66 100644 --- a/src/com/fsck/k9/controller/MessagingController.java +++ b/src/com/fsck/k9/controller/MessagingController.java @@ -50,7 +50,6 @@ import com.fsck.k9.R; import com.fsck.k9.activity.FolderList; import com.fsck.k9.activity.MessageList; import com.fsck.k9.activity.MessageReference; -import com.fsck.k9.activity.MessageView; import com.fsck.k9.activity.NotificationDeleteConfirmation; import com.fsck.k9.helper.Contacts; import com.fsck.k9.helper.power.TracingPowerManager; @@ -4831,7 +4830,7 @@ public class MessagingController implements Runnable { } if (treatAsSingleMessageNotification) { - targetIntent = MessageView.actionHandleNotificationIntent( + targetIntent = MessageList.actionHandleNotificationIntent( context, message.makeMessageReference()); } else { String initialFolder = message.getFolder().getName();