blob: 7ca69cc460ba40f52e1441c8ef7a74e84d3da6bc [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2014 Google Inc.
* Licensed to The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.android.mail.ui.settings;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import com.android.mail.preferences.MailPrefs;
import com.android.mail.preferences.MailPrefs.PreferenceKeys;
import com.android.mail.providers.SuggestionsProvider;
import com.android.mail.providers.UIProvider.AutoAdvance;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.android.mail.R;
import com.google.common.annotations.VisibleForTesting;
/**
* This fragment shows general app preferences.
*/
public class GeneralPrefsFragment extends MailPreferenceFragment
implements OnClickListener, OnPreferenceChangeListener {
// Keys used to reference pref widgets which don't map directly to preference entries
static final String AUTO_ADVANCE_WIDGET = "auto-advance-widget";
static final String CALLED_FROM_TEST = "called-from-test";
// Category for removal actions
protected static final String REMOVAL_ACTIONS_GROUP = "removal-actions-group";
protected MailPrefs mMailPrefs;
private AlertDialog mClearSearchHistoryDialog;
private ListPreference mAutoAdvance;
private static final int[] AUTO_ADVANCE_VALUES = {
AutoAdvance.NEWER,
AutoAdvance.OLDER,
AutoAdvance.LIST
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mMailPrefs = MailPrefs.get(getActivity());
// Set the shared prefs name to use prefs auto-persist behavior by default.
// Any pref more complex than the default (say, involving migration), should set
// "persistent=false" in the XML and manually handle preference initialization and change.
getPreferenceManager()
.setSharedPreferencesName(mMailPrefs.getSharedPreferencesName());
addPreferencesFromResource(R.xml.general_preferences);
mAutoAdvance = (ListPreference) findPreference(AUTO_ADVANCE_WIDGET);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
/*
* We deliberately do not call super because our menu includes the parent's menu options to
* allow custom ordering.
*/
menu.clear();
inflater.inflate(R.menu.general_prefs_fragment_menu, menu);
MenuItem feedbackMenuItem = menu.findItem(R.id.help_info_menu_item);
Uri feedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
if (feedbackMenuItem != null) {
feedbackMenuItem.setVisible(!Uri.EMPTY.equals(feedbackUri));
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int itemId = item.getItemId();
if (itemId == R.id.clear_search_history_menu_item) {
clearSearchHistory();
return true;
} else if (itemId == R.id.clear_picture_approvals_menu_item) {
clearDisplayImages();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (getActivity() == null) {
// Monkeys cause bad things. This callback may be delayed if for some reason the
// preference screen was closed really quickly - just bail then.
return false;
}
final String key = preference.getKey();
if (PreferenceKeys.REMOVAL_ACTION.equals(key)) {
final String removalAction = newValue.toString();
mMailPrefs.setRemovalAction(removalAction);
} else if (AUTO_ADVANCE_WIDGET.equals(key)) {
final int prefsAutoAdvanceMode =
AUTO_ADVANCE_VALUES[mAutoAdvance.findIndexOfValue((String) newValue)];
mMailPrefs.setAutoAdvanceMode(prefsAutoAdvanceMode);
} else if (!PreferenceKeys.CONVERSATION_LIST_SWIPE.equals(key) &&
!PreferenceKeys.SHOW_SENDER_IMAGES.equals(key) &&
!PreferenceKeys.DEFAULT_REPLY_ALL.equals(key) &&
!PreferenceKeys.CONVERSATION_OVERVIEW_MODE.equals(key) &&
!PreferenceKeys.CONFIRM_DELETE.equals(key) &&
!PreferenceKeys.CONFIRM_ARCHIVE.equals(key) &&
!PreferenceKeys.CONFIRM_SEND.equals(key)) {
return false;
}
return true;
}
private void clearDisplayImages() {
final ClearPictureApprovalsDialogFragment fragment =
ClearPictureApprovalsDialogFragment.newInstance();
fragment.show(getActivity().getFragmentManager(),
ClearPictureApprovalsDialogFragment.FRAGMENT_TAG);
}
private void clearSearchHistory() {
mClearSearchHistoryDialog = new AlertDialog.Builder(getActivity())
.setMessage(R.string.clear_history_dialog_message)
.setTitle(R.string.clear_history_dialog_title)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setPositiveButton(R.string.clear, this)
.setNegativeButton(R.string.cancel, this)
.show();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (dialog.equals(mClearSearchHistoryDialog)) {
if (which == DialogInterface.BUTTON_POSITIVE) {
final Context context = getActivity();
// Clear the history in the background, as it causes a disk
// write.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
final SuggestionsProvider suggestions =
new SuggestionsProvider(context);
suggestions.clearHistory();
suggestions.cleanup();
return null;
}
}.execute();
Toast.makeText(getActivity(), R.string.search_history_cleared, Toast.LENGTH_SHORT)
.show();
}
}
}
@Override
public void onStop() {
super.onStop();
if (mClearSearchHistoryDialog != null && mClearSearchHistoryDialog.isShowing()) {
mClearSearchHistoryDialog.dismiss();
}
}
@Override
public void onResume() {
super.onResume();
// Manually initialize the preference views that require massaging. Prefs that require
// massaging include:
// 1. a prefs UI control that does not map 1:1 to storage
// 2. a pref that must obtain its initial value from migrated storage, and for which we
// don't want to always persist a migrated value
final int autoAdvanceModeIndex = prefValueToWidgetIndex(AUTO_ADVANCE_VALUES,
mMailPrefs.getAutoAdvanceMode(), AutoAdvance.DEFAULT);
mAutoAdvance.setValueIndex(autoAdvanceModeIndex);
listenForPreferenceChange(
PreferenceKeys.REMOVAL_ACTION,
PreferenceKeys.CONVERSATION_LIST_SWIPE,
PreferenceKeys.SHOW_SENDER_IMAGES,
PreferenceKeys.DEFAULT_REPLY_ALL,
PreferenceKeys.CONVERSATION_OVERVIEW_MODE,
AUTO_ADVANCE_WIDGET,
PreferenceKeys.CONFIRM_DELETE,
PreferenceKeys.CONFIRM_ARCHIVE,
PreferenceKeys.CONFIRM_SEND
);
}
protected boolean supportsArchive() {
return true;
}
/**
* Converts the prefs value into an index useful for configuring the UI widget, falling back to
* the default value if the value from the prefs can't be found for some reason. If neither can
* be found, it throws an {@link java.lang.IllegalArgumentException}
*
* @param conversionArray An array of prefs values, in widget order
* @param prefValue Value of the preference
* @param defaultValue Default value, as a fallback if we can't map the real value
* @return Index of the entry (or fallback) in the conversion array
*/
@VisibleForTesting
static int prefValueToWidgetIndex(int[] conversionArray, int prefValue, int defaultValue) {
for (int i = 0; i < conversionArray.length; i++) {
if (conversionArray[i] == prefValue) {
return i;
}
}
LogUtils.e(LogUtils.TAG, "Can't map preference value " + prefValue);
for (int i = 0; i < conversionArray.length; i++) {
if (conversionArray[i] == defaultValue) {
return i;
}
}
throw new IllegalArgumentException("Can't map default preference value " + prefValue);
}
private void listenForPreferenceChange(String... keys) {
for (String key : keys) {
Preference p = findPreference(key);
if (p != null) {
p.setOnPreferenceChangeListener(this);
}
}
}
}