/** Called from UI thread when user select Delete */ public void onDelete() { if (K9.confirmDelete() || (K9.confirmDeleteStarred() && mMessage.isSet(Flag.FLAGGED))) { showDialog(R.id.dialog_confirm_delete); } else { delete(); } }
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Shortcuts that work no matter what is selected if ( // TODO - when we move to android 2.0, uncomment this. // android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && K9.manageBack()) { // Take care of calling this method on earlier versions of // the platform where it doesn't exist. onBackPressed(); return true; } switch (keyCode) { case KeyEvent.KEYCODE_Q: // case KeyEvent.KEYCODE_BACK: { onAccounts(); return true; } case KeyEvent.KEYCODE_S: { onEditAccount(); return true; } case KeyEvent.KEYCODE_H: { Toast toast = Toast.makeText(this, R.string.folder_list_help_key, Toast.LENGTH_LONG); toast.show(); return true; } case KeyEvent.KEYCODE_1: { setDisplayMode(FolderMode.FIRST_CLASS); return true; } case KeyEvent.KEYCODE_2: { setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS); return true; } case KeyEvent.KEYCODE_3: { setDisplayMode(FolderMode.NOT_SECOND_CLASS); return true; } case KeyEvent.KEYCODE_4: { setDisplayMode(FolderMode.ALL); return true; } } // switch return super.onKeyDown(keyCode, event); } // onKeyDown
@Override public boolean onCreate() { mMessageHelper = MessageHelper.getInstance(getContext()); registerQueryHandler(new ThrottlingQueryHandler(new AccountsQueryHandler())); registerQueryHandler(new ThrottlingQueryHandler(new MessagesQueryHandler())); registerQueryHandler(new ThrottlingQueryHandler(new UnreadQueryHandler())); K9.registerApplicationAware( new K9.ApplicationAware() { @Override public void initializeComponent(final K9 application) { Log.v(K9.LOG_TAG, "Registering content resolver notifier"); MessagingController.getInstance(application) .addListener( new MessagingListener() { @Override public void searchStats(final AccountStats stats) { application.getContentResolver().notifyChange(CONTENT_URI, null); } }); } }); return true; }
private boolean useSplitView() { SplitViewMode splitViewMode = K9.getSplitViewMode(); int orientation = getResources().getConfiguration().orientation; return (splitViewMode == SplitViewMode.ALWAYS || (splitViewMode == SplitViewMode.WHEN_IN_LANDSCAPE && orientation == Configuration.ORIENTATION_LANDSCAPE)); }
/** * Loads the last known database version of the accounts' databases from a {@link * SharedPreference}. * * <p>If the stored version matches {@link LocalStore#DB_VERSION} we know that the databases are * up to date.<br> * Using {@code SharedPreferences} should be a lot faster than opening all SQLite databases to get * the current database version. * * <p>See {@link UpgradeDatabases} for a detailed explanation of the database upgrade process. * * @see #areDatabasesUpToDate() */ public void checkCachedDatabaseVersion() { sDatabaseVersionCache = getSharedPreferences(DATABASE_VERSION_CACHE, MODE_PRIVATE); int cachedVersion = sDatabaseVersionCache.getInt(KEY_LAST_ACCOUNT_DATABASE_VERSION, 0); if (cachedVersion >= LocalStore.DB_VERSION) { K9.setDatabasesUpToDate(false); } }
@Override public void showNextMessageOrReturn() { if (K9.messageViewReturnToList() || !showNextMessage()) { if (mDisplayMode == DisplayMode.SPLIT_VIEW) { showMessageViewPlaceHolder(); } else { showMessageList(); } } }
@Override public Integer receive(Context context, Intent intent, Integer tmpWakeLockId) { if (K9.DEBUG) Log.i(K9.LOG_TAG, "BootReceiver.onReceive" + intent); final String action = intent.getAction(); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { // K9.setServicesEnabled(context, tmpWakeLockId); // tmpWakeLockId = null; } else if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) { MailService.actionCancel(context, tmpWakeLockId); tmpWakeLockId = null; } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) { MailService.actionReset(context, tmpWakeLockId); tmpWakeLockId = null; } else if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { MailService.connectivityChange(context, tmpWakeLockId); tmpWakeLockId = null; } else if ("com.android.sync.SYNC_CONN_STATUS_CHANGED".equals(action)) { K9.BACKGROUND_OPS bOps = K9.getBackgroundOps(); if (bOps == K9.BACKGROUND_OPS.WHEN_CHECKED_AUTO_SYNC) { MailService.actionReset(context, tmpWakeLockId); tmpWakeLockId = null; } } else if (FIRE_INTENT.equals(action)) { Intent alarmedIntent = intent.getParcelableExtra(ALARMED_INTENT); String alarmedAction = alarmedIntent.getAction(); if (K9.DEBUG) Log.i(K9.LOG_TAG, "BootReceiver Got alarm to fire alarmedIntent " + alarmedAction); alarmedIntent.putExtra(WAKE_LOCK_ID, tmpWakeLockId); tmpWakeLockId = null; context.startService(alarmedIntent); } else if (SCHEDULE_INTENT.equals(action)) { long atTime = intent.getLongExtra(AT_TIME, -1); Intent alarmedIntent = intent.getParcelableExtra(ALARMED_INTENT); if (K9.DEBUG) Log.i( K9.LOG_TAG, "BootReceiver Scheduling intent " + alarmedIntent + " for " + new Date(atTime)); PendingIntent pi = buildPendingIntent(context, intent); K9AlarmManager alarmMgr = K9AlarmManager.getAlarmManager(context); alarmMgr.set(AlarmManager.RTC_WAKEUP, atTime, pi); } else if (CANCEL_INTENT.equals(action)) { Intent alarmedIntent = intent.getParcelableExtra(ALARMED_INTENT); if (K9.DEBUG) Log.i(K9.LOG_TAG, "BootReceiver Canceling alarmedIntent " + alarmedIntent); PendingIntent pi = buildPendingIntent(context, intent); K9AlarmManager alarmMgr = K9AlarmManager.getAlarmManager(context); alarmMgr.cancel(pi); } return tmpWakeLockId; }
private void configureMenu(Menu menu) { // first run displayMessage() gets called before onCreateOptionMenu() if (menu == 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(); // comply with the setting if (!mAccount.getEnableMoveButtons()) { menu.findItem(R.id.move).setVisible(false); menu.findItem(R.id.archive).setVisible(false); menu.findItem(R.id.spam).setVisible(false); } else { // 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); } } }
private void onChooseContactNameColor() { new ColorPickerDialog( this, new ColorPickerDialog.OnColorChangedListener() { public void colorChanged(int color) { K9.setContactNameColor(color); } }, K9.getContactNameColor()) .show(); }
@Override public boolean onKeyUp(int keyCode, KeyEvent event) { // Swallow these events too to avoid the audible notification of a volume change if (K9.useVolumeKeysForListNavigationEnabled()) { 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); }
private void onToggleColors() { if (K9.getK9MessageViewTheme() == K9.THEME_DARK) { K9.setK9MessageViewTheme(K9.THEME_LIGHT); } else { K9.setK9MessageViewTheme(K9.THEME_DARK); } 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(); }
@Override public void onBackPressed() { // This will be called either automatically for you on 2.0 // or later, or by the code above on earlier versions of the // platform. if (K9.manageBack()) { onAccounts(); } else { // TODO - when we move to android 2.0, uncomment this instead. // super.onBackPressed() finish(); } }
private void onToggleTheme() { if (K9.getK9MessageViewTheme() == K9.Theme.DARK) { K9.setK9MessageViewThemeSetting(K9.Theme.LIGHT); } else { K9.setK9MessageViewThemeSetting(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(); }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case ACTIVITY_CHOOSE_FOLDER: if (resultCode == RESULT_OK && data != null) { // obtain the filename Uri fileUri = data.getData(); if (fileUri != null) { String filePath = fileUri.getPath(); if (filePath != null) { mAttachmentPathPreference.setSummary(filePath.toString()); K9.setAttachmentDefaultPath(filePath.toString()); } } } break; } super.onActivityResult(requestCode, resultCode, data); }
/** * Create fragment instances if necessary. * * @see #findFragments() */ private void initializeFragments() { FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.addOnBackStackChangedListener(this); boolean hasMessageListFragment = (mMessageListFragment != null); if (!hasMessageListFragment) { FragmentTransaction ft = fragmentManager.beginTransaction(); mMessageListFragment = MessageListFragment.newInstance( mSearch, false, (K9.isThreadedViewEnabled() && !mNoThreading)); ft.add(R.id.message_list_container, mMessageListFragment); ft.commit(); } // Check if the fragment wasn't restarted and has a MessageReference in the arguments. If // so, open the referenced message. if (!hasMessageListFragment && mMessageViewFragment == null && mMessageReference != null) { openMessage(mMessageReference); } }
private void onDone() { mAccount.setDescription(mAccount.getEmail()); mAccount.setNotifyNewMail(mNotifyView.isChecked()); mAccount.setShowOngoing(mNotifySyncView.isChecked()); mAccount.setAutomaticCheckIntervalMinutes( (Integer) ((SpinnerOption) mCheckFrequencyView.getSelectedItem()).value); mAccount.setDisplayCount((Integer) ((SpinnerOption) mDisplayCountView.getSelectedItem()).value); if (mPushEnable.isChecked()) { mAccount.setFolderPushMode(Account.FolderMode.FIRST_CLASS); } else { mAccount.setFolderPushMode(Account.FolderMode.NONE); } mAccount.save(Preferences.getPreferences(this)); if (mAccount.equals(Preferences.getPreferences(this).getDefaultAccount()) || getIntent().getBooleanExtra(EXTRA_MAKE_DEFAULT, false)) { Preferences.getPreferences(this).setDefaultAccount(mAccount); } K9.setServicesEnabled(this); AccountSetupNames.actionSetNames(this, mAccount); finish(); }
public void onRefile(String dstFolder) { if (!mController.isMoveCapable(mAccount)) { return; } if (!mController.isMoveCapable(mMessage)) { Toast toast = Toast.makeText( getActivity(), R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); toast.show(); return; } if (K9.FOLDER_NONE.equalsIgnoreCase(dstFolder)) { return; } if (mAccount.getSpamFolderName().equals(dstFolder) && K9.confirmSpam()) { mDstFolder = dstFolder; showDialog(R.id.dialog_confirm_spam); } else { refileMessage(dstFolder); } }
private void onOpenFolder(String folder) { MessageList.actionHandleFolder(this, mAccount, folder); if (K9.manageBack()) { finish(); } }
/** * Handle hotkeys * * <p>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 (mMessageViewFragment != null && mDisplayMode != DisplayMode.MESSAGE_LIST && K9.useVolumeKeysForNavigationEnabled()) { showPreviousMessage(); return true; } else if (mDisplayMode != DisplayMode.MESSAGE_VIEW && K9.useVolumeKeysForListNavigationEnabled()) { mMessageListFragment.onMoveUp(); return true; } break; } case KeyEvent.KEYCODE_VOLUME_DOWN: { if (mMessageViewFragment != null && mDisplayMode != DisplayMode.MESSAGE_LIST && K9.useVolumeKeysForNavigationEnabled()) { showNextMessage(); return true; } else if (mDisplayMode != DisplayMode.MESSAGE_VIEW && K9.useVolumeKeysForListNavigationEnabled()) { mMessageListFragment.onMoveDown(); return true; } break; } case KeyEvent.KEYCODE_C: { mMessageListFragment.onCompose(); return true; } case KeyEvent.KEYCODE_Q: { onShowFolderList(); return true; } case KeyEvent.KEYCODE_O: { mMessageListFragment.onCycleSort(); return true; } case KeyEvent.KEYCODE_I: { mMessageListFragment.onReverseSort(); return true; } case KeyEvent.KEYCODE_DEL: case KeyEvent.KEYCODE_D: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onDelete(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onDelete(); } return true; } case KeyEvent.KEYCODE_S: { mMessageListFragment.toggleMessageSelect(); return true; } case KeyEvent.KEYCODE_G: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onToggleFlagged(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onToggleFlagged(); } return true; } case KeyEvent.KEYCODE_M: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onMove(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onMove(); } return true; } case KeyEvent.KEYCODE_V: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onArchive(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onArchive(); } return true; } case KeyEvent.KEYCODE_Y: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onCopy(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onCopy(); } return true; } case KeyEvent.KEYCODE_Z: { if (mDisplayMode == DisplayMode.MESSAGE_LIST) { mMessageListFragment.onToggleRead(); } else if (mMessageViewFragment != null) { mMessageViewFragment.onToggleRead(); } return true; } case KeyEvent.KEYCODE_F: { if (mMessageViewFragment != null) { mMessageViewFragment.onForward(); } return true; } case KeyEvent.KEYCODE_A: { if (mMessageViewFragment != null) { mMessageViewFragment.onReplyAll(); } return true; } case KeyEvent.KEYCODE_R: { if (mMessageViewFragment != null) { mMessageViewFragment.onReply(); } return true; } case KeyEvent.KEYCODE_J: case KeyEvent.KEYCODE_P: { if (mMessageViewFragment != null) { showPreviousMessage(); } return true; } case KeyEvent.KEYCODE_N: case KeyEvent.KEYCODE_K: { if (mMessageViewFragment != null) { showNextMessage(); } return true; } /* FIXME case KeyEvent.KEYCODE_Z: { mMessageViewFragment.zoom(event); return true; }*/ case KeyEvent.KEYCODE_H: { Toast toast = Toast.makeText(this, R.string.message_list_help_key, Toast.LENGTH_LONG); toast.show(); return true; } } return false; }
public class LauncherShortcuts extends K9ListActivity implements OnItemClickListener { private AccountsAdapter mAdapter; private FontSizes mFontSizes = K9.getFontSizes(); @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // finish() immediately if we aren't supposed to be here if (!Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { finish(); return; } setContentView(R.layout.launcher_shortcuts); ListView listView = getListView(); listView.setOnItemClickListener(this); listView.setItemsCanFocus(false); refresh(); } private void refresh() { Account[] accounts = Preferences.getPreferences(this).getAccounts(); mAdapter = new AccountsAdapter(accounts); getListView().setAdapter(mAdapter); } private void setupShortcut(Account account) { final Intent shortcutIntent = FolderList.actionHandleAccountIntent(this, account, null, true); Intent intent = new Intent(); intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); String description = account.getDescription(); if (description == null || description.length() == 0) { description = account.getEmail(); } intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, description); Parcelable iconResource = Intent.ShortcutIconResource.fromContext(this, R.drawable.icon); intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); setResult(RESULT_OK, intent); finish(); } public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Account account = (Account) parent.getItemAtPosition(position); setupShortcut(account); } class AccountsAdapter extends ArrayAdapter<Account> { public AccountsAdapter(Account[] accounts) { super(LauncherShortcuts.this, 0, accounts); } @Override public View getView(int position, View convertView, ViewGroup parent) { final BaseAccount account = getItem(position); View view; if (convertView != null) { view = convertView; } else { view = getLayoutInflater().inflate(R.layout.accounts_item, parent, false); } AccountViewHolder holder = (AccountViewHolder) view.getTag(); if (holder == null) { holder = new AccountViewHolder(); holder.description = (TextView) view.findViewById(R.id.description); holder.email = (TextView) view.findViewById(R.id.email); holder.newMessageCount = (TextView) view.findViewById(R.id.new_message_count); holder.flaggedMessageCount = (TextView) view.findViewById(R.id.flagged_message_count); holder.activeIcons = (RelativeLayout) view.findViewById(R.id.active_icons); holder.chip = view.findViewById(R.id.chip); holder.folders = (ImageButton) view.findViewById(R.id.folders); view.setTag(holder); } if (account.getEmail().equals(account.getDescription())) { holder.email.setVisibility(View.GONE); } else { holder.email.setVisibility(View.VISIBLE); holder.email.setText(account.getEmail()); } String description = account.getDescription(); if (description == null || description.length() == 0) { description = account.getEmail(); } holder.description.setText(description); holder.newMessageCount.setVisibility(View.GONE); holder.flaggedMessageCount.setVisibility(View.GONE); if (account instanceof Account) { Account realAccount = (Account) account; holder.chip.setBackgroundColor(realAccount.getChipColor()); holder.chip.getBackground().setAlpha(255); } else { holder.chip.setBackgroundColor(0x00000000); } holder.description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getAccountName()); holder.email.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getAccountDescription()); holder.folders.setVisibility(View.VISIBLE); holder.folders.setOnClickListener( new OnClickListener() { public void onClick(View v) { FolderList.actionHandleAccount(LauncherShortcuts.this, (Account) account); } }); return view; } class AccountViewHolder { public TextView description; public TextView email; public TextView newMessageCount; public TextView flaggedMessageCount; public RelativeLayout activeIcons; public View chip; public ImageButton folders; } } }
/** * 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. * * @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 (mDisplayMode == DisplayMode.MESSAGE_LIST || mMessageViewFragment == null || !mMessageViewFragment.isInitialized()) { menu.findItem(R.id.next_message).setVisible(false); menu.findItem(R.id.previous_message).setVisible(false); menu.findItem(R.id.delete).setVisible(false); menu.findItem(R.id.single_message_options).setVisible(false); menu.findItem(R.id.refile).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); menu.findItem(R.id.show_headers).setVisible(false); menu.findItem(R.id.hide_headers).setVisible(false); } else { // hide prev/next buttons in split mode if (mDisplayMode != DisplayMode.MESSAGE_VIEW) { menu.findItem(R.id.next_message).setVisible(false); menu.findItem(R.id.previous_message).setVisible(false); } else { MessageReference ref = mMessageViewFragment.getMessageReference(); boolean initialized = (mMessageListFragment != null && mMessageListFragment.isLoadFinished()); boolean canDoPrev = (initialized && !mMessageListFragment.isFirst(ref)); boolean canDoNext = (initialized && !mMessageListFragment.isLast(ref)); MenuItem prev = menu.findItem(R.id.previous_message); prev.setEnabled(canDoPrev); prev.getIcon().setAlpha(canDoPrev ? 255 : 127); MenuItem next = menu.findItem(R.id.next_message); next.setEnabled(canDoNext); next.getIcon().setAlpha(canDoNext ? 255 : 127); } MenuItem toggleTheme = menu.findItem(R.id.toggle_message_view_theme); if (K9.useFixedMessageViewTheme()) { toggleTheme.setVisible(false); } else { // Set title of menu item to switch to dark/light 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()); // Jellybean has built-in long press selection support menu.findItem(R.id.select_text).setVisible(Build.VERSION.SDK_INT < 16); 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); } if (mMessageViewFragment.allHeadersVisible()) { menu.findItem(R.id.show_headers).setVisible(false); } else { menu.findItem(R.id.hide_headers).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 (mDisplayMode == DisplayMode.MESSAGE_VIEW || mMessageListFragment == null || !mMessageListFragment.isInitialized()) { 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); } else { menu.findItem(R.id.set_sort).setVisible(true); menu.findItem(R.id.select_all).setVisible(true); 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); } else { 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()); } 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 on the server if (!mMessageListFragment.isRemoteSearch() && mMessageListFragment.isRemoteSearchAllowed()) { menu.findItem(R.id.search_remote).setVisible(true); } else if (!mMessageListFragment.isManualSearch()) { menu.findItem(R.id.search).setVisible(true); } } }
private void saveSettings() { SharedPreferences preferences = Preferences.getPreferences(this).getPreferences(); K9.setK9Language(mLanguage.getValue()); K9.setK9Theme(themeNameToId(mTheme.getValue())); K9.setUseFixedMessageViewTheme(mFixedMessageTheme.isChecked()); K9.setK9MessageViewThemeSetting(themeNameToId(mMessageTheme.getValue())); K9.setK9ComposerThemeSetting(themeNameToId(mComposerTheme.getValue())); K9.setAnimations(mAnimations.isChecked()); K9.setGesturesEnabled(mGestures.isChecked()); K9.setUseVolumeKeysForNavigation(mVolumeNavigation.getCheckedItems()[0]); K9.setUseVolumeKeysForListNavigation(mVolumeNavigation.getCheckedItems()[1]); K9.setStartIntegratedInbox( !mHideSpecialAccounts.isChecked() && mStartIntegratedInbox.isChecked()); K9.setNotificationHideSubject( NotificationHideSubject.valueOf(mNotificationHideSubject.getValue())); int index = 0; K9.setConfirmDelete(mConfirmActions.getCheckedItems()[index++]); K9.setConfirmDeleteStarred(mConfirmActions.getCheckedItems()[index++]); if (NotificationController.platformSupportsExtendedNotifications()) { K9.setConfirmDeleteFromNotification(mConfirmActions.getCheckedItems()[index++]); } K9.setConfirmSpam(mConfirmActions.getCheckedItems()[index++]); K9.setConfirmDiscardMessage(mConfirmActions.getCheckedItems()[index++]); K9.setMeasureAccounts(mMeasureAccounts.isChecked()); K9.setCountSearchMessages(mCountSearch.isChecked()); K9.setHideSpecialAccounts(mHideSpecialAccounts.isChecked()); K9.setMessageListPreviewLines(Integer.parseInt(mPreviewLines.getValue())); K9.setMessageListCheckboxes(mCheckboxes.isChecked()); K9.setMessageListStars(mStars.isChecked()); K9.setShowCorrespondentNames(mShowCorrespondentNames.isChecked()); K9.setMessageListSenderAboveSubject(mSenderAboveSubject.isChecked()); K9.setShowContactName(mShowContactName.isChecked()); K9.setShowContactPicture(mShowContactPicture.isChecked()); K9.setColorizeMissingContactPictures(mColorizeMissingContactPictures.isChecked()); K9.setUseBackgroundAsUnreadIndicator(mBackgroundAsUnreadIndicator.isChecked()); K9.setThreadedViewEnabled(mThreadedView.isChecked()); K9.setChangeContactNameColor(mChangeContactNameColor.isChecked()); K9.setMessageViewFixedWidthFont(mFixedWidth.isChecked()); K9.setMessageViewReturnToList(mReturnToList.isChecked()); K9.setMessageViewShowNext(mShowNext.isChecked()); K9.setAutofitWidth(mAutofitWidth.isChecked()); K9.setQuietTimeEnabled(mQuietTimeEnabled.isChecked()); boolean[] enabledRefileActions = mVisibleRefileActions.getCheckedItems(); K9.setMessageViewDeleteActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_DELETE]); K9.setMessageViewArchiveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_ARCHIVE]); K9.setMessageViewMoveActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_MOVE]); K9.setMessageViewCopyActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_COPY]); K9.setMessageViewSpamActionVisible(enabledRefileActions[VISIBLE_REFILE_ACTIONS_SPAM]); K9.setCheckMailDuringDoze(checkMailDuringDoze.isChecked()); K9.setNotificationDuringQuietTimeEnabled(!mDisableNotificationDuringQuietTime.isChecked()); K9.setQuietTimeStarts(mQuietTimeStarts.getTime()); K9.setQuietTimeEnds(mQuietTimeEnds.getTime()); K9.setWrapFolderNames(mWrapFolderNames.isChecked()); if (mNotificationQuickDelete != null) { K9.setNotificationQuickDeleteBehaviour( NotificationQuickDelete.valueOf(mNotificationQuickDelete.getValue())); } if (mLockScreenNotificationVisibility != null) { K9.setLockScreenNotificationVisibility( K9.LockScreenNotificationVisibility.valueOf( mLockScreenNotificationVisibility.getValue())); } K9.setSplitViewMode(SplitViewMode.valueOf(mSplitViewMode.getValue())); K9.setAttachmentDefaultPath(mAttachmentPathPreference.getSummary().toString()); boolean needsRefresh = K9.setBackgroundOps(mBackgroundOps.getValue()); if (!K9.DEBUG && mDebugLogging.isChecked()) { Toast.makeText(this, R.string.debug_logging_enabled, Toast.LENGTH_LONG).show(); } K9.DEBUG = mDebugLogging.isChecked(); K9.DEBUG_SENSITIVE = mSensitiveLogging.isChecked(); K9.setHideUserAgent(mHideUserAgent.isChecked()); K9.setHideTimeZone(mHideTimeZone.isChecked()); Editor editor = preferences.edit(); K9.save(editor); editor.commit(); if (needsRefresh) { MailService.actionReset(this, null); } }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.global_preferences); mLanguage = (ListPreference) findPreference(PREFERENCE_LANGUAGE); List<CharSequence> entryVector = new ArrayList<CharSequence>(Arrays.asList(mLanguage.getEntries())); List<CharSequence> entryValueVector = new ArrayList<CharSequence>(Arrays.asList(mLanguage.getEntryValues())); String supportedLanguages[] = getResources().getStringArray(R.array.supported_languages); Set<String> supportedLanguageSet = new HashSet<String>(Arrays.asList(supportedLanguages)); for (int i = entryVector.size() - 1; i > -1; --i) { if (!supportedLanguageSet.contains(entryValueVector.get(i))) { entryVector.remove(i); entryValueVector.remove(i); } } initListPreference( mLanguage, K9.getK9Language(), entryVector.toArray(EMPTY_CHAR_SEQUENCE_ARRAY), entryValueVector.toArray(EMPTY_CHAR_SEQUENCE_ARRAY)); mTheme = setupListPreference(PREFERENCE_THEME, themeIdToName(K9.getK9Theme())); mFixedMessageTheme = (CheckBoxPreference) findPreference(PREFERENCE_FIXED_MESSAGE_THEME); mFixedMessageTheme.setChecked(K9.useFixedMessageViewTheme()); mMessageTheme = setupListPreference( PREFERENCE_MESSAGE_VIEW_THEME, themeIdToName(K9.getK9MessageViewThemeSetting())); mComposerTheme = setupListPreference( PREFERENCE_COMPOSER_THEME, themeIdToName(K9.getK9ComposerThemeSetting())); findPreference(PREFERENCE_FONT_SIZE) .setOnPreferenceClickListener( new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { onFontSizeSettings(); return true; } }); mAnimations = (CheckBoxPreference) findPreference(PREFERENCE_ANIMATIONS); mAnimations.setChecked(K9.showAnimations()); mGestures = (CheckBoxPreference) findPreference(PREFERENCE_GESTURES); mGestures.setChecked(K9.gesturesEnabled()); mVolumeNavigation = (CheckBoxListPreference) findPreference(PREFERENCE_VOLUME_NAVIGATION); mVolumeNavigation.setItems( new CharSequence[] { getString(R.string.volume_navigation_message), getString(R.string.volume_navigation_list) }); mVolumeNavigation.setCheckedItems( new boolean[] { K9.useVolumeKeysForNavigationEnabled(), K9.useVolumeKeysForListNavigationEnabled() }); mStartIntegratedInbox = (CheckBoxPreference) findPreference(PREFERENCE_START_INTEGRATED_INBOX); mStartIntegratedInbox.setChecked(K9.startIntegratedInbox()); mConfirmActions = (CheckBoxListPreference) findPreference(PREFERENCE_CONFIRM_ACTIONS); boolean canDeleteFromNotification = NotificationController.platformSupportsExtendedNotifications(); CharSequence[] confirmActionEntries = new CharSequence[canDeleteFromNotification ? 5 : 4]; boolean[] confirmActionValues = new boolean[canDeleteFromNotification ? 5 : 4]; int index = 0; confirmActionEntries[index] = getString(R.string.global_settings_confirm_action_delete); confirmActionValues[index++] = K9.confirmDelete(); confirmActionEntries[index] = getString(R.string.global_settings_confirm_action_delete_starred); confirmActionValues[index++] = K9.confirmDeleteStarred(); if (canDeleteFromNotification) { confirmActionEntries[index] = getString(R.string.global_settings_confirm_action_delete_notif); confirmActionValues[index++] = K9.confirmDeleteFromNotification(); } confirmActionEntries[index] = getString(R.string.global_settings_confirm_action_spam); confirmActionValues[index++] = K9.confirmSpam(); confirmActionEntries[index] = getString(R.string.global_settings_confirm_menu_discard); confirmActionValues[index++] = K9.confirmDiscardMessage(); mConfirmActions.setItems(confirmActionEntries); mConfirmActions.setCheckedItems(confirmActionValues); mNotificationHideSubject = setupListPreference( PREFERENCE_NOTIFICATION_HIDE_SUBJECT, K9.getNotificationHideSubject().toString()); mMeasureAccounts = (CheckBoxPreference) findPreference(PREFERENCE_MEASURE_ACCOUNTS); mMeasureAccounts.setChecked(K9.measureAccounts()); mCountSearch = (CheckBoxPreference) findPreference(PREFERENCE_COUNT_SEARCH); mCountSearch.setChecked(K9.countSearchMessages()); mHideSpecialAccounts = (CheckBoxPreference) findPreference(PREFERENCE_HIDE_SPECIAL_ACCOUNTS); mHideSpecialAccounts.setChecked(K9.isHideSpecialAccounts()); mPreviewLines = setupListPreference( PREFERENCE_MESSAGELIST_PREVIEW_LINES, Integer.toString(K9.messageListPreviewLines())); mSenderAboveSubject = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_SENDER_ABOVE_SUBJECT); mSenderAboveSubject.setChecked(K9.messageListSenderAboveSubject()); mCheckboxes = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_CHECKBOXES); mCheckboxes.setChecked(K9.messageListCheckboxes()); mStars = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_STARS); mStars.setChecked(K9.messageListStars()); mShowCorrespondentNames = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_SHOW_CORRESPONDENT_NAMES); mShowCorrespondentNames.setChecked(K9.showCorrespondentNames()); mShowContactName = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_SHOW_CONTACT_NAME); mShowContactName.setChecked(K9.showContactName()); mShowContactPicture = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_SHOW_CONTACT_PICTURE); mShowContactPicture.setChecked(K9.showContactPicture()); mColorizeMissingContactPictures = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_COLORIZE_MISSING_CONTACT_PICTURES); mColorizeMissingContactPictures.setChecked(K9.isColorizeMissingContactPictures()); mBackgroundAsUnreadIndicator = (CheckBoxPreference) findPreference(PREFERENCE_BACKGROUND_AS_UNREAD_INDICATOR); mBackgroundAsUnreadIndicator.setChecked(K9.useBackgroundAsUnreadIndicator()); mChangeContactNameColor = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGELIST_CONTACT_NAME_COLOR); mChangeContactNameColor.setChecked(K9.changeContactNameColor()); mThreadedView = (CheckBoxPreference) findPreference(PREFERENCE_THREADED_VIEW); mThreadedView.setChecked(K9.isThreadedViewEnabled()); if (K9.changeContactNameColor()) { mChangeContactNameColor.setSummary(R.string.global_settings_registered_name_color_changed); } else { mChangeContactNameColor.setSummary(R.string.global_settings_registered_name_color_default); } mChangeContactNameColor.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { final Boolean checked = (Boolean) newValue; if (checked) { onChooseContactNameColor(); mChangeContactNameColor.setSummary( R.string.global_settings_registered_name_color_changed); } else { mChangeContactNameColor.setSummary( R.string.global_settings_registered_name_color_default); } mChangeContactNameColor.setChecked(checked); return false; } }); mFixedWidth = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGEVIEW_FIXEDWIDTH); mFixedWidth.setChecked(K9.messageViewFixedWidthFont()); mReturnToList = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGEVIEW_RETURN_TO_LIST); mReturnToList.setChecked(K9.messageViewReturnToList()); mShowNext = (CheckBoxPreference) findPreference(PREFERENCE_MESSAGEVIEW_SHOW_NEXT); mShowNext.setChecked(K9.messageViewShowNext()); mAutofitWidth = (CheckBoxPreference) findPreference(PREFERENCE_AUTOFIT_WIDTH); mAutofitWidth.setChecked(K9.autofitWidth()); mQuietTimeEnabled = (CheckBoxPreference) findPreference(PREFERENCE_QUIET_TIME_ENABLED); mQuietTimeEnabled.setChecked(K9.getQuietTimeEnabled()); mDisableNotificationDuringQuietTime = (CheckBoxPreference) findPreference(PREFERENCE_DISABLE_NOTIFICATION_DURING_QUIET_TIME); mDisableNotificationDuringQuietTime.setChecked(!K9.isNotificationDuringQuietTimeEnabled()); mQuietTimeStarts = (TimePickerPreference) findPreference(PREFERENCE_QUIET_TIME_STARTS); mQuietTimeStarts.setDefaultValue(K9.getQuietTimeStarts()); mQuietTimeStarts.setSummary(K9.getQuietTimeStarts()); mQuietTimeStarts.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { final String time = (String) newValue; mQuietTimeStarts.setSummary(time); return false; } }); mQuietTimeEnds = (TimePickerPreference) findPreference(PREFERENCE_QUIET_TIME_ENDS); mQuietTimeEnds.setSummary(K9.getQuietTimeEnds()); mQuietTimeEnds.setDefaultValue(K9.getQuietTimeEnds()); mQuietTimeEnds.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference preference, Object newValue) { final String time = (String) newValue; mQuietTimeEnds.setSummary(time); return false; } }); mNotificationQuickDelete = setupListPreference( PREFERENCE_NOTIF_QUICK_DELETE, K9.getNotificationQuickDeleteBehaviour().toString()); if (!NotificationController.platformSupportsExtendedNotifications()) { PreferenceScreen prefs = (PreferenceScreen) findPreference("notification_preferences"); prefs.removePreference(mNotificationQuickDelete); mNotificationQuickDelete = null; } mLockScreenNotificationVisibility = setupListPreference( PREFERENCE_LOCK_SCREEN_NOTIFICATION_VISIBILITY, K9.getLockScreenNotificationVisibility().toString()); if (!NotificationController.platformSupportsLockScreenNotifications()) { ((PreferenceScreen) findPreference("notification_preferences")) .removePreference(mLockScreenNotificationVisibility); mLockScreenNotificationVisibility = null; } mBackgroundOps = setupListPreference(PREFERENCE_BACKGROUND_OPS, K9.getBackgroundOps().name()); mDebugLogging = (CheckBoxPreference) findPreference(PREFERENCE_DEBUG_LOGGING); mSensitiveLogging = (CheckBoxPreference) findPreference(PREFERENCE_SENSITIVE_LOGGING); mHideUserAgent = (CheckBoxPreference) findPreference(PREFERENCE_HIDE_USERAGENT); mHideTimeZone = (CheckBoxPreference) findPreference(PREFERENCE_HIDE_TIMEZONE); mDebugLogging.setChecked(K9.DEBUG); mSensitiveLogging.setChecked(K9.DEBUG_SENSITIVE); mHideUserAgent.setChecked(K9.hideUserAgent()); mHideTimeZone.setChecked(K9.hideTimeZone()); mAttachmentPathPreference = findPreference(PREFERENCE_ATTACHMENT_DEF_PATH); mAttachmentPathPreference.setSummary(K9.getAttachmentDefaultPath()); mAttachmentPathPreference.setOnPreferenceClickListener( new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { FileBrowserHelper.getInstance() .showFileBrowserActivity( Prefs.this, new File(K9.getAttachmentDefaultPath()), ACTIVITY_CHOOSE_FOLDER, callback); return true; } FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() { @Override public void onPathEntered(String path) { mAttachmentPathPreference.setSummary(path); K9.setAttachmentDefaultPath(path); } @Override public void onCancel() { // canceled, do nothing } }; }); mWrapFolderNames = (CheckBoxPreference) findPreference(PREFERENCE_FOLDERLIST_WRAP_NAME); mWrapFolderNames.setChecked(K9.wrapFolderNames()); mVisibleRefileActions = (CheckBoxListPreference) findPreference(PREFERENCE_MESSAGEVIEW_VISIBLE_REFILE_ACTIONS); CharSequence[] visibleRefileActionsEntries = new CharSequence[5]; visibleRefileActionsEntries[VISIBLE_REFILE_ACTIONS_DELETE] = getString(R.string.delete_action); visibleRefileActionsEntries[VISIBLE_REFILE_ACTIONS_ARCHIVE] = getString(R.string.archive_action); visibleRefileActionsEntries[VISIBLE_REFILE_ACTIONS_MOVE] = getString(R.string.move_action); visibleRefileActionsEntries[VISIBLE_REFILE_ACTIONS_COPY] = getString(R.string.copy_action); visibleRefileActionsEntries[VISIBLE_REFILE_ACTIONS_SPAM] = getString(R.string.spam_action); boolean[] visibleRefileActionsValues = new boolean[5]; visibleRefileActionsValues[VISIBLE_REFILE_ACTIONS_DELETE] = K9.isMessageViewDeleteActionVisible(); visibleRefileActionsValues[VISIBLE_REFILE_ACTIONS_ARCHIVE] = K9.isMessageViewArchiveActionVisible(); visibleRefileActionsValues[VISIBLE_REFILE_ACTIONS_MOVE] = K9.isMessageViewMoveActionVisible(); visibleRefileActionsValues[VISIBLE_REFILE_ACTIONS_COPY] = K9.isMessageViewCopyActionVisible(); visibleRefileActionsValues[VISIBLE_REFILE_ACTIONS_SPAM] = K9.isMessageViewSpamActionVisible(); checkMailDuringDoze = (CheckBoxPreference) findPreference(PREFERENCE_CHECK_MAIL_DURING_DOZE); checkMailDuringDoze.setChecked(K9.isCheckMailDuringDoze()); mVisibleRefileActions.setItems(visibleRefileActionsEntries); mVisibleRefileActions.setCheckedItems(visibleRefileActionsValues); mSplitViewMode = (ListPreference) findPreference(PREFERENCE_SPLITVIEW_MODE); initListPreference( mSplitViewMode, K9.getSplitViewMode().name(), mSplitViewMode.getEntries(), mSplitViewMode.getEntryValues()); }
@Override public void onCreate() { maybeSetupStrictMode(); super.onCreate(); app = this; galleryBuggy = checkForBuggyGallery(); Preferences prefs = Preferences.getPreferences(this); SharedPreferences sprefs = prefs.getPreferences(); DEBUG = sprefs.getBoolean("enableDebugLogging", false); DEBUG_SENSITIVE = sprefs.getBoolean("enableSensitiveLogging", false); mAnimations = sprefs.getBoolean("animations", true); mGesturesEnabled = sprefs.getBoolean("gesturesEnabled", true); mUseVolumeKeysForNavigation = sprefs.getBoolean("useVolumeKeysForNavigation", false); mUseVolumeKeysForListNavigation = sprefs.getBoolean("useVolumeKeysForListNavigation", false); mManageBack = sprefs.getBoolean("manageBack", false); mStartIntegratedInbox = sprefs.getBoolean("startIntegratedInbox", false); mMeasureAccounts = sprefs.getBoolean("measureAccounts", true); mCountSearchMessages = sprefs.getBoolean("countSearchMessages", true); mHideSpecialAccounts = sprefs.getBoolean("hideSpecialAccounts", false); mMessageListStars = sprefs.getBoolean("messageListStars", true); mMessageListCheckboxes = sprefs.getBoolean("messageListCheckboxes", false); mMessageListTouchable = sprefs.getBoolean("messageListTouchable", false); mMessageListPreviewLines = sprefs.getInt("messageListPreviewLines", 2); mMobileOptimizedLayout = sprefs.getBoolean("mobileOptimizedLayout", false); mZoomControlsEnabled = sprefs.getBoolean("zoomControlsEnabled", false); mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false); mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00"); mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00"); mShowCorrespondentNames = sprefs.getBoolean("showCorrespondentNames", true); mShowContactName = sprefs.getBoolean("showContactName", false); mChangeContactNameColor = sprefs.getBoolean("changeRegisteredNameColor", false); mContactNameColor = sprefs.getInt("registeredNameColor", 0xff00008f); mMessageViewFixedWidthFont = sprefs.getBoolean("messageViewFixedWidthFont", false); mMessageViewReturnToList = sprefs.getBoolean("messageViewReturnToList", false); useGalleryBugWorkaround = sprefs.getBoolean("useGalleryBugWorkaround", K9.isGalleryBuggy()); mConfirmDelete = sprefs.getBoolean("confirmDelete", false); mKeyguardPrivacy = sprefs.getBoolean("keyguardPrivacy", false); compactLayouts = sprefs.getBoolean("compactLayouts", false); fontSizes.load(sprefs); try { setBackgroundOps( BACKGROUND_OPS.valueOf(sprefs.getString("backgroundOperations", "WHEN_CHECKED"))); } catch (Exception e) { setBackgroundOps(BACKGROUND_OPS.WHEN_CHECKED); } K9.setK9Language(sprefs.getString("language", "")); K9.setK9Theme(sprefs.getInt("theme", android.R.style.Theme_Light)); /* * We have to give MimeMessage a temp directory because File.createTempFile(String, String) * doesn't work in Android and MimeMessage does not have access to a Context. */ BinaryTempFileBody.setTempDirectory(getCacheDir()); /* * Enable background sync of messages */ setServicesEnabled(this); registerReceivers(); MessagingController.getInstance(this) .addListener( new MessagingListener() { private void broadcastIntent( String action, Account account, String folder, Message message) { try { Uri uri = Uri.parse( "email://messages/" + account.getAccountNumber() + "/" + Uri.encode(folder) + "/" + Uri.encode(message.getUid())); Intent intent = new Intent(action, uri); intent.putExtra(K9.Intents.EmailReceived.EXTRA_ACCOUNT, account.getDescription()); intent.putExtra(K9.Intents.EmailReceived.EXTRA_FOLDER, folder); intent.putExtra(K9.Intents.EmailReceived.EXTRA_SENT_DATE, message.getSentDate()); intent.putExtra( K9.Intents.EmailReceived.EXTRA_FROM, Address.toString(message.getFrom())); intent.putExtra( K9.Intents.EmailReceived.EXTRA_TO, Address.toString(message.getRecipients(Message.RecipientType.TO))); intent.putExtra( K9.Intents.EmailReceived.EXTRA_CC, Address.toString(message.getRecipients(Message.RecipientType.CC))); intent.putExtra( K9.Intents.EmailReceived.EXTRA_BCC, Address.toString(message.getRecipients(Message.RecipientType.BCC))); intent.putExtra(K9.Intents.EmailReceived.EXTRA_SUBJECT, message.getSubject()); intent.putExtra( K9.Intents.EmailReceived.EXTRA_FROM_SELF, account.isAnIdentity(message.getFrom())); K9.this.sendBroadcast(intent); if (K9.DEBUG) Log.d( K9.LOG_TAG, "Broadcasted: action=" + action + " account=" + account.getDescription() + " folder=" + folder + " message uid=" + message.getUid()); } catch (MessagingException e) { Log.w( K9.LOG_TAG, "Error: action=" + action + " account=" + account.getDescription() + " folder=" + folder + " message uid=" + message.getUid()); } } @Override public void synchronizeMailboxRemovedMessage( Account account, String folder, Message message) { broadcastIntent( K9.Intents.EmailReceived.ACTION_EMAIL_DELETED, account, folder, message); } @Override public void messageDeleted(Account account, String folder, Message message) { broadcastIntent( K9.Intents.EmailReceived.ACTION_EMAIL_DELETED, account, folder, message); } @Override public void synchronizeMailboxNewMessage( Account account, String folder, Message message) { broadcastIntent( K9.Intents.EmailReceived.ACTION_EMAIL_RECEIVED, account, folder, message); } @Override public void searchStats(final AccountStats stats) { // let observers know a fetch occured K9.this.sendBroadcast( new Intent(K9.Intents.EmailReceived.ACTION_REFRESH_OBSERVER, null)); } }); notifyObservers(); }
public View getItemView(int itemPosition, View convertView, ViewGroup parent) { FolderInfoHolder folder = (FolderInfoHolder) getItem(itemPosition); View view; if (convertView != null) { view = convertView; } else { view = mInflater.inflate(R.layout.folder_list_item, parent, false); } FolderViewHolder holder = (FolderViewHolder) view.getTag(); if (holder == null) { holder = new FolderViewHolder(); holder.folderName = (TextView) view.findViewById(R.id.folder_name); holder.newMessageCount = (TextView) view.findViewById(R.id.folder_unread_message_count); holder.flaggedMessageCount = (TextView) view.findViewById(R.id.folder_flagged_message_count); holder.folderStatus = (TextView) view.findViewById(R.id.folder_status); holder.activeIcons = (RelativeLayout) view.findViewById(R.id.active_icons); holder.chip = view.findViewById(R.id.chip); holder.folderListItemLayout = (LinearLayout) view.findViewById(R.id.folder_list_item_layout); holder.rawFolderName = folder.name; view.setTag(holder); } if (folder == null) { return view; } holder.folderName.setText(folder.displayName); String statusText = ""; if (folder.loading) { statusText = getString(R.string.status_loading); } else if (folder.status != null) { statusText = folder.status; } else if (folder.lastChecked != 0) { Date lastCheckedDate = new Date(folder.lastChecked); statusText = getTimeFormat().format(lastCheckedDate) + " " + getDateFormat().format(lastCheckedDate); } if (folder.pushActive) { statusText = getString(R.string.folder_push_active_symbol) + " " + statusText; } if (statusText != null) { holder.folderStatus.setText(statusText); holder.folderStatus.setVisibility(View.VISIBLE); } else { holder.folderStatus.setText(null); holder.folderStatus.setVisibility(View.GONE); } if (folder.unreadMessageCount != 0) { holder.newMessageCount.setText(Integer.toString(folder.unreadMessageCount)); holder.newMessageCount.setOnClickListener( new FolderClickListener( mAccount, folder.name, folder.displayName, SearchModifier.UNREAD)); holder.newMessageCount.setVisibility(View.VISIBLE); } else { holder.newMessageCount.setVisibility(View.GONE); } if (K9.messageListStars() && folder.flaggedMessageCount > 0) { holder.flaggedMessageCount.setText(Integer.toString(folder.flaggedMessageCount)); holder.flaggedMessageCount.setOnClickListener( new FolderClickListener( mAccount, folder.name, folder.displayName, SearchModifier.FLAGGED)); holder.flaggedMessageCount.setVisibility(View.VISIBLE); } else { holder.flaggedMessageCount.setVisibility(View.GONE); } if (K9.useCompactLayouts() && holder.folderListItemLayout != null) { holder.folderListItemLayout.setMinimumHeight(0); } holder.activeIcons.setOnClickListener( new OnClickListener() { public void onClick(View v) { Toast toast = Toast.makeText( getApplication(), getString(R.string.tap_hint), Toast.LENGTH_SHORT); toast.show(); } }); holder.chip.setBackgroundDrawable(mAccount.generateColorChip().drawable()); holder.chip.getBackground().setAlpha(folder.unreadMessageCount == 0 ? 127 : 255); holder.folderName.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderName()); holder.folderStatus.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderStatus()); return view; }
public class MessageHeader extends ScrollView implements OnClickListener { private Context mContext; private TextView mFromView; private TextView mDateView; private TextView mToView; private TextView mToLabel; private TextView mCcView; private TextView mCcLabel; private TextView mSubjectView; private View mChip; private CheckBox mFlagged; private int defaultSubjectColor; private TextView mAdditionalHeadersView; private View mAnsweredIcon; private View mForwardedIcon; private Message mMessage; private Account mAccount; private FontSizes mFontSizes = K9.getFontSizes(); private Contacts mContacts; private SavedState mSavedState; private MessageHelper mMessageHelper; private ContactPictureLoader mContactsPictureLoader; private QuickContactBadge mContactBadge; private OnLayoutChangedListener mOnLayoutChangedListener; /** Pair class is only available since API Level 5, so we need this helper class unfortunately */ private static class HeaderEntry { public String label; public String value; public HeaderEntry(String label, String value) { this.label = label; this.value = value; } } public MessageHeader(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mContacts = Contacts.getInstance(mContext); } @Override protected void onFinishInflate() { mAnsweredIcon = findViewById(R.id.answered); mForwardedIcon = findViewById(R.id.forwarded); mFromView = (TextView) findViewById(R.id.from); mToView = (TextView) findViewById(R.id.to); mToLabel = (TextView) findViewById(R.id.to_label); mCcView = (TextView) findViewById(R.id.cc); mCcLabel = (TextView) findViewById(R.id.cc_label); mContactBadge = (QuickContactBadge) findViewById(R.id.contact_badge); mSubjectView = (TextView) findViewById(R.id.subject); mAdditionalHeadersView = (TextView) findViewById(R.id.additional_headers_view); mChip = findViewById(R.id.chip); mDateView = (TextView) findViewById(R.id.date); mFlagged = (CheckBox) findViewById(R.id.flagged); defaultSubjectColor = mSubjectView.getCurrentTextColor(); mFontSizes.setViewTextSize(mSubjectView, mFontSizes.getMessageViewSubject()); mFontSizes.setViewTextSize(mDateView, mFontSizes.getMessageViewDate()); mFontSizes.setViewTextSize( mAdditionalHeadersView, mFontSizes.getMessageViewAdditionalHeaders()); mFontSizes.setViewTextSize(mFromView, mFontSizes.getMessageViewSender()); mFontSizes.setViewTextSize(mToView, mFontSizes.getMessageViewTo()); mFontSizes.setViewTextSize(mToLabel, mFontSizes.getMessageViewTo()); mFontSizes.setViewTextSize(mCcView, mFontSizes.getMessageViewCC()); mFontSizes.setViewTextSize(mCcLabel, mFontSizes.getMessageViewCC()); mFromView.setOnClickListener(this); mToView.setOnClickListener(this); mCcView.setOnClickListener(this); mMessageHelper = MessageHelper.getInstance(mContext); mSubjectView.setVisibility(VISIBLE); hideAdditionalHeaders(); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.from: { onAddSenderToContacts(); break; } case R.id.to: case R.id.cc: { expand((TextView) view, ((TextView) view).getEllipsize() != null); layoutChanged(); } } } private void onAddSenderToContacts() { if (mMessage != null) { try { final Address senderEmail = mMessage.getFrom()[0]; mContacts.createContact(senderEmail); } catch (Exception e) { Log.e(K9.LOG_TAG, "Couldn't create contact", e); } } } public void setOnFlagListener(OnClickListener listener) { if (mFlagged == null) return; mFlagged.setOnClickListener(listener); } public boolean additionalHeadersVisible() { return (mAdditionalHeadersView != null && mAdditionalHeadersView.getVisibility() == View.VISIBLE); } /** * Clear the text field for the additional headers display if they are not shown, to save UI * resources. */ private void hideAdditionalHeaders() { mAdditionalHeadersView.setVisibility(View.GONE); mAdditionalHeadersView.setText(""); } /** * Set up and then show the additional headers view. Called by {@link #onShowAdditionalHeaders()} * (when switching between messages). */ private void showAdditionalHeaders() { Integer messageToShow = null; try { // Retrieve additional headers boolean allHeadersDownloaded = mMessage.isSet(Flag.X_GOT_ALL_HEADERS); List<HeaderEntry> additionalHeaders = getAdditionalHeaders(mMessage); if (!additionalHeaders.isEmpty()) { // Show the additional headers that we have got. populateAdditionalHeadersView(additionalHeaders); mAdditionalHeadersView.setVisibility(View.VISIBLE); } if (!allHeadersDownloaded) { /* * Tell the user about the "save all headers" setting * * NOTE: This is only a temporary solution... in fact, * the system should download headers on-demand when they * have not been saved in their entirety initially. */ messageToShow = R.string.message_additional_headers_not_downloaded; } else if (additionalHeaders.isEmpty()) { // All headers have been downloaded, but there are no additional headers. messageToShow = R.string.message_no_additional_headers_available; } } catch (Exception e) { messageToShow = R.string.message_additional_headers_retrieval_failed; } // Show a message to the user, if any if (messageToShow != null) { Toast toast = Toast.makeText(mContext, messageToShow, Toast.LENGTH_LONG); toast.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL, 0, 0); toast.show(); } } public void populate(final Message message, final Account account) throws MessagingException { final Contacts contacts = K9.showContactName() ? mContacts : null; final CharSequence from = Address.toFriendly(message.getFrom(), contacts); final CharSequence to = Address.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts); final CharSequence cc = Address.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts); Address[] fromAddrs = message.getFrom(); Address[] toAddrs = message.getRecipients(Message.RecipientType.TO); Address[] ccAddrs = message.getRecipients(Message.RecipientType.CC); boolean fromMe = mMessageHelper.toMe(account, fromAddrs); String counterpartyAddress = null; if (fromMe) { if (toAddrs.length > 0) { counterpartyAddress = toAddrs[0].getAddress(); } else if (ccAddrs.length > 0) { counterpartyAddress = ccAddrs[0].getAddress(); } } else if (fromAddrs.length > 0) { counterpartyAddress = fromAddrs[0].getAddress(); } /* * Only reset visibility of the subject if populate() was called because a new * message is shown. If it is the same, do not force the subject visible, because * this breaks the MessageTitleView in the action bar, which may hide our subject * if it fits in the action bar but is only called when a new message is shown * or the device is rotated. */ if (mMessage == null || mMessage.getId() != message.getId()) { mSubjectView.setVisibility(VISIBLE); } mMessage = message; mAccount = account; if (K9.showContactPicture()) { mContactBadge.setVisibility(View.VISIBLE); mContactsPictureLoader = new ContactPictureLoader(mContext, R.drawable.ic_contact_picture); } else { mContactBadge.setVisibility(View.GONE); } final String subject = message.getSubject(); if (StringUtils.isNullOrEmpty(subject)) { mSubjectView.setText(mContext.getText(R.string.general_no_subject)); } else { mSubjectView.setText(subject); } mSubjectView.setTextColor(0xff000000 | defaultSubjectColor); String dateTime = DateUtils.formatDateTime( mContext, message.getSentDate().getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR); mDateView.setText(dateTime); if (K9.showContactPicture()) { mContactBadge.assignContactFromEmail(counterpartyAddress, true); if (counterpartyAddress != null) { mContactsPictureLoader.loadContactPicture(counterpartyAddress, mContactBadge); } else { mContactBadge.setImageResource(R.drawable.ic_contact_picture); } } mFromView.setText(from); updateAddressField(mToView, to, mToLabel); updateAddressField(mCcView, cc, mCcLabel); mAnsweredIcon.setVisibility(message.isSet(Flag.ANSWERED) ? View.VISIBLE : View.GONE); mForwardedIcon.setVisibility(message.isSet(Flag.FORWARDED) ? View.VISIBLE : View.GONE); mFlagged.setChecked(message.isSet(Flag.FLAGGED)); int chipColor = mAccount.getChipColor(); int chipColorAlpha = (!message.isSet(Flag.SEEN)) ? 255 : 127; mChip.setBackgroundColor(chipColor); mChip.getBackground().setAlpha(chipColorAlpha); setVisibility(View.VISIBLE); if (mSavedState != null) { if (mSavedState.additionalHeadersVisible) { showAdditionalHeaders(); } mSavedState = null; } else { hideAdditionalHeaders(); } } public void onShowAdditionalHeaders() { int currentVisibility = mAdditionalHeadersView.getVisibility(); if (currentVisibility == View.VISIBLE) { hideAdditionalHeaders(); expand(mToView, false); expand(mCcView, false); } else { showAdditionalHeaders(); expand(mToView, true); expand(mCcView, true); } layoutChanged(); } private void updateAddressField(TextView v, CharSequence text, View label) { boolean hasText = !TextUtils.isEmpty(text); v.setText(text); v.setVisibility(hasText ? View.VISIBLE : View.GONE); label.setVisibility(hasText ? View.VISIBLE : View.GONE); } /** Expand or collapse a TextView by removing or adding the 2 lines limitation */ private void expand(TextView v, boolean expand) { if (expand) { v.setMaxLines(Integer.MAX_VALUE); v.setEllipsize(null); } else { v.setMaxLines(2); v.setEllipsize(android.text.TextUtils.TruncateAt.END); } } private List<HeaderEntry> getAdditionalHeaders(final Message message) throws MessagingException { List<HeaderEntry> additionalHeaders = new LinkedList<HeaderEntry>(); Set<String> headerNames = new LinkedHashSet<String>(message.getHeaderNames()); for (String headerName : headerNames) { String[] headerValues = message.getHeader(headerName); for (String headerValue : headerValues) { additionalHeaders.add(new HeaderEntry(headerName, headerValue)); } } return additionalHeaders; } /** * Set up the additional headers text view with the supplied header data. * * @param additionalHeaders List of header entries. Each entry consists of a header name and a * header value. Header names may appear multiple times. * <p>This method is always called from within the UI thread by {@link * #showAdditionalHeaders()}. */ private void populateAdditionalHeadersView(final List<HeaderEntry> additionalHeaders) { SpannableStringBuilder sb = new SpannableStringBuilder(); boolean first = true; for (HeaderEntry additionalHeader : additionalHeaders) { if (!first) { sb.append("\n"); } else { first = false; } StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); SpannableString label = new SpannableString(additionalHeader.label + ": "); label.setSpan(boldSpan, 0, label.length(), 0); sb.append(label); sb.append(MimeUtility.unfoldAndDecode(additionalHeader.value)); } mAdditionalHeadersView.setText(sb); } @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState savedState = new SavedState(superState); savedState.additionalHeadersVisible = additionalHeadersVisible(); return savedState; } @Override public void onRestoreInstanceState(Parcelable state) { if (!(state instanceof SavedState)) { super.onRestoreInstanceState(state); return; } SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); mSavedState = savedState; } static class SavedState extends BaseSavedState { boolean additionalHeadersVisible; public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { @Override public SavedState createFromParcel(Parcel in) { return new SavedState(in); } @Override public SavedState[] newArray(int size) { return new SavedState[size]; } }; SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); this.additionalHeadersVisible = (in.readInt() != 0); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeInt((this.additionalHeadersVisible) ? 1 : 0); } } public interface OnLayoutChangedListener { void onLayoutChanged(); } public void setOnLayoutChangedListener(OnLayoutChangedListener listener) { mOnLayoutChangedListener = listener; } private void layoutChanged() { if (mOnLayoutChangedListener != null) { mOnLayoutChangedListener.onLayoutChanged(); } } public void hideSubjectLine() { mSubjectView.setVisibility(GONE); } }
/** * Load preferences into our statics. * * <p>If you're adding a preference here, odds are you'll need to add it to {@link * com.fsck.k9.preferences.GlobalSettings}, too. * * @param prefs Preferences to load */ public static void loadPrefs(Preferences prefs) { SharedPreferences sprefs = prefs.getPreferences(); DEBUG = sprefs.getBoolean("enableDebugLogging", false); if (!DEBUG && sIsDebuggable && Debug.isDebuggerConnected()) { // If the debugger is attached, we're probably (surprise surprise) debugging something. DEBUG = true; Log.i(K9.LOG_TAG, "Debugger attached; enabling debug logging."); } DEBUG_SENSITIVE = sprefs.getBoolean("enableSensitiveLogging", false); mAnimations = sprefs.getBoolean("animations", true); mGesturesEnabled = sprefs.getBoolean("gesturesEnabled", false); mUseVolumeKeysForNavigation = sprefs.getBoolean("useVolumeKeysForNavigation", false); mUseVolumeKeysForListNavigation = sprefs.getBoolean("useVolumeKeysForListNavigation", false); mStartIntegratedInbox = sprefs.getBoolean("startIntegratedInbox", false); mMeasureAccounts = sprefs.getBoolean("measureAccounts", true); mCountSearchMessages = sprefs.getBoolean("countSearchMessages", true); mHideSpecialAccounts = sprefs.getBoolean("hideSpecialAccounts", false); mMessageListSenderAboveSubject = sprefs.getBoolean("messageListSenderAboveSubject", false); mMessageListCheckboxes = sprefs.getBoolean("messageListCheckboxes", false); mMessageListStars = sprefs.getBoolean("messageListStars", true); mMessageListPreviewLines = sprefs.getInt("messageListPreviewLines", 2); mAutofitWidth = sprefs.getBoolean("autofitWidth", true); mQuietTimeEnabled = sprefs.getBoolean("quietTimeEnabled", false); mQuietTimeStarts = sprefs.getString("quietTimeStarts", "21:00"); mQuietTimeEnds = sprefs.getString("quietTimeEnds", "7:00"); mShowCorrespondentNames = sprefs.getBoolean("showCorrespondentNames", true); mShowContactName = sprefs.getBoolean("showContactName", false); sShowContactPicture = sprefs.getBoolean("showContactPicture", true); mChangeContactNameColor = sprefs.getBoolean("changeRegisteredNameColor", false); mContactNameColor = sprefs.getInt("registeredNameColor", 0xff00008f); mMessageViewFixedWidthFont = sprefs.getBoolean("messageViewFixedWidthFont", false); mMessageViewReturnToList = sprefs.getBoolean("messageViewReturnToList", false); mMessageViewShowNext = sprefs.getBoolean("messageViewShowNext", false); mWrapFolderNames = sprefs.getBoolean("wrapFolderNames", false); mHideUserAgent = sprefs.getBoolean("hideUserAgent", false); mHideTimeZone = sprefs.getBoolean("hideTimeZone", false); mConfirmDelete = sprefs.getBoolean("confirmDelete", false); mConfirmDeleteStarred = sprefs.getBoolean("confirmDeleteStarred", false); mConfirmSpam = sprefs.getBoolean("confirmSpam", false); mConfirmDeleteFromNotification = sprefs.getBoolean("confirmDeleteFromNotification", true); try { String value = sprefs.getString("sortTypeEnum", Account.DEFAULT_SORT_TYPE.name()); mSortType = SortType.valueOf(value); } catch (Exception e) { mSortType = Account.DEFAULT_SORT_TYPE; } boolean sortAscending = sprefs.getBoolean("sortAscending", Account.DEFAULT_SORT_ASCENDING); mSortAscending.put(mSortType, sortAscending); String notificationHideSubject = sprefs.getString("notificationHideSubject", null); if (notificationHideSubject == null) { // If the "notificationHideSubject" setting couldn't be found, the app was probably // updated. Look for the old "keyguardPrivacy" setting and map it to the new enum. sNotificationHideSubject = (sprefs.getBoolean("keyguardPrivacy", false)) ? NotificationHideSubject.WHEN_LOCKED : NotificationHideSubject.NEVER; } else { sNotificationHideSubject = NotificationHideSubject.valueOf(notificationHideSubject); } String notificationQuickDelete = sprefs.getString("notificationQuickDelete", null); if (notificationQuickDelete != null) { sNotificationQuickDelete = NotificationQuickDelete.valueOf(notificationQuickDelete); } String lockScreenNotificationVisibility = sprefs.getString("lockScreenNotificationVisibility", null); if (lockScreenNotificationVisibility != null) { sLockScreenNotificationVisibility = LockScreenNotificationVisibility.valueOf(lockScreenNotificationVisibility); } String splitViewMode = sprefs.getString("splitViewMode", null); if (splitViewMode != null) { sSplitViewMode = SplitViewMode.valueOf(splitViewMode); } mAttachmentDefaultPath = sprefs.getString( "attachmentdefaultpath", Environment.getExternalStorageDirectory().toString()); sUseBackgroundAsUnreadIndicator = sprefs.getBoolean("useBackgroundAsUnreadIndicator", true); sThreadedViewEnabled = sprefs.getBoolean("threadedView", true); fontSizes.load(sprefs); try { setBackgroundOps( BACKGROUND_OPS.valueOf( sprefs.getString( "backgroundOperations", BACKGROUND_OPS.WHEN_CHECKED_AUTO_SYNC.name()))); } catch (Exception e) { setBackgroundOps(BACKGROUND_OPS.WHEN_CHECKED_AUTO_SYNC); } sColorizeMissingContactPictures = sprefs.getBoolean("colorizeMissingContactPictures", true); sMessageViewArchiveActionVisible = sprefs.getBoolean("messageViewArchiveActionVisible", false); sMessageViewDeleteActionVisible = sprefs.getBoolean("messageViewDeleteActionVisible", true); sMessageViewMoveActionVisible = sprefs.getBoolean("messageViewMoveActionVisible", false); sMessageViewCopyActionVisible = sprefs.getBoolean("messageViewCopyActionVisible", false); sMessageViewSpamActionVisible = sprefs.getBoolean("messageViewSpamActionVisible", false); K9.setK9Language(sprefs.getString("language", "")); int themeValue = sprefs.getInt("theme", Theme.LIGHT.ordinal()); // We used to save the resource ID of the theme. So convert that to the new format if // necessary. if (themeValue == Theme.DARK.ordinal() || themeValue == android.R.style.Theme) { K9.setK9Theme(Theme.DARK); } else { K9.setK9Theme(Theme.LIGHT); } themeValue = sprefs.getInt("messageViewTheme", Theme.USE_GLOBAL.ordinal()); K9.setK9MessageViewThemeSetting(Theme.values()[themeValue]); themeValue = sprefs.getInt("messageComposeTheme", Theme.USE_GLOBAL.ordinal()); K9.setK9ComposerThemeSetting(Theme.values()[themeValue]); K9.setUseFixedMessageViewTheme(sprefs.getBoolean("fixedMessageViewTheme", true)); }
/** * FolderList is the primary user interface for the program. This Activity shows list of the * Account's folders */ public class FolderList extends K9ListActivity { private static final int DIALOG_MARK_ALL_AS_READ = 1; private static final String EXTRA_ACCOUNT = "account"; private static final String EXTRA_INITIAL_FOLDER = "initialFolder"; private static final String EXTRA_FROM_NOTIFICATION = "fromNotification"; private static final String EXTRA_FROM_SHORTCUT = "fromShortcut"; private static final boolean REFRESH_REMOTE = true; private ListView mListView; private FolderListAdapter mAdapter; private LayoutInflater mInflater; private Account mAccount; private FolderListHandler mHandler = new FolderListHandler(); private int mUnreadMessageCount; private FontSizes mFontSizes = K9.getFontSizes(); private Context context; class FolderListHandler extends Handler { public void refreshTitle() { runOnUiThread( new Runnable() { public void run() { String dispString = mAdapter.mListener.formatHeader( FolderList.this, getString(R.string.folder_list_title, mAccount.getDescription()), mUnreadMessageCount, getTimeFormat()); setTitle(dispString); } }); } public void newFolders(final List<FolderInfoHolder> newFolders) { runOnUiThread( new Runnable() { public void run() { mAdapter.mFolders.clear(); mAdapter.mFolders.addAll(newFolders); mHandler.dataChanged(); } }); } public void workingAccount(final int res) { runOnUiThread( new Runnable() { public void run() { String toastText = getString(res, mAccount.getDescription()); Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_SHORT); toast.show(); } }); } public void accountSizeChanged(final long oldSize, final long newSize) { runOnUiThread( new Runnable() { public void run() { String toastText = getString( R.string.account_size_changed, mAccount.getDescription(), SizeFormatter.formatSize(getApplication(), oldSize), SizeFormatter.formatSize(getApplication(), newSize)); Toast toast = Toast.makeText(getApplication(), toastText, Toast.LENGTH_LONG); toast.show(); } }); } public void folderLoading(final String folder, final boolean loading) { runOnUiThread( new Runnable() { public void run() { FolderInfoHolder folderHolder = mAdapter.getFolder(folder); if (folderHolder != null) { folderHolder.loading = loading; } } }); } public void progress(final boolean progress) { runOnUiThread( new Runnable() { public void run() { setProgressBarIndeterminateVisibility(progress); } }); } public void dataChanged() { runOnUiThread( new Runnable() { public void run() { mAdapter.notifyDataSetChanged(); } }); } } public void setProgress(boolean progress) { mHandler.progress(progress); } /** * This class is responsible for reloading the list of local messages for a given folder, * notifying the adapter that the message have been loaded and queueing up a remote update of the * folder. */ private void checkMail(FolderInfoHolder folder) { TracingPowerManager pm = TracingPowerManager.getPowerManager(this); final TracingWakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FolderList checkMail"); wakeLock.setReferenceCounted(false); wakeLock.acquire(K9.WAKE_LOCK_TIMEOUT); MessagingListener listener = new MessagingListener() { @Override public void synchronizeMailboxFinished( Account account, String folder, int totalMessagesInMailbox, int numNewMessages) { if (!account.equals(mAccount)) { return; } wakeLock.release(); } @Override public void synchronizeMailboxFailed(Account account, String folder, String message) { if (!account.equals(mAccount)) { return; } wakeLock.release(); } }; MessagingController.getInstance(getApplication()) .synchronizeMailbox(mAccount, folder.name, listener, null); sendMail(mAccount); } public static Intent actionHandleAccountIntent(Context context, Account account) { return actionHandleAccountIntent(context, account, null, false); } public static Intent actionHandleAccountIntent( Context context, Account account, String initialFolder) { return actionHandleAccountIntent(context, account, initialFolder, false); } public static Intent actionHandleAccountIntent( Context context, Account account, String initialFolder, boolean fromShortcut) { Intent intent = new Intent(context, FolderList.class); intent.putExtra(EXTRA_ACCOUNT, account.getUuid()); if (initialFolder != null) { intent.putExtra(EXTRA_INITIAL_FOLDER, initialFolder); } if (fromShortcut) { intent.putExtra(EXTRA_FROM_SHORTCUT, true); } return intent; } private static void actionHandleAccount(Context context, Account account, String initialFolder) { Intent intent = actionHandleAccountIntent(context, account, initialFolder); context.startActivity(intent); } public static void actionHandleAccount(Context context, Account account) { actionHandleAccount(context, account, null); } public static Intent actionHandleNotification( Context context, Account account, String initialFolder) { Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse("email://accounts/" + account.getAccountNumber()), context, FolderList.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(EXTRA_ACCOUNT, account.getUuid()); intent.putExtra(EXTRA_FROM_NOTIFICATION, true); if (initialFolder != null) { intent.putExtra(EXTRA_INITIAL_FOLDER, initialFolder); } return intent; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.folder_list); mListView = getListView(); mListView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET); mListView.setLongClickable(true); mListView.setFastScrollEnabled(true); mListView.setScrollingCacheEnabled(true); mListView.setOnItemClickListener( new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { onOpenFolder(((FolderInfoHolder) mAdapter.getItem(id)).name); } }); registerForContextMenu(mListView); mListView.setSaveEnabled(true); mInflater = getLayoutInflater(); onNewIntent(getIntent()); context = this; } @Override public void onNewIntent(Intent intent) { setIntent(intent); // onNewIntent doesn't autoset our "internal" intent String initialFolder; mUnreadMessageCount = 0; String accountUuid = intent.getStringExtra(EXTRA_ACCOUNT); mAccount = Preferences.getPreferences(this).getAccount(accountUuid); if (mAccount == null) { // This shouldn't normally happen. But apparently it does. See issue 2261. finish(); return; } initialFolder = intent.getStringExtra(EXTRA_INITIAL_FOLDER); boolean fromNotification = intent.getBooleanExtra(EXTRA_FROM_NOTIFICATION, false); if (fromNotification && mAccount.goToUnreadMessageSearch()) { MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount); openUnreadSearch(this, mAccount); finish(); } else if (initialFolder != null && !K9.FOLDER_NONE.equals(initialFolder)) { onOpenFolder(initialFolder); finish(); } else if (intent.getBooleanExtra(EXTRA_FROM_SHORTCUT, false) && !K9.FOLDER_NONE.equals(mAccount.getAutoExpandFolderName())) { onOpenFolder(mAccount.getAutoExpandFolderName()); finish(); } else { initializeActivityView(); } } private void initializeActivityView() { mAdapter = new FolderListAdapter(); restorePreviousData(); setListAdapter(mAdapter); setTitle(mAccount.getDescription()); } @SuppressWarnings("unchecked") private void restorePreviousData() { final Object previousData = getLastNonConfigurationInstance(); if (previousData != null) { mAdapter.mFolders = (ArrayList<FolderInfoHolder>) previousData; } } @Override public Object onRetainNonConfigurationInstance() { return (mAdapter == null) ? null : mAdapter.mFolders; } @Override public void onPause() { super.onPause(); MessagingController.getInstance(getApplication()).removeListener(mAdapter.mListener); } /** * On resume we refresh the folder list (in the background) and we refresh the messages for any * folder that is currently open. This guarantees that things like unread message count and read * status are updated. */ @Override public void onResume() { super.onResume(); if (!mAccount.isAvailable(this)) { Log.i(K9.LOG_TAG, "account unavaliabale, not showing folder-list but account-list"); startActivity(new Intent(this, Accounts.class)); finish(); return; } if (mAdapter == null) initializeActivityView(); MessagingController.getInstance(getApplication()).addListener(mAdapter.mListener); // mAccount.refresh(Preferences.getPreferences(this)); MessagingController.getInstance(getApplication()) .getAccountStats(this, mAccount, mAdapter.mListener); onRefresh(!REFRESH_REMOTE); MessagingController.getInstance(getApplication()).notifyAccountCancel(this, mAccount); } @Override public void onBackPressed() { // This will be called either automatically for you on 2.0 // or later, or by the code above on earlier versions of the // platform. if (K9.manageBack()) { onAccounts(); } else { // TODO - when we move to android 2.0, uncomment this instead. // super.onBackPressed() finish(); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Shortcuts that work no matter what is selected if ( // TODO - when we move to android 2.0, uncomment this. // android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR && keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0 && K9.manageBack()) { // Take care of calling this method on earlier versions of // the platform where it doesn't exist. onBackPressed(); return true; } switch (keyCode) { case KeyEvent.KEYCODE_Q: // case KeyEvent.KEYCODE_BACK: { onAccounts(); return true; } case KeyEvent.KEYCODE_S: { onEditAccount(); return true; } case KeyEvent.KEYCODE_H: { Toast toast = Toast.makeText(this, R.string.folder_list_help_key, Toast.LENGTH_LONG); toast.show(); return true; } case KeyEvent.KEYCODE_1: { setDisplayMode(FolderMode.FIRST_CLASS); return true; } case KeyEvent.KEYCODE_2: { setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS); return true; } case KeyEvent.KEYCODE_3: { setDisplayMode(FolderMode.NOT_SECOND_CLASS); return true; } case KeyEvent.KEYCODE_4: { setDisplayMode(FolderMode.ALL); return true; } } // switch return super.onKeyDown(keyCode, event); } // onKeyDown private void setDisplayMode(FolderMode newMode) { mAccount.setFolderDisplayMode(newMode); mAccount.save(Preferences.getPreferences(this)); if (mAccount.getFolderPushMode() != FolderMode.NONE) { MailService.actionRestartPushers(this, null); } onRefresh(false); } private void onRefresh(final boolean forceRemote) { MessagingController.getInstance(getApplication()) .listFolders(mAccount, forceRemote, mAdapter.mListener); } private void onEditPrefs() { Prefs.actionPrefs(this); } private void onEditAccount() { AccountSettings.actionSettings(this, mAccount); } private void onEditFolder(Account account, String folderName) { FolderSettings.actionSettings(this, account, folderName); } private void onAccounts() { Accounts.listAccounts(this); finish(); } private void onEmptyTrash(final Account account) { mHandler.dataChanged(); MessagingController.getInstance(getApplication()).emptyTrash(account, null); } private void onExpunge(final Account account, String folderName) { MessagingController.getInstance(getApplication()).expunge(account, folderName, null); } private void onClearFolder(Account account, String folderName) { // There has to be a cheaper way to get at the localFolder object than this LocalFolder localFolder = null; try { if (account == null || folderName == null || !account.isAvailable(FolderList.this)) { Log.i(K9.LOG_TAG, "not clear folder of unavailable account"); return; } localFolder = account.getLocalStore().getFolder(folderName); localFolder.open(Folder.OpenMode.READ_WRITE); localFolder.clearAllMessages(); } catch (Exception e) { Log.e(K9.LOG_TAG, "Exception while clearing folder", e); } finally { if (localFolder != null) { localFolder.close(); } } } private void sendMail(Account account) { MessagingController.getInstance(getApplication()) .sendPendingMessages(account, mAdapter.mListener); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.compose: MessageCompose.actionCompose(this, mAccount); return true; case R.id.check_mail: MessagingController.getInstance(getApplication()) .checkMail(this, mAccount, true, true, mAdapter.mListener); return true; case R.id.send_messages: MessagingController.getInstance(getApplication()).sendPendingMessages(mAccount, null); return true; case R.id.accounts: onAccounts(); return true; case R.id.list_folders: onRefresh(REFRESH_REMOTE); return true; case R.id.account_settings: onEditAccount(); return true; case R.id.app_settings: onEditPrefs(); return true; case R.id.empty_trash: onEmptyTrash(mAccount); return true; case R.id.compact: onCompact(mAccount); return true; case R.id.export: onExport(mAccount); return true; case R.id.export_all: onExport(null); return true; case R.id.display_1st_class: { setDisplayMode(FolderMode.FIRST_CLASS); return true; } case R.id.display_1st_and_2nd_class: { setDisplayMode(FolderMode.FIRST_AND_SECOND_CLASS); return true; } case R.id.display_not_second_class: { setDisplayMode(FolderMode.NOT_SECOND_CLASS); return true; } case R.id.display_all: { setDisplayMode(FolderMode.ALL); return true; } default: return super.onOptionsItemSelected(item); } } private void onOpenFolder(String folder) { MessageList.actionHandleFolder(this, mAccount, folder); if (K9.manageBack()) { finish(); } } private void onCompact(Account account) { mHandler.workingAccount(R.string.compacting_account); MessagingController.getInstance(getApplication()).compact(account, null); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.folder_list_option, menu); return true; } @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position); switch (item.getItemId()) { case R.id.open_folder: onOpenFolder(folder.name); break; case R.id.mark_all_as_read: onMarkAllAsRead(mAccount, folder.name); break; case R.id.send_messages: sendMail(mAccount); break; case R.id.check_mail: checkMail(folder); break; case R.id.folder_settings: onEditFolder(mAccount, folder.name); break; case R.id.empty_trash: onEmptyTrash(mAccount); break; case R.id.expunge: onExpunge(mAccount, folder.name); break; case R.id.clear_local_folder: onClearFolder(mAccount, folder.name); break; } return super.onContextItemSelected(item); } private FolderInfoHolder mSelectedContextFolder = null; private void onMarkAllAsRead(final Account account, final String folder) { mSelectedContextFolder = mAdapter.getFolder(folder); showDialog(DIALOG_MARK_ALL_AS_READ); } @Override public Dialog onCreateDialog(int id) { switch (id) { case DIALOG_MARK_ALL_AS_READ: return createMarkAllAsReadDialog(); } return super.onCreateDialog(id); } @Override public void onPrepareDialog(int id, Dialog dialog) { switch (id) { case DIALOG_MARK_ALL_AS_READ: ((AlertDialog) dialog) .setMessage( getString( R.string.mark_all_as_read_dlg_instructions_fmt, mSelectedContextFolder.displayName)); break; default: super.onPrepareDialog(id, dialog); } } private Dialog createMarkAllAsReadDialog() { return new AlertDialog.Builder(this) .setTitle(R.string.mark_all_as_read_dlg_title) .setMessage( getString( R.string.mark_all_as_read_dlg_instructions_fmt, mSelectedContextFolder.displayName)) .setPositiveButton( R.string.okay_action, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_MARK_ALL_AS_READ); try { MessagingController.getInstance(getApplication()) .markAllMessagesRead(mAccount, mSelectedContextFolder.name); mSelectedContextFolder.unreadMessageCount = 0; mHandler.dataChanged(); } catch (Exception e) { // Ignore } } }) .setNegativeButton( R.string.cancel_action, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_MARK_ALL_AS_READ); } }) .create(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; getMenuInflater().inflate(R.menu.folder_context, menu); FolderInfoHolder folder = (FolderInfoHolder) mAdapter.getItem(info.position); menu.setHeaderTitle(folder.displayName); if (!folder.name.equals(mAccount.getTrashFolderName())) menu.findItem(R.id.empty_trash).setVisible(false); if (folder.name.equals(mAccount.getOutboxFolderName())) { menu.findItem(R.id.check_mail).setVisible(false); } else { menu.findItem(R.id.send_messages).setVisible(false); } if (K9.ERROR_FOLDER_NAME.equals(folder.name)) { menu.findItem(R.id.expunge).setVisible(false); } menu.setHeaderTitle(folder.displayName); } class FolderListAdapter extends BaseAdapter { private ArrayList<FolderInfoHolder> mFolders = new ArrayList<FolderInfoHolder>(); public Object getItem(long position) { return getItem((int) position); } public Object getItem(int position) { return mFolders.get(position); } public long getItemId(int position) { return position; } public int getCount() { return mFolders.size(); } @Override public boolean isEnabled(int item) { return true; } @Override public boolean areAllItemsEnabled() { return true; } private ActivityListener mListener = new ActivityListener() { @Override public void informUserOfStatus() { mHandler.refreshTitle(); } @Override public void accountStatusChanged(BaseAccount account, AccountStats stats) { if (!account.equals(mAccount)) { return; } if (stats == null) { return; } mUnreadMessageCount = stats.unreadMessageCount; super.accountStatusChanged(account, stats); } @Override public void listFoldersStarted(Account account) { if (account.equals(mAccount)) { mHandler.progress(true); } super.listFoldersStarted(account); } @Override public void listFoldersFailed(Account account, String message) { if (account.equals(mAccount)) { mHandler.progress(false); if (Config.LOGV) { Log.v(K9.LOG_TAG, "listFoldersFailed " + message); } } super.listFoldersFailed(account, message); } @Override public void listFoldersFinished(Account account) { if (account.equals(mAccount)) { mHandler.progress(false); MessagingController.getInstance(getApplication()).refreshListener(mAdapter.mListener); mHandler.dataChanged(); } super.listFoldersFinished(account); } @Override public void listFolders(Account account, Folder[] folders) { if (account.equals(mAccount)) { List<FolderInfoHolder> newFolders = new LinkedList<FolderInfoHolder>(); List<FolderInfoHolder> topFolders = new LinkedList<FolderInfoHolder>(); Account.FolderMode aMode = account.getFolderDisplayMode(); Preferences prefs = Preferences.getPreferences(getApplication().getApplicationContext()); for (Folder folder : folders) { try { folder.refresh(prefs); Folder.FolderClass fMode = folder.getDisplayClass(); if ((aMode == Account.FolderMode.FIRST_CLASS && fMode != Folder.FolderClass.FIRST_CLASS) || (aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS && fMode != Folder.FolderClass.FIRST_CLASS && fMode != Folder.FolderClass.SECOND_CLASS) || (aMode == Account.FolderMode.NOT_SECOND_CLASS && fMode == Folder.FolderClass.SECOND_CLASS)) { continue; } } catch (MessagingException me) { Log.e( K9.LOG_TAG, "Couldn't get prefs to check for displayability of folder " + folder.getName(), me); } FolderInfoHolder holder = null; int folderIndex = getFolderIndex(folder.getName()); if (folderIndex >= 0) { holder = (FolderInfoHolder) getItem(folderIndex); } int unreadMessageCount = 0; try { unreadMessageCount = folder.getUnreadMessageCount(); } catch (Exception e) { Log.e( K9.LOG_TAG, "Unable to get unreadMessageCount for " + mAccount.getDescription() + ":" + folder.getName()); } if (holder == null) { holder = new FolderInfoHolder(context, folder, mAccount, unreadMessageCount); } else { holder.populate(context, folder, mAccount, unreadMessageCount); } if (folder.isInTopGroup()) { topFolders.add(holder); } else { newFolders.add(holder); } } Collections.sort(newFolders); Collections.sort(topFolders); topFolders.addAll(newFolders); mHandler.newFolders(topFolders); } super.listFolders(account, folders); } @Override public void synchronizeMailboxStarted(Account account, String folder) { super.synchronizeMailboxStarted(account, folder); if (account.equals(mAccount)) { mHandler.progress(true); mHandler.folderLoading(folder, true); mHandler.dataChanged(); } } @Override public void synchronizeMailboxFinished( Account account, String folder, int totalMessagesInMailbox, int numNewMessages) { super.synchronizeMailboxFinished( account, folder, totalMessagesInMailbox, numNewMessages); if (account.equals(mAccount)) { mHandler.progress(false); mHandler.folderLoading(folder, false); refreshFolder(account, folder); } } private void refreshFolder(Account account, String folderName) { // There has to be a cheaper way to get at the localFolder object than this Folder localFolder = null; try { if (account != null && folderName != null) { if (!account.isAvailable(FolderList.this)) { Log.i(K9.LOG_TAG, "not refreshing folder of unavailable account"); return; } localFolder = account.getLocalStore().getFolder(folderName); int unreadMessageCount = localFolder.getUnreadMessageCount(); FolderInfoHolder folderHolder = getFolder(folderName); if (folderHolder != null) { folderHolder.populate(context, localFolder, mAccount, unreadMessageCount); mHandler.dataChanged(); } } } catch (Exception e) { Log.e(K9.LOG_TAG, "Exception while populating folder", e); } finally { if (localFolder != null) { localFolder.close(); } } } @Override public void synchronizeMailboxFailed(Account account, String folder, String message) { super.synchronizeMailboxFailed(account, folder, message); if (!account.equals(mAccount)) { return; } mHandler.progress(false); mHandler.folderLoading(folder, false); // String mess = truncateStatus(message); // mHandler.folderStatus(folder, mess); FolderInfoHolder holder = getFolder(folder); if (holder != null) { holder.lastChecked = 0; } mHandler.dataChanged(); } @Override public void setPushActive(Account account, String folderName, boolean enabled) { if (!account.equals(mAccount)) { return; } FolderInfoHolder holder = getFolder(folderName); if (holder != null) { holder.pushActive = enabled; mHandler.dataChanged(); } } @Override public void messageDeleted(Account account, String folder, Message message) { synchronizeMailboxRemovedMessage(account, folder, message); } @Override public void emptyTrashCompleted(Account account) { if (account.equals(mAccount)) { refreshFolder(account, mAccount.getTrashFolderName()); } } @Override public void folderStatusChanged( Account account, String folderName, int unreadMessageCount) { if (account.equals(mAccount)) { refreshFolder(account, folderName); } } @Override public void sendPendingMessagesCompleted(Account account) { super.sendPendingMessagesCompleted(account); if (account.equals(mAccount)) { refreshFolder(account, mAccount.getOutboxFolderName()); } } @Override public void sendPendingMessagesStarted(Account account) { super.sendPendingMessagesStarted(account); if (account.equals(mAccount)) { mHandler.dataChanged(); } } @Override public void sendPendingMessagesFailed(Account account) { super.sendPendingMessagesFailed(account); if (account.equals(mAccount)) { refreshFolder(account, mAccount.getOutboxFolderName()); } } @Override public void accountSizeChanged(Account account, long oldSize, long newSize) { if (account.equals(mAccount)) { mHandler.accountSizeChanged(oldSize, newSize); } } }; public int getFolderIndex(String folder) { FolderInfoHolder searchHolder = new FolderInfoHolder(); searchHolder.name = folder; return mFolders.indexOf(searchHolder); } public FolderInfoHolder getFolder(String folder) { FolderInfoHolder holder = null; int index = getFolderIndex(folder); if (index >= 0) { holder = (FolderInfoHolder) getItem(index); if (holder != null) { return holder; } } return null; } public View getView(int position, View convertView, ViewGroup parent) { if (position <= getCount()) { return getItemView(position, convertView, parent); } else { // XXX TODO - should catch an exception here return null; } } public View getItemView(int itemPosition, View convertView, ViewGroup parent) { FolderInfoHolder folder = (FolderInfoHolder) getItem(itemPosition); View view; if (convertView != null) { view = convertView; } else { view = mInflater.inflate(R.layout.folder_list_item, parent, false); } FolderViewHolder holder = (FolderViewHolder) view.getTag(); if (holder == null) { holder = new FolderViewHolder(); holder.folderName = (TextView) view.findViewById(R.id.folder_name); holder.newMessageCount = (TextView) view.findViewById(R.id.folder_unread_message_count); holder.flaggedMessageCount = (TextView) view.findViewById(R.id.folder_flagged_message_count); holder.folderStatus = (TextView) view.findViewById(R.id.folder_status); holder.activeIcons = (RelativeLayout) view.findViewById(R.id.active_icons); holder.chip = view.findViewById(R.id.chip); holder.folderListItemLayout = (LinearLayout) view.findViewById(R.id.folder_list_item_layout); holder.rawFolderName = folder.name; view.setTag(holder); } if (folder == null) { return view; } holder.folderName.setText(folder.displayName); String statusText = ""; if (folder.loading) { statusText = getString(R.string.status_loading); } else if (folder.status != null) { statusText = folder.status; } else if (folder.lastChecked != 0) { Date lastCheckedDate = new Date(folder.lastChecked); statusText = getTimeFormat().format(lastCheckedDate) + " " + getDateFormat().format(lastCheckedDate); } if (folder.pushActive) { statusText = getString(R.string.folder_push_active_symbol) + " " + statusText; } if (statusText != null) { holder.folderStatus.setText(statusText); holder.folderStatus.setVisibility(View.VISIBLE); } else { holder.folderStatus.setText(null); holder.folderStatus.setVisibility(View.GONE); } if (folder.unreadMessageCount != 0) { holder.newMessageCount.setText(Integer.toString(folder.unreadMessageCount)); holder.newMessageCount.setOnClickListener( new FolderClickListener( mAccount, folder.name, folder.displayName, SearchModifier.UNREAD)); holder.newMessageCount.setVisibility(View.VISIBLE); } else { holder.newMessageCount.setVisibility(View.GONE); } if (K9.messageListStars() && folder.flaggedMessageCount > 0) { holder.flaggedMessageCount.setText(Integer.toString(folder.flaggedMessageCount)); holder.flaggedMessageCount.setOnClickListener( new FolderClickListener( mAccount, folder.name, folder.displayName, SearchModifier.FLAGGED)); holder.flaggedMessageCount.setVisibility(View.VISIBLE); } else { holder.flaggedMessageCount.setVisibility(View.GONE); } if (K9.useCompactLayouts() && holder.folderListItemLayout != null) { holder.folderListItemLayout.setMinimumHeight(0); } holder.activeIcons.setOnClickListener( new OnClickListener() { public void onClick(View v) { Toast toast = Toast.makeText( getApplication(), getString(R.string.tap_hint), Toast.LENGTH_SHORT); toast.show(); } }); holder.chip.setBackgroundDrawable(mAccount.generateColorChip().drawable()); holder.chip.getBackground().setAlpha(folder.unreadMessageCount == 0 ? 127 : 255); holder.folderName.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderName()); holder.folderStatus.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mFontSizes.getFolderStatus()); return view; } @Override public boolean hasStableIds() { return false; } public boolean isItemSelectable(int position) { return true; } } static class FolderViewHolder { public TextView folderName; public TextView folderStatus; public TextView newMessageCount; public TextView flaggedMessageCount; public RelativeLayout activeIcons; public String rawFolderName; public View chip; public LinearLayout folderListItemLayout; } private class FolderClickListener implements OnClickListener { final BaseAccount account; final String folderName; final String displayName; final SearchModifier searchModifier; FolderClickListener( BaseAccount nAccount, String folderName, String displayName, SearchModifier nSearchModifier) { account = nAccount; this.folderName = folderName; searchModifier = nSearchModifier; this.displayName = displayName; } @Override public void onClick(View v) { String description = getString( R.string.search_title, getString(R.string.message_list_title, account.getDescription(), displayName), getString(searchModifier.resId)); SearchSpecification searchSpec = new SearchSpecification() { @Override public String[] getAccountUuids() { return new String[] {account.getUuid()}; } @Override public Flag[] getForbiddenFlags() { return searchModifier.forbiddenFlags; } @Override public String getQuery() { return ""; } @Override public Flag[] getRequiredFlags() { return searchModifier.requiredFlags; } @Override public boolean isIntegrate() { return false; } @Override public String[] getFolderNames() { return new String[] {folderName}; } }; MessageList.actionHandle(FolderList.this, description, searchSpec); } } private static Flag[] UNREAD_FLAG_ARRAY = {Flag.SEEN}; private void openUnreadSearch(Context context, final Account account) { String description = getString( R.string.search_title, mAccount.getDescription(), getString(R.string.unread_modifier)); SearchSpecification searchSpec = new SearchSpecification() { // interface has no override @Override public String[] getAccountUuids() { return new String[] {account.getUuid()}; } // interface has no override @Override public Flag[] getForbiddenFlags() { return UNREAD_FLAG_ARRAY; } // interface has no override @Override public String getQuery() { return ""; } @Override public Flag[] getRequiredFlags() { return null; } @Override public boolean isIntegrate() { return false; } @Override public String[] getFolderNames() { return null; } }; MessageList.actionHandle(context, description, searchSpec); } }
public void populate(final Message message, final Account account) throws MessagingException { final Contacts contacts = K9.showContactName() ? mContacts : null; final CharSequence from = Address.toFriendly(message.getFrom(), contacts); final CharSequence to = Address.toFriendly(message.getRecipients(Message.RecipientType.TO), contacts); final CharSequence cc = Address.toFriendly(message.getRecipients(Message.RecipientType.CC), contacts); Address[] fromAddrs = message.getFrom(); Address[] toAddrs = message.getRecipients(Message.RecipientType.TO); Address[] ccAddrs = message.getRecipients(Message.RecipientType.CC); boolean fromMe = mMessageHelper.toMe(account, fromAddrs); String counterpartyAddress = null; if (fromMe) { if (toAddrs.length > 0) { counterpartyAddress = toAddrs[0].getAddress(); } else if (ccAddrs.length > 0) { counterpartyAddress = ccAddrs[0].getAddress(); } } else if (fromAddrs.length > 0) { counterpartyAddress = fromAddrs[0].getAddress(); } /* * Only reset visibility of the subject if populate() was called because a new * message is shown. If it is the same, do not force the subject visible, because * this breaks the MessageTitleView in the action bar, which may hide our subject * if it fits in the action bar but is only called when a new message is shown * or the device is rotated. */ if (mMessage == null || mMessage.getId() != message.getId()) { mSubjectView.setVisibility(VISIBLE); } mMessage = message; mAccount = account; if (K9.showContactPicture()) { mContactBadge.setVisibility(View.VISIBLE); mContactsPictureLoader = new ContactPictureLoader(mContext, R.drawable.ic_contact_picture); } else { mContactBadge.setVisibility(View.GONE); } final String subject = message.getSubject(); if (StringUtils.isNullOrEmpty(subject)) { mSubjectView.setText(mContext.getText(R.string.general_no_subject)); } else { mSubjectView.setText(subject); } mSubjectView.setTextColor(0xff000000 | defaultSubjectColor); String dateTime = DateUtils.formatDateTime( mContext, message.getSentDate().getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR); mDateView.setText(dateTime); if (K9.showContactPicture()) { mContactBadge.assignContactFromEmail(counterpartyAddress, true); if (counterpartyAddress != null) { mContactsPictureLoader.loadContactPicture(counterpartyAddress, mContactBadge); } else { mContactBadge.setImageResource(R.drawable.ic_contact_picture); } } mFromView.setText(from); updateAddressField(mToView, to, mToLabel); updateAddressField(mCcView, cc, mCcLabel); mAnsweredIcon.setVisibility(message.isSet(Flag.ANSWERED) ? View.VISIBLE : View.GONE); mForwardedIcon.setVisibility(message.isSet(Flag.FORWARDED) ? View.VISIBLE : View.GONE); mFlagged.setChecked(message.isSet(Flag.FLAGGED)); int chipColor = mAccount.getChipColor(); int chipColorAlpha = (!message.isSet(Flag.SEEN)) ? 255 : 127; mChip.setBackgroundColor(chipColor); mChip.getBackground().setAlpha(chipColorAlpha); setVisibility(View.VISIBLE); if (mSavedState != null) { if (mSavedState.additionalHeadersVisible) { showAdditionalHeaders(); } mSavedState = null; } else { hideAdditionalHeaders(); } }