diff --git a/gradle.properties b/gradle.properties
index b170f9cd1..af4a74583 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,7 @@
kotlinVersion=1.2.31
androidCompileSdkVersion=27
androidBuildToolsVersion=27.0.3
-androidSupportLibraryVersion=27.0.2
+androidSupportLibraryVersion=27.1.1
timberVersion=4.5.1
koinVersion=0.9.1
@@ -10,5 +10,3 @@ junitVersion=4.12
mockitoVersion=2.18.0
okioVersion=1.14.0
truthVersion=0.35
-
-android.enableAapt2=false
diff --git a/k9mail/build.gradle b/k9mail/build.gradle
index bfc565cbf..d2700ce6e 100644
--- a/k9mail/build.gradle
+++ b/k9mail/build.gradle
@@ -27,8 +27,12 @@ dependencies {
implementation 'commons-io:commons-io:2.4'
implementation "com.android.support:support-v4:${androidSupportLibraryVersion}"
implementation "com.android.support:appcompat-v7:${androidSupportLibraryVersion}"
+ implementation "com.android.support:preference-v14:${androidSupportLibraryVersion}"
+ implementation 'com.takisoft.fix:preference-v7-datetimepicker:27.1.1.1'
+ implementation 'com.takisoft.fix:preference-v7-colorpicker:27.1.1.1'
implementation "com.android.support:recyclerview-v7:${androidSupportLibraryVersion}"
implementation "android.arch.lifecycle:extensions:1.1.0"
+ implementation 'androidx.core:core-ktx:0.3'
implementation 'org.jsoup:jsoup:1.11.2'
implementation 'de.cketti.library.changelog:ckchangelog:1.2.1'
implementation 'com.github.bumptech.glide:glide:3.6.1'
diff --git a/k9mail/src/debug/res/values/app-specific.xml b/k9mail/src/debug/res/values/app-specific.xml
new file mode 100644
index 000000000..3bc22ec0b
--- /dev/null
+++ b/k9mail/src/debug/res/values/app-specific.xml
@@ -0,0 +1,4 @@
+
+
+ com.fsck.k9.debug
+
diff --git a/k9mail/src/main/AndroidManifest.xml b/k9mail/src/main/AndroidManifest.xml
index 51f2f5075..8c9761656 100644
--- a/k9mail/src/main/AndroidManifest.xml
+++ b/k9mail/src/main/AndroidManifest.xml
@@ -303,6 +303,10 @@
android:name=".ui.settings.AboutActivity"
android:label="@string/about_action" />
+
+
diff --git a/k9mail/src/main/java/com/fsck/k9/activity/ColorPickerDialog.java b/k9mail/src/main/java/com/fsck/k9/activity/ColorPickerDialog.java
index 5b1c27c27..9ecd5ee0c 100644
--- a/k9mail/src/main/java/com/fsck/k9/activity/ColorPickerDialog.java
+++ b/k9mail/src/main/java/com/fsck/k9/activity/ColorPickerDialog.java
@@ -38,7 +38,7 @@ public class ColorPickerDialog extends AlertDialog {
mColorChangedListener = listener;
@SuppressLint("InflateParams")
- View view = LayoutInflater.from(context).inflate(R.layout.color_picker_dialog, null);
+ View view = LayoutInflater.from(context).inflate(R.layout.holo_color_picker_dialog, null);
mColorPicker = (ColorPicker) view.findViewById(R.id.color_picker);
mColorPicker.setColor(color);
diff --git a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java b/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java
deleted file mode 100644
index e8a30fadc..000000000
--- a/k9mail/src/main/java/com/fsck/k9/activity/setup/Prefs.java
+++ /dev/null
@@ -1,580 +0,0 @@
-package com.fsck.k9.activity.setup;
-
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceScreen;
-import android.text.TextUtils;
-import android.widget.Toast;
-
-import com.fsck.k9.K9;
-import com.fsck.k9.K9.NotificationHideSubject;
-import com.fsck.k9.K9.NotificationQuickDelete;
-import com.fsck.k9.K9.SplitViewMode;
-import com.fsck.k9.Preferences;
-import com.fsck.k9.R;
-import com.fsck.k9.activity.ColorPickerDialog;
-import com.fsck.k9.activity.K9PreferenceActivity;
-import com.fsck.k9.helper.FileBrowserHelper;
-import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
-import com.fsck.k9.notification.NotificationController;
-import com.fsck.k9.preferences.CheckBoxListPreference;
-import com.fsck.k9.preferences.Storage;
-import com.fsck.k9.preferences.StorageEditor;
-import com.fsck.k9.preferences.TimePickerPreference;
-import com.fsck.k9.service.MailService;
-
-
-public class Prefs extends K9PreferenceActivity {
-
- /**
- * Immutable empty {@link CharSequence} array
- */
- private static final CharSequence[] EMPTY_CHAR_SEQUENCE_ARRAY = new CharSequence[0];
-
- /*
- * Keys of the preferences defined in res/xml/global_preferences.xml
- */
- private static final String PREFERENCE_LANGUAGE = "language";
- private static final String PREFERENCE_THEME = "theme";
- private static final String PREFERENCE_MESSAGE_VIEW_THEME = "messageViewTheme";
- private static final String PREFERENCE_FIXED_MESSAGE_THEME = "fixed_message_view_theme";
- private static final String PREFERENCE_COMPOSER_THEME = "message_compose_theme";
- private static final String PREFERENCE_FONT_SIZE = "font_size";
- private static final String PREFERENCE_ANIMATIONS = "animations";
- private static final String PREFERENCE_GESTURES = "gestures";
- private static final String PREFERENCE_VOLUME_NAVIGATION = "volume_navigation";
- private static final String PREFERENCE_START_INTEGRATED_INBOX = "start_integrated_inbox";
- private static final String PREFERENCE_CONFIRM_ACTIONS = "confirm_actions";
- private static final String PREFERENCE_NOTIFICATION_HIDE_SUBJECT = "notification_hide_subject";
- private static final String PREFERENCE_MEASURE_ACCOUNTS = "measure_accounts";
- private static final String PREFERENCE_COUNT_SEARCH = "count_search";
- private static final String PREFERENCE_HIDE_SPECIAL_ACCOUNTS = "hide_special_accounts";
- private static final String PREFERENCE_MESSAGELIST_CHECKBOXES = "messagelist_checkboxes";
- private static final String PREFERENCE_MESSAGELIST_PREVIEW_LINES = "messagelist_preview_lines";
- private static final String PREFERENCE_MESSAGELIST_SENDER_ABOVE_SUBJECT = "messagelist_sender_above_subject";
- private static final String PREFERENCE_MESSAGELIST_STARS = "messagelist_stars";
- private static final String PREFERENCE_MESSAGELIST_SHOW_CORRESPONDENT_NAMES = "messagelist_show_correspondent_names";
- private static final String PREFERENCE_MESSAGELIST_SHOW_CONTACT_NAME = "messagelist_show_contact_name";
- private static final String PREFERENCE_MESSAGELIST_CONTACT_NAME_COLOR = "messagelist_contact_name_color";
- private static final String PREFERENCE_MESSAGELIST_SHOW_CONTACT_PICTURE = "messagelist_show_contact_picture";
- private static final String PREFERENCE_MESSAGELIST_COLORIZE_MISSING_CONTACT_PICTURES =
- "messagelist_colorize_missing_contact_pictures";
- private static final String PREFERENCE_MESSAGEVIEW_FIXEDWIDTH = "messageview_fixedwidth_font";
- private static final String PREFERENCE_MESSAGEVIEW_VISIBLE_REFILE_ACTIONS = "messageview_visible_refile_actions";
-
- private static final String PREFERENCE_MESSAGEVIEW_RETURN_TO_LIST = "messageview_return_to_list";
- private static final String PREFERENCE_MESSAGEVIEW_SHOW_NEXT = "messageview_show_next";
- private static final String PREFERENCE_QUIET_TIME_ENABLED = "quiet_time_enabled";
- private static final String PREFERENCE_DISABLE_NOTIFICATION_DURING_QUIET_TIME =
- "disable_notifications_during_quiet_time";
- private static final String PREFERENCE_QUIET_TIME_STARTS = "quiet_time_starts";
- private static final String PREFERENCE_QUIET_TIME_ENDS = "quiet_time_ends";
- private static final String PREFERENCE_NOTIF_QUICK_DELETE = "notification_quick_delete";
- private static final String PREFERENCE_LOCK_SCREEN_NOTIFICATION_VISIBILITY = "lock_screen_notification_visibility";
- private static final String PREFERENCE_HIDE_USERAGENT = "privacy_hide_useragent";
- private static final String PREFERENCE_HIDE_TIMEZONE = "privacy_hide_timezone";
- private static final String PREFERENCE_HIDE_HOSTNAME_WHEN_CONNECTING = "privacy_hide_hostname_when_connecting";
-
- private static final String PREFERENCE_AUTOFIT_WIDTH = "messageview_autofit_width";
- private static final String PREFERENCE_BACKGROUND_OPS = "background_ops";
- private static final String PREFERENCE_DEBUG_LOGGING = "debug_logging";
- private static final String PREFERENCE_SENSITIVE_LOGGING = "sensitive_logging";
-
- private static final String PREFERENCE_ATTACHMENT_DEF_PATH = "attachment_default_path";
- private static final String PREFERENCE_BACKGROUND_AS_UNREAD_INDICATOR = "messagelist_background_as_unread_indicator";
- private static final String PREFERENCE_THREADED_VIEW = "threaded_view";
- private static final String PREFERENCE_FOLDERLIST_WRAP_NAME = "folderlist_wrap_folder_name";
- private static final String PREFERENCE_SPLITVIEW_MODE = "splitview_mode";
-
- private static final int ACTIVITY_CHOOSE_FOLDER = 1;
-
- // Named indices for the mVisibleRefileActions field
- private static final int VISIBLE_REFILE_ACTIONS_DELETE = 0;
- private static final int VISIBLE_REFILE_ACTIONS_ARCHIVE = 1;
- private static final int VISIBLE_REFILE_ACTIONS_MOVE = 2;
- private static final int VISIBLE_REFILE_ACTIONS_COPY = 3;
- private static final int VISIBLE_REFILE_ACTIONS_SPAM = 4;
-
- private ListPreference mLanguage;
- private ListPreference mTheme;
- private CheckBoxPreference mFixedMessageTheme;
- private ListPreference mMessageTheme;
- private ListPreference mComposerTheme;
- private CheckBoxPreference mAnimations;
- private CheckBoxPreference mGestures;
- private CheckBoxListPreference mVolumeNavigation;
- private CheckBoxPreference mStartIntegratedInbox;
- private CheckBoxListPreference mConfirmActions;
- private ListPreference mNotificationHideSubject;
- private CheckBoxPreference mMeasureAccounts;
- private CheckBoxPreference mCountSearch;
- private CheckBoxPreference mHideSpecialAccounts;
- private ListPreference mPreviewLines;
- private CheckBoxPreference mSenderAboveSubject;
- private CheckBoxPreference mCheckboxes;
- private CheckBoxPreference mStars;
- private CheckBoxPreference mShowCorrespondentNames;
- private CheckBoxPreference mShowContactName;
- private CheckBoxPreference mChangeContactNameColor;
- private CheckBoxPreference mShowContactPicture;
- private CheckBoxPreference mColorizeMissingContactPictures;
- private CheckBoxPreference mFixedWidth;
- private CheckBoxPreference mReturnToList;
- private CheckBoxPreference mShowNext;
- private CheckBoxPreference mAutofitWidth;
- private ListPreference mBackgroundOps;
- private CheckBoxPreference mDebugLogging;
- private CheckBoxPreference mSensitiveLogging;
- private CheckBoxPreference mHideUserAgent;
- private CheckBoxPreference mHideTimeZone;
- private CheckBoxPreference mHideHostnameWhenConnecting;
- private CheckBoxPreference mWrapFolderNames;
- private CheckBoxListPreference mVisibleRefileActions;
-
- private CheckBoxPreference mQuietTimeEnabled;
- private CheckBoxPreference mDisableNotificationDuringQuietTime;
- private com.fsck.k9.preferences.TimePickerPreference mQuietTimeStarts;
- private com.fsck.k9.preferences.TimePickerPreference mQuietTimeEnds;
- private ListPreference mNotificationQuickDelete;
- private ListPreference mLockScreenNotificationVisibility;
- private Preference mAttachmentPathPreference;
-
- private CheckBoxPreference mBackgroundAsUnreadIndicator;
- private CheckBoxPreference mThreadedView;
- private ListPreference mSplitViewMode;
-
-
- public static void actionPrefs(Context context) {
- Intent i = new Intent(context, Prefs.class);
- context.startActivity(i);
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- addPreferencesFromResource(R.xml.global_preferences);
-
- mLanguage = (ListPreference) findPreference(PREFERENCE_LANGUAGE);
- List entryVector = new ArrayList(Arrays.asList(mLanguage.getEntries()));
- List entryValueVector = new ArrayList(Arrays.asList(mLanguage.getEntryValues()));
- String supportedLanguages[] = getResources().getStringArray(R.array.supported_languages);
- Set supportedLanguageSet = new HashSet(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 ? 6 : 5];
- boolean[] confirmActionValues = new boolean[confirmActionEntries.length];
- 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();
- confirmActionEntries[index] = getString(R.string.global_settings_confirm_menu_mark_all_read);
- confirmActionValues[index++] = K9.confirmMarkAllRead();
-
- 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);
- mHideHostnameWhenConnecting = (CheckBoxPreference)findPreference(PREFERENCE_HIDE_HOSTNAME_WHEN_CONNECTING);
-
- mDebugLogging.setChecked(K9.isDebug());
- mSensitiveLogging.setChecked(K9.DEBUG_SENSITIVE);
- mHideUserAgent.setChecked(K9.hideUserAgent());
- mHideTimeZone.setChecked(K9.hideTimeZone());
- mHideHostnameWhenConnecting.setChecked(K9.hideHostnameWhenConnecting());
-
- 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();
-
- mVisibleRefileActions.setItems(visibleRefileActionsEntries);
- mVisibleRefileActions.setCheckedItems(visibleRefileActionsValues);
-
- mSplitViewMode = (ListPreference) findPreference(PREFERENCE_SPLITVIEW_MODE);
- initListPreference(mSplitViewMode, K9.getSplitViewMode().name(),
- mSplitViewMode.getEntries(), mSplitViewMode.getEntryValues());
- }
-
- private static String themeIdToName(K9.Theme theme) {
- switch (theme) {
- case DARK: return "dark";
- case USE_GLOBAL: return "global";
- default: return "light";
- }
- }
-
- private static K9.Theme themeNameToId(String theme) {
- if (TextUtils.equals(theme, "dark")) {
- return K9.Theme.DARK;
- } else if (TextUtils.equals(theme, "global")) {
- return K9.Theme.USE_GLOBAL;
- } else {
- return K9.Theme.LIGHT;
- }
- }
-
- private void saveSettings() {
- Storage storage = Preferences.getPreferences(this).getStorage();
-
- 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.setConfirmMarkAllRead(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.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.isDebug() && mDebugLogging.isChecked()) {
- Toast.makeText(this, R.string.debug_logging_enabled, Toast.LENGTH_LONG).show();
- }
- K9.setDebug(mDebugLogging.isChecked());
- K9.DEBUG_SENSITIVE = mSensitiveLogging.isChecked();
- K9.setHideUserAgent(mHideUserAgent.isChecked());
- K9.setHideTimeZone(mHideTimeZone.isChecked());
- K9.setHideHostnameWhenConnecting(mHideHostnameWhenConnecting.isChecked());
-
- StorageEditor editor = storage.edit();
- K9.save(editor);
- editor.commit();
-
- if (needsRefresh) {
- MailService.actionReset(this, null);
- }
- }
-
- @Override
- protected void onPause() {
- saveSettings();
- super.onPause();
- }
-
- private void onFontSizeSettings() {
- FontSizeSettings.actionEditSettings(this);
- }
-
- private void onChooseContactNameColor() {
- new ColorPickerDialog(this, new ColorPickerDialog.OnColorChangedListener() {
- public void colorChanged(int color) {
- K9.setContactNameColor(color);
- }
- },
- K9.getContactNameColor()).show();
- }
-
- @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);
- }
-}
diff --git a/k9mail/src/main/java/com/fsck/k9/helper/NamedThreadFactory.kt b/k9mail/src/main/java/com/fsck/k9/helper/NamedThreadFactory.kt
new file mode 100644
index 000000000..265ea4ccc
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/helper/NamedThreadFactory.kt
@@ -0,0 +1,9 @@
+package com.fsck.k9.helper
+
+import java.util.concurrent.ThreadFactory
+
+class NamedThreadFactory(private val threadNamePrefix: String) : ThreadFactory {
+ var counter: Int = 0
+
+ override fun newThread(runnable: Runnable) = Thread(runnable, "$threadNamePrefix-${ counter++ }")
+}
diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/CheckBoxListPreference.java b/k9mail/src/main/java/com/fsck/k9/preferences/CheckBoxListPreference.java
deleted file mode 100644
index 7b14d68d6..000000000
--- a/k9mail/src/main/java/com/fsck/k9/preferences/CheckBoxListPreference.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.fsck.k9.preferences;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.preference.DialogPreference;
-import android.util.AttributeSet;
-
-public class CheckBoxListPreference extends DialogPreference {
-
- private CharSequence[] mItems;
-
- private boolean[] mCheckedItems;
-
- /**
- * checkboxes state when the dialog is displayed
- */
- private boolean[] mPendingItems;
-
- public CheckBoxListPreference(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- public CheckBoxListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onPrepareDialogBuilder(final Builder builder) {
- mPendingItems = new boolean[mItems.length];
-
- System.arraycopy(mCheckedItems, 0, mPendingItems, 0, mCheckedItems.length);
-
- builder.setMultiChoiceItems(mItems, mPendingItems,
- new DialogInterface.OnMultiChoiceClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which,
- final boolean isChecked) {
- mPendingItems[which] = isChecked;
- }
- });
- }
-
- @Override
- protected void onDialogClosed(boolean positiveResult) {
- if (positiveResult) {
- System.arraycopy(mPendingItems, 0, mCheckedItems, 0, mPendingItems.length);
- }
- mPendingItems = null;
- }
-
- public void setItems(final CharSequence[] items) {
- mItems = items;
- }
-
- public void setCheckedItems(final boolean[] items) {
- mCheckedItems = items;
- }
-
- public boolean[] getCheckedItems() {
- return mCheckedItems;
- }
-
-}
diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java b/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java
index 87192866d..c55736da1 100644
--- a/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java
+++ b/k9mail/src/main/java/com/fsck/k9/preferences/GlobalSettings.java
@@ -30,7 +30,6 @@ import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
import com.fsck.k9.preferences.Settings.PseudoEnumSetting;
import com.fsck.k9.preferences.Settings.SettingsDescription;
import com.fsck.k9.preferences.Settings.SettingsUpgrader;
-import com.fsck.k9.preferences.Settings.StringSetting;
import com.fsck.k9.preferences.Settings.V;
import com.fsck.k9.preferences.Settings.WebFontSizeSetting;
@@ -423,7 +422,7 @@ public class GlobalSettings {
super("");
Map mapping = new HashMap<>();
- String[] values = K9.app.getResources().getStringArray(R.array.settings_language_values);
+ String[] values = K9.app.getResources().getStringArray(R.array.language_values);
for (String value : values) {
if (value.length() == 0) {
mapping.put("", "default");
@@ -545,13 +544,15 @@ public class GlobalSettings {
}
private static class TimeSetting extends SettingsDescription {
+ private static final String VALIDATION_EXPRESSION = "[0-2]*[0-9]:[0-5]*[0-9]";
+
TimeSetting(String defaultValue) {
super(defaultValue);
}
@Override
public String fromString(String value) throws InvalidSettingValueException {
- if (!value.matches(TimePickerPreference.VALIDATION_EXPRESSION)) {
+ if (!value.matches(VALIDATION_EXPRESSION)) {
throw new InvalidSettingValueException();
}
return value;
diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/TimePickerPreference.java b/k9mail/src/main/java/com/fsck/k9/preferences/TimePickerPreference.java
deleted file mode 100644
index 24e418f7a..000000000
--- a/k9mail/src/main/java/com/fsck/k9/preferences/TimePickerPreference.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Sourced from http://www.ebessette.com/d/TimePickerPreference
- * on 2010-11-27 by jessev
- */
-
-package com.fsck.k9.preferences;
-
-import java.util.Locale;
-
-import android.content.Context;
-import android.preference.DialogPreference;
-import android.text.format.DateFormat;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.TimePicker;
-
-/**
- * A preference type that allows a user to choose a time
- */
-public class TimePickerPreference extends DialogPreference implements
- TimePicker.OnTimeChangedListener {
-
- /**
- * The validation expression for this preference
- */
- public static final String VALIDATION_EXPRESSION = "[0-2]*[0-9]:[0-5]*[0-9]";
-
- /**
- * The default value for this preference
- */
- private String defaultValue;
- /**
- * Store the original value, in case the user
- * chooses to abort the {@link DialogPreference}
- * after making a change.
- */
- private int originalHour = 0;
- /**
- * Store the original value, in case the user
- * chooses to abort the {@link DialogPreference}
- * after making a change.
- */
- private int originalMinute = 0;
- /**
- * @param context
- * @param attrs
- */
- public TimePickerPreference(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- initialize();
- }
-
- /**
- * @param context
- * @param attrs
- * @param defStyle
- */
- public TimePickerPreference(final Context context, final AttributeSet attrs,
- final int defStyle) {
- super(context, attrs, defStyle);
- initialize();
- }
-
- /**
- * Initialize this preference
- */
- private void initialize() {
- setPersistent(true);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see android.preference.DialogPreference#onCreateDialogView()
- */
- @Override
- protected View onCreateDialogView() {
-
- TimePicker tp = new TimePicker(getContext());
- tp.setIs24HourView(DateFormat.is24HourFormat(getContext()));
- tp.setOnTimeChangedListener(this);
- originalHour = getHour();
- originalMinute = getMinute();
- if (originalHour >= 0 && originalMinute >= 0) {
- tp.setCurrentHour(originalHour);
- tp.setCurrentMinute(originalMinute);
- }
-
- return tp;
- }
-
- /**
- * @see
- * android.widget.TimePicker.OnTimeChangedListener#onTimeChanged(android
- * .widget.TimePicker, int, int)
- */
- @Override
- public void onTimeChanged(final TimePicker view, final int hour, final int minute) {
-
- persistString(String.format(Locale.US, "%02d:%02d", hour, minute));
- callChangeListener(String.format(Locale.US, "%02d:%02d", hour, minute));
- }
-
- /**
- * If not a positive result, restore the original value
- * before going to super.onDialogClosed(positiveResult).
- */
- @Override
- protected void onDialogClosed(boolean positiveResult) {
-
- if (!positiveResult) {
- persistString(String.format(Locale.US, "%02d:%02d", originalHour, originalMinute));
- callChangeListener(String.format(Locale.US, "%02d:%02d", originalHour, originalMinute));
- }
- super.onDialogClosed(positiveResult);
- }
-
- /**
- * @see android.preference.Preference#setDefaultValue(java.lang.Object)
- */
- @Override
- public void setDefaultValue(final Object defaultValue) {
- // BUG this method is never called if you use the 'android:defaultValue' attribute in your XML preference file, not sure why it isn't
-
- super.setDefaultValue(defaultValue);
-
- if (!(defaultValue instanceof String)) {
- return;
- }
-
- if (!((String) defaultValue).matches(VALIDATION_EXPRESSION)) {
- return;
- }
-
- this.defaultValue = (String) defaultValue;
- }
-
- /**
- * Get the hour value (in 24 hour time)
- *
- * @return The hour value, will be 0 to 23 (inclusive) or -1 if illegal
- */
- private int getHour() {
- String time = getTime();
- if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
- return -1;
- }
-
- return Integer.parseInt(time.split(":")[0]);
- }
-
- /**
- * Get the minute value
- *
- * @return the minute value, will be 0 to 59 (inclusive) or -1 if illegal
- */
- private int getMinute() {
- String time = getTime();
- if (time == null || !time.matches(VALIDATION_EXPRESSION)) {
- return -1;
- }
-
- return Integer.parseInt(time.split(":")[1]);
- }
-
- /**
- * Get the time. It is only legal, if it matches
- * {@link #VALIDATION_EXPRESSION}.
- *
- * @return the time as hh:mm
- */
- public String getTime() {
- return getPersistedString(this.defaultValue);
- }
-
-}
-
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/FragmentExtras.kt b/k9mail/src/main/java/com/fsck/k9/ui/FragmentExtras.kt
new file mode 100644
index 000000000..33acb6242
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/FragmentExtras.kt
@@ -0,0 +1,27 @@
+package com.fsck.k9.ui
+
+import android.support.v4.app.Fragment
+import android.support.v4.app.FragmentActivity
+import android.support.v4.app.FragmentTransaction
+import androidx.core.os.bundleOf
+
+inline fun FragmentActivity.fragmentTransaction(crossinline block: FragmentTransaction.() -> Unit) {
+ with(supportFragmentManager.beginTransaction()) {
+ block()
+ commit()
+ }
+}
+
+inline fun FragmentActivity.fragmentTransactionWithBackStack(
+ name: String? = null,
+ crossinline block: FragmentTransaction.() -> Unit
+) {
+ fragmentTransaction {
+ block()
+ addToBackStack(name)
+ }
+}
+
+fun Fragment.withArguments(vararg argumentPairs: Pair) = apply {
+ arguments = bundleOf(*argumentPairs)
+}
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/AboutActivity.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/AboutActivity.kt
index 320c7aa8f..eaeff37c0 100644
--- a/k9mail/src/main/java/com/fsck/k9/ui/settings/AboutActivity.kt
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/AboutActivity.kt
@@ -104,6 +104,7 @@ class AboutActivity : K9Activity() {
companion object {
private val USED_LIBRARIES = mapOf(
"Android Support Library" to "https://developer.android.com/topic/libraries/support-library/index.html",
+ "Android-Support-Preference-V7-Fix" to "https://github.com/Gericop/Android-Support-Preference-V7-Fix",
"ckChangeLog" to "https://github.com/cketti/ckChangeLog",
"Commons IO" to "http://commons.apache.org/io/",
"Glide" to "https://github.com/bumptech/glide",
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
index 091264672..ce0885b6d 100644
--- a/k9mail/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/KoinModule.kt
@@ -1,10 +1,19 @@
package com.fsck.k9.ui.settings
+import com.fsck.k9.helper.FileBrowserHelper
+import com.fsck.k9.helper.NamedThreadFactory
import com.fsck.k9.ui.account.AccountsLiveData
+import com.fsck.k9.ui.settings.general.GeneralSettingsDataStore
import org.koin.android.architecture.ext.viewModel
import org.koin.dsl.module.applicationContext
+import java.util.concurrent.Executors
val settingsUiModule = applicationContext {
bean { AccountsLiveData(get()) }
viewModel { SettingsViewModel(get()) }
+ bean { FileBrowserHelper.getInstance() }
+ bean { GeneralSettingsDataStore(get(), get(), get("GeneralSettingsExecutor")) }
+ bean("GeneralSettingsExecutor") {
+ Executors.newSingleThreadExecutor(NamedThreadFactory("GeneralSettingsDataStore"))
+ }
}
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/PreferenceExtras.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/PreferenceExtras.kt
new file mode 100644
index 000000000..4fb7b1091
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/PreferenceExtras.kt
@@ -0,0 +1,11 @@
+package com.fsck.k9.ui.settings
+
+import android.support.v7.preference.Preference
+
+
+inline fun Preference.onClick(crossinline action: () -> Unit) = setOnPreferenceClickListener {
+ action()
+ true
+}
+
+fun Preference.remove() = parent?.removePreference(this)
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/SettingsAction.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/SettingsAction.kt
index 7b20a64a5..d65d784b8 100644
--- a/k9mail/src/main/java/com/fsck/k9/ui/settings/SettingsAction.kt
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/SettingsAction.kt
@@ -2,12 +2,12 @@ package com.fsck.k9.ui.settings
import android.app.Activity
import com.fsck.k9.activity.setup.AccountSetupBasics
-import com.fsck.k9.activity.setup.Prefs
+import com.fsck.k9.ui.settings.general.GeneralSettingsActivity
internal enum class SettingsAction {
GENERAL_SETTINGS {
override fun execute(activity: Activity) {
- Prefs.actionPrefs(activity)
+ GeneralSettingsActivity.start(activity)
}
},
ADD_ACCOUNT {
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsActivity.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsActivity.kt
new file mode 100644
index 000000000..7a40ffe95
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsActivity.kt
@@ -0,0 +1,61 @@
+package com.fsck.k9.ui.settings.general
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.support.v7.preference.PreferenceFragmentCompat
+import android.support.v7.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback
+import android.support.v7.preference.PreferenceScreen
+import android.view.MenuItem
+import com.fsck.k9.R
+import com.fsck.k9.activity.K9Activity
+import com.fsck.k9.ui.fragmentTransaction
+import com.fsck.k9.ui.fragmentTransactionWithBackStack
+
+class GeneralSettingsActivity : K9Activity(), OnPreferenceStartScreenCallback {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.general_settings)
+
+ initializeActionBar()
+
+ if (savedInstanceState == null) {
+ fragmentTransaction {
+ add(R.id.generalSettingsContainer, GeneralSettingsFragment.create())
+ }
+ }
+ }
+
+ private fun initializeActionBar() {
+ val actionBar = supportActionBar ?: throw RuntimeException("getSupportActionBar() == null")
+ actionBar.setDisplayHomeAsUpEnabled(true)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == android.R.id.home) {
+ onBackPressed()
+ return true
+ }
+
+ return super.onOptionsItemSelected(item)
+ }
+
+ override fun onPreferenceStartScreen(
+ caller: PreferenceFragmentCompat, preferenceScreen: PreferenceScreen
+ ): Boolean {
+ fragmentTransactionWithBackStack {
+ replace(R.id.generalSettingsContainer, GeneralSettingsFragment.create(preferenceScreen.key))
+ }
+
+ return true
+ }
+
+
+ companion object {
+ fun start(context: Context) {
+ val intent = Intent(context, GeneralSettingsActivity::class.java)
+ context.startActivity(intent)
+ }
+ }
+}
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt
new file mode 100644
index 000000000..47fed5c09
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsDataStore.kt
@@ -0,0 +1,257 @@
+package com.fsck.k9.ui.settings.general
+
+import android.content.Context
+import android.support.v4.app.FragmentActivity
+import android.support.v7.preference.PreferenceDataStore
+import com.fsck.k9.K9
+import com.fsck.k9.K9.Theme
+import com.fsck.k9.Preferences
+import com.fsck.k9.service.MailService
+import java.util.concurrent.ExecutorService
+
+class GeneralSettingsDataStore(
+ private val context: Context,
+ private val preferences: Preferences,
+ private val executorService: ExecutorService
+) : PreferenceDataStore() {
+ var activity: FragmentActivity? = null
+
+ override fun getBoolean(key: String, defValue: Boolean): Boolean {
+ return when (key) {
+ "fixed_message_view_theme" -> K9.useFixedMessageViewTheme()
+ "animations" -> K9.showAnimations()
+ "measure_accounts" -> K9.measureAccounts()
+ "count_search" -> K9.countSearchMessages()
+ "hide_special_accounts" -> K9.isHideSpecialAccounts()
+ "folderlist_wrap_folder_name" -> K9.wrapFolderNames()
+ "messagelist_stars" -> K9.messageListStars()
+ "messagelist_checkboxes" -> K9.messageListCheckboxes()
+ "messagelist_show_correspondent_names" -> K9.showCorrespondentNames()
+ "messagelist_sender_above_subject" -> K9.messageListSenderAboveSubject()
+ "messagelist_show_contact_name" -> K9.showContactName()
+ "messagelist_change_contact_name_color" -> K9.changeContactNameColor()
+ "messagelist_show_contact_picture" -> K9.showContactPicture()
+ "messagelist_colorize_missing_contact_pictures" -> K9.isColorizeMissingContactPictures()
+ "messagelist_background_as_unread_indicator" -> K9.useBackgroundAsUnreadIndicator()
+ "threaded_view" -> K9.isThreadedViewEnabled()
+ "messageview_fixedwidth_font" -> K9.messageViewFixedWidthFont()
+ "messageview_autofit_width" -> K9.autofitWidth()
+ "start_integrated_inbox" -> K9.startIntegratedInbox()
+ "gestures" -> K9.gesturesEnabled()
+ "messageview_return_to_list" -> K9.messageViewReturnToList()
+ "messageview_show_next" -> K9.messageViewShowNext()
+ "quiet_time_enabled" -> K9.getQuietTimeEnabled()
+ "disable_notifications_during_quiet_time" -> K9.isNotificationDuringQuietTimeEnabled()
+ "privacy_hide_useragent" -> K9.hideUserAgent()
+ "privacy_hide_timezone" -> K9.hideTimeZone()
+ "privacy_hide_hostname_when_connecting" -> K9.hideHostnameWhenConnecting()
+ "debug_logging" -> K9.isDebug()
+ "sensitive_logging" -> K9.DEBUG_SENSITIVE
+ else -> defValue
+ }
+ }
+
+ override fun putBoolean(key: String, value: Boolean) {
+ when (key) {
+ "fixed_message_view_theme" -> K9.setUseFixedMessageViewTheme(value)
+ "animations" -> K9.setAnimations(value)
+ "measure_accounts" -> K9.setMeasureAccounts(value)
+ "count_search" -> K9.setCountSearchMessages(value)
+ "hide_special_accounts" -> K9.setHideSpecialAccounts(value)
+ "folderlist_wrap_folder_name" -> K9.setWrapFolderNames(value)
+ "messagelist_stars" -> K9.setMessageListStars(value)
+ "messagelist_checkboxes" -> K9.setMessageListCheckboxes(value)
+ "messagelist_show_correspondent_names" -> K9.setShowCorrespondentNames(value)
+ "messagelist_sender_above_subject" -> K9.setMessageListSenderAboveSubject(value)
+ "messagelist_show_contact_name" -> K9.setShowContactName(value)
+ "messagelist_change_contact_name_color" -> K9.setChangeContactNameColor(value)
+ "messagelist_show_contact_picture" -> K9.setShowContactPicture(value)
+ "messagelist_colorize_missing_contact_pictures" -> K9.setColorizeMissingContactPictures(value)
+ "messagelist_background_as_unread_indicator" -> K9.setUseBackgroundAsUnreadIndicator(value)
+ "threaded_view" -> K9.setThreadedViewEnabled(value)
+ "messageview_fixedwidth_font" -> K9.setMessageViewFixedWidthFont(value)
+ "messageview_autofit_width" -> K9.setAutofitWidth(value)
+ "start_integrated_inbox" -> K9.setStartIntegratedInbox(value)
+ "gestures" -> K9.setGesturesEnabled(value)
+ "messageview_return_to_list" -> K9.setMessageViewReturnToList(value)
+ "messageview_show_next" -> K9.setMessageViewShowNext(value)
+ "quiet_time_enabled" -> K9.setQuietTimeEnabled(value)
+ "disable_notifications_during_quiet_time" -> K9.setNotificationDuringQuietTimeEnabled(value)
+ "privacy_hide_useragent" -> K9.setHideUserAgent(value)
+ "privacy_hide_timezone" -> K9.setHideTimeZone(value)
+ "privacy_hide_hostname_when_connecting" -> K9.hideHostnameWhenConnecting()
+ "debug_logging" -> K9.setDebug(value)
+ "sensitive_logging" -> K9.DEBUG_SENSITIVE = value
+ else -> return
+ }
+
+ saveSettings()
+ }
+
+ override fun getInt(key: String?, defValue: Int): Int {
+ return when (key) {
+ "messagelist_contact_name_color" -> K9.getContactNameColor()
+ else -> defValue
+ }
+ }
+
+ override fun putInt(key: String?, value: Int) {
+ when (key) {
+ "messagelist_contact_name_color" -> K9.setContactNameColor(value)
+ else -> return
+ }
+
+ saveSettings()
+ }
+
+ override fun getString(key: String, defValue: String?): String? {
+ return when (key) {
+ "language" -> K9.getK9Language()
+ "theme" -> themeToString(K9.getK9Theme())
+ "fixed_message_view_theme" -> themeToString(K9.getK9MessageViewThemeSetting())
+ "message_compose_theme" -> themeToString(K9.getK9ComposerThemeSetting())
+ "messageViewTheme" -> themeToString(K9.getK9MessageViewThemeSetting())
+ "messagelist_preview_lines" -> K9.messageListPreviewLines().toString()
+ "splitview_mode" -> K9.getSplitViewMode().name
+ "notification_quick_delete" -> K9.getNotificationQuickDeleteBehaviour().name
+ "lock_screen_notification_visibility" -> K9.getLockScreenNotificationVisibility().name
+ "background_ops" -> K9.getBackgroundOps().name
+ "notification_hide_subject" -> K9.getNotificationHideSubject().name
+ "attachment_default_path" -> K9.getAttachmentDefaultPath()
+ "quiet_time_starts" -> K9.getQuietTimeStarts()
+ "quiet_time_ends" -> K9.getQuietTimeEnds()
+ else -> defValue
+ }
+ }
+
+ override fun putString(key: String, value: String?) {
+ if (value == null) return
+
+ when (key) {
+ "language" -> setLanguage(value)
+ "theme" -> setTheme(value)
+ "fixed_message_view_theme" -> K9.setK9MessageViewThemeSetting(stringToTheme(value))
+ "message_compose_theme" -> K9.setK9ComposerThemeSetting(stringToTheme(value))
+ "messageViewTheme" -> K9.setK9MessageViewThemeSetting(stringToTheme(value))
+ "messagelist_preview_lines" -> K9.setMessageListPreviewLines(value.toInt())
+ "splitview_mode" -> K9.setSplitViewMode(K9.SplitViewMode.valueOf(value))
+ "notification_quick_delete" -> K9.setNotificationQuickDeleteBehaviour(K9.NotificationQuickDelete.valueOf(value))
+ "lock_screen_notification_visibility" -> K9.setLockScreenNotificationVisibility(K9.LockScreenNotificationVisibility.valueOf(value))
+ "background_ops" -> setBackgroundOps(value)
+ "notification_hide_subject" -> K9.setNotificationHideSubject(K9.NotificationHideSubject.valueOf(value))
+ "attachment_default_path" -> K9.setAttachmentDefaultPath(value)
+ "quiet_time_starts" -> K9.setQuietTimeStarts(value)
+ "quiet_time_ends" -> K9.setQuietTimeEnds(value)
+ else -> return
+ }
+
+ saveSettings()
+ }
+
+ override fun getStringSet(key: String, defValues: Set?): Set? {
+ return when (key) {
+ "confirm_actions" -> {
+ mutableSetOf().apply {
+ if (K9.confirmDelete()) add("delete")
+ if (K9.confirmDeleteStarred()) add("delete_starred")
+ if (K9.confirmDeleteFromNotification()) add("delete_notif")
+ if (K9.confirmSpam()) add("spam")
+ if (K9.confirmDiscardMessage()) add("discard")
+ if (K9.confirmMarkAllRead()) add("mark_all_read")
+ }
+ }
+ "messageview_visible_refile_actions" -> {
+ mutableSetOf().apply {
+ if (K9.isMessageViewDeleteActionVisible()) add("delete")
+ if (K9.isMessageViewArchiveActionVisible()) add("archive")
+ if (K9.isMessageViewMoveActionVisible()) add("move")
+ if (K9.isMessageViewCopyActionVisible()) add("copy")
+ if (K9.isMessageViewSpamActionVisible()) add("spam")
+ }
+ }
+ "volume_navigation" -> {
+ mutableSetOf().apply {
+ if (K9.useVolumeKeysForNavigationEnabled()) add("message")
+ if (K9.useVolumeKeysForListNavigationEnabled()) add("list")
+ }
+ }
+ else -> defValues
+ }
+ }
+
+ override fun putStringSet(key: String, values: MutableSet?) {
+ val checkedValues = values ?: emptySet()
+ when (key) {
+ "confirm_actions" -> {
+ K9.setConfirmDelete("delete" in checkedValues)
+ K9.setConfirmDeleteStarred("delete_starred" in checkedValues)
+ K9.setConfirmDeleteFromNotification("delete_notif" in checkedValues)
+ K9.setConfirmSpam("spam" in checkedValues)
+ K9.setConfirmDiscardMessage("discard" in checkedValues)
+ K9.setConfirmMarkAllRead("mark_all_read" in checkedValues)
+ }
+ "messageview_visible_refile_actions" -> {
+ K9.setMessageViewDeleteActionVisible("delete" in checkedValues)
+ K9.setMessageViewArchiveActionVisible("archive" in checkedValues)
+ K9.setMessageViewMoveActionVisible("move" in checkedValues)
+ K9.setMessageViewCopyActionVisible("copy" in checkedValues)
+ K9.setMessageViewSpamActionVisible("spam" in checkedValues)
+ }
+ "volume_navigation" -> {
+ K9.setUseVolumeKeysForNavigation("message" in checkedValues)
+ K9.setUseVolumeKeysForListNavigation("list" in checkedValues)
+ }
+ else -> return
+ }
+
+ saveSettings()
+ }
+
+ private fun saveSettings() {
+ val editor = preferences.storage.edit()
+ K9.save(editor)
+
+ executorService.execute {
+ editor.commit()
+ }
+ }
+
+ private fun setTheme(value: String?) {
+ K9.setK9Theme(stringToTheme(value))
+ recreateActivity()
+ }
+
+ private fun setLanguage(language: String?) {
+ K9.setK9Language(language)
+ recreateActivity()
+ }
+
+ private fun themeToString(theme: Theme) = when (theme) {
+ Theme.LIGHT -> "light"
+ Theme.DARK -> "dark"
+ Theme.USE_GLOBAL -> "global"
+ }
+
+ private fun stringToTheme(theme: String?) = when (theme) {
+ "light" -> Theme.LIGHT
+ "dark" -> Theme.DARK
+ "global" -> Theme.USE_GLOBAL
+ else -> throw AssertionError()
+ }
+
+ private fun setBackgroundOps(value: String) {
+ val newBackgroundOps = K9.BACKGROUND_OPS.valueOf(value)
+ if (newBackgroundOps != K9.getBackgroundOps()) {
+ K9.setBackgroundOps(value)
+ resetMailService()
+ }
+ }
+
+ private fun resetMailService() {
+ MailService.actionReset(context, null)
+ }
+
+ private fun recreateActivity() {
+ activity?.recreate()
+ }
+}
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt
new file mode 100644
index 000000000..67ee400fa
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/GeneralSettingsFragment.kt
@@ -0,0 +1,127 @@
+package com.fsck.k9.ui.settings.general
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.support.v14.preference.MultiSelectListPreference
+import android.support.v7.preference.Preference
+import com.fsck.k9.R
+import com.fsck.k9.helper.FileBrowserHelper
+import com.fsck.k9.notification.NotificationController
+import com.fsck.k9.ui.settings.onClick
+import com.fsck.k9.ui.settings.remove
+import com.fsck.k9.ui.withArguments
+import com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat
+import org.koin.android.ext.android.inject
+import java.io.File
+
+class GeneralSettingsFragment : PreferenceFragmentCompat() {
+ private val dataStore: GeneralSettingsDataStore by inject()
+ private val fileBrowserHelper: FileBrowserHelper by inject()
+
+ private lateinit var attachmentDefaultPathPreference: Preference
+
+
+ override fun onCreatePreferencesFix(savedInstanceState: Bundle?, rootKey: String?) {
+ preferenceManager.preferenceDataStore = dataStore
+
+ setPreferencesFromResource(R.xml.general_settings, rootKey)
+
+ initializeAttachmentDefaultPathPreference()
+ initializeStartInUnifiedInbox()
+ initializeConfirmActions()
+ initializeLockScreenNotificationVisibility()
+ initializeNotificationQuickDelete()
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ activity?.title = preferenceScreen.title
+ dataStore.activity = activity
+ }
+
+ private fun initializeAttachmentDefaultPathPreference() {
+ findPreference(PREFERENCE_ATTACHMENT_DEFAULT_PATH)?.apply {
+ attachmentDefaultPathPreference = this
+
+ summary = attachmentDefaultPath()
+ onClick {
+ fileBrowserHelper.showFileBrowserActivity(this@GeneralSettingsFragment,
+ File(attachmentDefaultPath()), REQUEST_PICK_DIRECTORY,
+ object : FileBrowserHelper.FileBrowserFailOverCallback {
+ override fun onPathEntered(path: String) {
+ setAttachmentDefaultPath(path)
+ }
+
+ override fun onCancel() = Unit
+ }
+ )
+ }
+ }
+ }
+
+ private fun initializeStartInUnifiedInbox() {
+ findPreference(PREFERENCE_START_IN_UNIFIED_INBOX)?.apply {
+ if (hideSpecialAccounts()) {
+ isEnabled = false
+ }
+ }
+ }
+
+ private fun initializeConfirmActions() {
+ val notificationActionsSupported = NotificationController.platformSupportsExtendedNotifications()
+ if (!notificationActionsSupported) {
+ (findPreference(PREFERENCE_CONFIRM_ACTIONS) as? MultiSelectListPreference)?.apply {
+ val deleteIndex = entryValues.indexOf(CONFIRM_ACTION_DELETE_FROM_NOTIFICATION)
+ entries = entries.filterIndexed { index, _ -> index != deleteIndex }.toTypedArray()
+ entryValues = entryValues.filterIndexed { index, _ -> index != deleteIndex }.toTypedArray()
+ }
+ }
+ }
+
+ private fun initializeLockScreenNotificationVisibility() {
+ val lockScreenNotificationsSupported = NotificationController.platformSupportsLockScreenNotifications()
+ if (!lockScreenNotificationsSupported) {
+ findPreference(PREFERENCE_LOCK_SCREEN_NOTIFICATION_VISIBILITY)?.apply { remove() }
+ }
+ }
+
+ private fun initializeNotificationQuickDelete() {
+ val notificationActionsSupported = NotificationController.platformSupportsExtendedNotifications()
+ if (!notificationActionsSupported) {
+ findPreference(PREFERENCE_NOTIFICATION_QUICK_DELETE)?.apply { remove() }
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
+ if (requestCode == REQUEST_PICK_DIRECTORY && resultCode == Activity.RESULT_OK && result != null) {
+ result.data?.path?.let {
+ setAttachmentDefaultPath(it)
+ }
+ }
+ }
+
+ private fun attachmentDefaultPath() = dataStore.getString(PREFERENCE_ATTACHMENT_DEFAULT_PATH, "")
+
+ private fun setAttachmentDefaultPath(path: String) {
+ attachmentDefaultPathPreference.summary = path
+ dataStore.putString(PREFERENCE_ATTACHMENT_DEFAULT_PATH, path)
+ }
+
+ private fun hideSpecialAccounts() = dataStore.getBoolean(PREFERENCE_HIDE_SPECIAL_ACCOUNTS, false)
+
+
+ companion object {
+ private const val REQUEST_PICK_DIRECTORY = 1
+ private const val PREFERENCE_ATTACHMENT_DEFAULT_PATH = "attachment_default_path"
+ private const val PREFERENCE_START_IN_UNIFIED_INBOX = "start_integrated_inbox"
+ private const val PREFERENCE_HIDE_SPECIAL_ACCOUNTS = "hide_special_accounts"
+ private const val PREFERENCE_CONFIRM_ACTIONS = "confirm_actions"
+ private const val PREFERENCE_LOCK_SCREEN_NOTIFICATION_VISIBILITY = "lock_screen_notification_visibility"
+ private const val PREFERENCE_NOTIFICATION_QUICK_DELETE = "notification_quick_delete"
+ private const val CONFIRM_ACTION_DELETE_FROM_NOTIFICATION = "delete_notif"
+
+ fun create(rootKey: String? = null) = GeneralSettingsFragment().withArguments(
+ PreferenceFragmentCompat.ARG_PREFERENCE_ROOT to rootKey)
+ }
+}
diff --git a/k9mail/src/main/java/com/fsck/k9/ui/settings/general/LanguagePreference.kt b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/LanguagePreference.kt
new file mode 100644
index 000000000..b99df7ae2
--- /dev/null
+++ b/k9mail/src/main/java/com/fsck/k9/ui/settings/general/LanguagePreference.kt
@@ -0,0 +1,39 @@
+package com.fsck.k9.ui.settings.general
+
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.support.v4.content.res.TypedArrayUtils
+import android.support.v7.preference.ListPreference
+import android.util.AttributeSet
+import com.fsck.k9.R
+
+
+class LanguagePreference
+@JvmOverloads
+@SuppressLint("RestrictedApi")
+constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = TypedArrayUtils.getAttr(context,
+ android.support.v7.preference.R.attr.dialogPreferenceStyle,
+ android.R.attr.dialogPreferenceStyle),
+ defStyleRes: Int = 0
+) : ListPreference(context, attrs, defStyleAttr, defStyleRes ) {
+
+ init {
+ val supportedLanguages = context.resources.getStringArray(R.array.supported_languages).toSet()
+
+ val newEntries = mutableListOf()
+ val newEntryValues = mutableListOf()
+ entryValues.forEachIndexed { index, language ->
+ if (language in supportedLanguages) {
+ newEntries.add(entries[index])
+ newEntryValues.add(entryValues[index])
+ }
+ }
+
+ entries = newEntries.toTypedArray()
+ entryValues = newEntryValues.toTypedArray()
+ }
+}
diff --git a/k9mail/src/main/res/layout/general_settings.xml b/k9mail/src/main/res/layout/general_settings.xml
new file mode 100644
index 000000000..23638c59a
--- /dev/null
+++ b/k9mail/src/main/res/layout/general_settings.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/k9mail/src/main/res/layout/color_picker_dialog.xml b/k9mail/src/main/res/layout/holo_color_picker_dialog.xml
similarity index 100%
rename from k9mail/src/main/res/layout/color_picker_dialog.xml
rename to k9mail/src/main/res/layout/holo_color_picker_dialog.xml
diff --git a/k9mail/src/main/res/values/app-specific.xml b/k9mail/src/main/res/values/app-specific.xml
new file mode 100644
index 000000000..448f15fe9
--- /dev/null
+++ b/k9mail/src/main/res/values/app-specific.xml
@@ -0,0 +1,4 @@
+
+
+ com.fsck.k9
+
diff --git a/k9mail/src/main/res/values/arrays.xml b/k9mail/src/main/res/values/arrays.xml
index 997da075c..d559ee105 100644
--- a/k9mail/src/main/res/values/arrays.xml
+++ b/k9mail/src/main/res/values/arrays.xml
@@ -341,254 +341,6 @@
- EXPUNGE_MANUALLY
-
- - @string/setting_language_system
- - Afrikaans
- - Azərbaycan
- - Bahasa indonesia
- - Bahasa melayu
- - Bamanankan
- - Brezhoneg
- - Català
- - Čeština
- - Cymraeg
- - Dansk
- - Deutsch
- - Eesti
- - English
- - Español
- - Esperanto
- - Euskera
- - Ɛʋɛ
- - Français
- - Français (Canada)
- - Fulfulde, Pulaar, Pular
- - Gaeilge
- - Gàidhlig
- - Galego
- - Hausa
- - Hrvatski
- - isiXhosa
- - isiZulu
- - Íslenska
- - Italiano
- - Kinyarwanda
- - Kirundi
- - Kiswahili
- - Latviešu
- - Lietuvių
- - Magyar
- - Malti
- - Nederlands
- - Norsk
- - Norsk Bokmål
- - O\'zbek
- - Polski
- - Português
- - Português (Brasil)
- - Pyccĸий
- - Română
- - Shqip
- - Slovenčina
- - Slovenščina
- - Somali
- - Suomi
- - Svenska
- - Tiếng Việt
- - Tϋrkçe
- - Wolof
- - Yorùbá
- - Ελληνικά
- - аҧсуа бызшәа
- - Беларуская
- - Български
- - Кыргыз
- - Қазақ
- - Македонски
- - Српски
- - Українська
- - Հայերեն
- - עברית
- - اردو
- - العربية
- - پښتو
- - فارسی
- - አማርኛ
- - हिंदी
- - తెలుగు
- - ಕನ್ನಡ
- - ภาษาไทย
- - 한국어
- - 中文(简体)
- - 中文(繁體)
- - 日本語
-
-
-
-
- - af
- - az
- - in
- - ms
- - bm
- - br
- - ca
- - cs
- - cy
- - da
- - de
- - et
- - en
- - es
- - eo
- - eu
- - ee
- - fr
- - fr_CA
- - ff
- - ga
- - gd
- - gl
- - ha
- - hr
- - xs
- - zu
- - is
- - it
- - rw
- - rn
- - sw
- - lv
- - lt
- - hu
- - mt
- - nl
- - no
- - nb
- - uz
- - pl
- - pt_PT
- - pt_BR
- - ru
- - ro
- - sq
- - sk
- - sl
- - so
- - fi
- - sv
- - vi
- - tr
- - wo
- - yo
- - el
- - ab
- - be
- - bg
- - ky
- - kk
- - mk
- - sr
- - uk
- - hy
- - iw
- - ur
- - ar
- - ps
- - fa
- - am
- - hi
- - te
- - kn
- - th
- - ko
- - zh_CN
- - zh_TW
- - ja
-
-
-
-
- - in
- - br
- - ca
- - cs
- - cy
- - da
- - de
- - et
- - en
- - es
- - eo
- - eu
- - fr
- - gd
- - gl
- - hr
- - is
- - it
- - lv
- - lt
- - hu
- - nl
- - nb
- - pl
- - pt_PT
- - pt_BR
- - ru
- - ro
- - sq
- - sk
- - sl
- - fi
- - sv
- - tr
- - el
- - bg
- - sr
- - uk
- - iw
- - fa
- - ko
- - zh_CN
- - zh_TW
- - ja
-
-
-
- - @string/setting_theme_light
- - @string/setting_theme_dark
-
-
-
- - light
- - dark
-
-
-
- - @string/setting_theme_light
- - @string/setting_theme_dark
- - @string/setting_theme_global
-
-
-
- - light
- - dark
- - global
-
-
-
- - @string/background_ops_auto_sync_only
- - @string/background_ops_always
- - @string/background_ops_never
-
-
-
- - WHEN_CHECKED_AUTO_SYNC
- - ALWAYS
- - NEVER
-
-
- @string/font_size_default
- @string/font_size_tiniest
@@ -666,26 +418,6 @@
- 10
-
- - 0
- - 1
- - 2
- - 3
- - 4
- - 5
- - 6
-
-
-
- - 0
- - 1
- - 2
- - 3
- - 4
- - 5
- - 6
-
-
- @string/account_settings_quote_style_prefix
- @string/account_settings_quote_style_header
@@ -728,55 +460,4 @@
- 0
-
- - @string/global_settings_notification_hide_subject_never
- - @string/global_settings_notification_hide_subject_when_locked
- - @string/global_settings_notification_hide_subject_always
-
-
-
- - NEVER
- - WHEN_LOCKED
- - ALWAYS
-
-
-
- - @string/global_settings_notification_quick_delete_never
- - @string/global_settings_notification_quick_delete_when_single_msg
- - @string/global_settings_notification_quick_delete_always
-
-
-
- - NEVER
- - FOR_SINGLE_MSG
- - ALWAYS
-
-
-
- - @string/global_settings_lock_screen_notification_visibility_nothing
- - @string/global_settings_lock_screen_notification_visibility_app_name
- - @string/global_settings_lock_screen_notification_visibility_message_count
- - @string/global_settings_lock_screen_notification_visibility_senders
- - @string/global_settings_lock_screen_notification_visibility_everything
-
-
-
- - NOTHING
- - APP_NAME
- - MESSAGE_COUNT
- - SENDERS
- - EVERYTHING
-
-
-
- - @string/global_settings_splitview_always
- - @string/global_settings_splitview_never
- - @string/global_settings_splitview_when_in_landscape
-
-
-
- - ALWAYS
- - NEVER
- - WHEN_IN_LANDSCAPE
-
diff --git a/k9mail/src/main/res/values/arrays_general_settings.xml b/k9mail/src/main/res/values/arrays_general_settings.xml
new file mode 100644
index 000000000..92438adae
--- /dev/null
+++ b/k9mail/src/main/res/values/arrays_general_settings.xml
@@ -0,0 +1,368 @@
+
+
+
+
+
+ - in
+ - br
+ - ca
+ - cs
+ - cy
+ - da
+ - de
+ - et
+ - en
+ - es
+ - eo
+ - eu
+ - fr
+ - gd
+ - gl
+ - hr
+ - is
+ - it
+ - lv
+ - lt
+ - hu
+ - nl
+ - nb
+ - pl
+ - pt_PT
+ - pt_BR
+ - ru
+ - ro
+ - sq
+ - sk
+ - sl
+ - fi
+ - sv
+ - tr
+ - el
+ - bg
+ - sr
+ - uk
+ - iw
+ - fa
+ - ko
+ - zh_CN
+ - zh_TW
+ - ja
+
+
+
+ - @string/setting_language_system
+ - Afrikaans
+ - Azərbaycan
+ - Bahasa indonesia
+ - Bahasa melayu
+ - Bamanankan
+ - Brezhoneg
+ - Català
+ - Čeština
+ - Cymraeg
+ - Dansk
+ - Deutsch
+ - Eesti
+ - English
+ - Español
+ - Esperanto
+ - Euskera
+ - Ɛʋɛ
+ - Français
+ - Français (Canada)
+ - Fulfulde, Pulaar, Pular
+ - Gaeilge
+ - Gàidhlig
+ - Galego
+ - Hausa
+ - Hrvatski
+ - isiXhosa
+ - isiZulu
+ - Íslenska
+ - Italiano
+ - Kinyarwanda
+ - Kirundi
+ - Kiswahili
+ - Latviešu
+ - Lietuvių
+ - Magyar
+ - Malti
+ - Nederlands
+ - Norsk
+ - Norsk Bokmål
+ - O\'zbek
+ - Polski
+ - Português
+ - Português (Brasil)
+ - Pyccĸий
+ - Română
+ - Shqip
+ - Slovenčina
+ - Slovenščina
+ - Somali
+ - Suomi
+ - Svenska
+ - Tiếng Việt
+ - Tϋrkçe
+ - Wolof
+ - Yorùbá
+ - Ελληνικά
+ - аҧсуа бызшәа
+ - Беларуская
+ - Български
+ - Кыргыз
+ - Қазақ
+ - Македонски
+ - Српски
+ - Українська
+ - Հայերեն
+ - עברית
+ - اردو
+ - العربية
+ - پښتو
+ - فارسی
+ - አማርኛ
+ - हिंदी
+ - తెలుగు
+ - ಕನ್ನಡ
+ - ภาษาไทย
+ - 한국어
+ - 中文(简体)
+ - 中文(繁體)
+ - 日本語
+
+
+
+
+ - af
+ - az
+ - in
+ - ms
+ - bm
+ - br
+ - ca
+ - cs
+ - cy
+ - da
+ - de
+ - et
+ - en
+ - es
+ - eo
+ - eu
+ - ee
+ - fr
+ - fr_CA
+ - ff
+ - ga
+ - gd
+ - gl
+ - ha
+ - hr
+ - xs
+ - zu
+ - is
+ - it
+ - rw
+ - rn
+ - sw
+ - lv
+ - lt
+ - hu
+ - mt
+ - nl
+ - no
+ - nb
+ - uz
+ - pl
+ - pt_PT
+ - pt_BR
+ - ru
+ - ro
+ - sq
+ - sk
+ - sl
+ - so
+ - fi
+ - sv
+ - vi
+ - tr
+ - wo
+ - yo
+ - el
+ - ab
+ - be
+ - bg
+ - ky
+ - kk
+ - mk
+ - sr
+ - uk
+ - hy
+ - iw
+ - ur
+ - ar
+ - ps
+ - fa
+ - am
+ - hi
+ - te
+ - kn
+ - th
+ - ko
+ - zh_CN
+ - zh_TW
+ - ja
+
+
+
+ - @string/setting_theme_light
+ - @string/setting_theme_dark
+
+
+
+ - light
+ - dark
+
+
+
+ - @string/setting_theme_light
+ - @string/setting_theme_dark
+ - @string/setting_theme_global
+
+
+
+ - light
+ - dark
+ - global
+
+
+
+ - @string/background_ops_auto_sync_only
+ - @string/background_ops_always
+ - @string/background_ops_never
+
+
+
+ - WHEN_CHECKED_AUTO_SYNC
+ - ALWAYS
+ - NEVER
+
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+ - 6
+
+
+
+ - @string/global_settings_notification_hide_subject_never
+ - @string/global_settings_notification_hide_subject_when_locked
+ - @string/global_settings_notification_hide_subject_always
+
+
+
+ - NEVER
+ - WHEN_LOCKED
+ - ALWAYS
+
+
+
+ - @string/global_settings_notification_quick_delete_never
+ - @string/global_settings_notification_quick_delete_when_single_msg
+ - @string/global_settings_notification_quick_delete_always
+
+
+
+ - NEVER
+ - FOR_SINGLE_MSG
+ - ALWAYS
+
+
+
+ - @string/global_settings_lock_screen_notification_visibility_nothing
+ - @string/global_settings_lock_screen_notification_visibility_app_name
+ - @string/global_settings_lock_screen_notification_visibility_message_count
+ - @string/global_settings_lock_screen_notification_visibility_senders
+ - @string/global_settings_lock_screen_notification_visibility_everything
+
+
+
+ - NOTHING
+ - APP_NAME
+ - MESSAGE_COUNT
+ - SENDERS
+ - EVERYTHING
+
+
+
+ - @string/global_settings_splitview_always
+ - @string/global_settings_splitview_never
+ - @string/global_settings_splitview_when_in_landscape
+
+
+
+ - ALWAYS
+ - NEVER
+ - WHEN_IN_LANDSCAPE
+
+
+
+ - @string/global_settings_confirm_action_delete
+ - @string/global_settings_confirm_action_delete_starred
+ - @string/global_settings_confirm_action_delete_notif
+ - @string/global_settings_confirm_action_spam
+ - @string/global_settings_confirm_menu_discard
+ - @string/global_settings_confirm_menu_mark_all_read
+
+
+
+ - delete
+ - delete_starred
+ - delete_notif
+ - spam
+ - discard
+ - mark_all_read
+
+
+
+ - @string/delete_action
+ - @string/archive_action
+ - @string/move_action
+ - @string/copy_action
+ - @string/spam_action
+
+
+
+ - delete
+ - archive
+ - move
+ - copy
+ - spam
+
+
+
+ - @string/volume_navigation_message
+ - @string/volume_navigation_list
+
+
+
+ - message
+ - list
+
+
+
diff --git a/k9mail/src/main/res/values/themes.xml b/k9mail/src/main/res/values/themes.xml
index 2f4c83f5d..27e08885b 100644
--- a/k9mail/src/main/res/values/themes.xml
+++ b/k9mail/src/main/res/values/themes.xml
@@ -10,6 +10,7 @@