Add new "general settings" Activity

This commit is contained in:
cketti 2018-04-05 23:59:08 +02:00
parent f9bf1980fd
commit 3fe2246473
20 changed files with 986 additions and 6 deletions

View file

@ -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

View file

@ -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'

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="application_id" translatable="false">com.fsck.k9.debug</string>
</resources>

View file

@ -303,6 +303,10 @@
android:name=".ui.settings.AboutActivity"
android:label="@string/about_action" />
<activity
android:name=".ui.settings.general.GeneralSettingsActivity"
android:label="@string/general_settings_title" />
<receiver
android:name=".service.BootReceiver"
android:enabled="true">

View file

@ -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);

View file

@ -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++ }")
}

View file

@ -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<String, Any?>) = apply {
arguments = bundleOf(*argumentPairs)
}

View file

@ -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"))
}
}

View file

@ -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)

View file

@ -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 {

View file

@ -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)
}
}
}

View file

@ -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<String>?): Set<String>? {
return when (key) {
"confirm_actions" -> {
mutableSetOf<String>().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<String>().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<String>().apply {
if (K9.useVolumeKeysForNavigationEnabled()) add("message")
if (K9.useVolumeKeysForListNavigationEnabled()) add("list")
}
}
else -> defValues
}
}
override fun putStringSet(key: String, values: MutableSet<String>?) {
val checkedValues = values ?: emptySet<String>()
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()
}
}

View file

@ -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)
}
}

View file

@ -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<CharSequence>()
val newEntryValues = mutableListOf<CharSequence>()
entryValues.forEachIndexed { index, language ->
if (language in supportedLanguages) {
newEntries.add(entries[index])
newEntryValues.add(entryValues[index])
}
}
entries = newEntries.toTypedArray()
entryValues = newEntryValues.toTypedArray()
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/generalSettingsContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="application_id" translatable="false">com.fsck.k9</string>
</resources>

View file

@ -779,4 +779,49 @@
<item>NEVER</item>
<item>WHEN_IN_LANDSCAPE</item>
</string-array>
<string-array name="general_settings_confirm_action_entries">
<item>@string/global_settings_confirm_action_delete</item>
<item>@string/global_settings_confirm_action_delete_starred</item>
<item>@string/global_settings_confirm_action_delete_notif</item>
<item>@string/global_settings_confirm_action_spam</item>
<item>@string/global_settings_confirm_menu_discard</item>
<item>@string/global_settings_confirm_menu_mark_all_read</item>
</string-array>
<string-array name="general_settings_confirm_action_values" translatable="false">
<item>delete</item>
<item>delete_starred</item>
<item>delete_notif</item>
<item>spam</item>
<item>discard</item>
<item>mark_all_read</item>
</string-array>
<string-array name="general_settings_messageview_visible_refile_actions_entries">
<item>@string/delete_action</item>
<item>@string/archive_action</item>
<item>@string/move_action</item>
<item>@string/copy_action</item>
<item>@string/spam_action</item>
</string-array>
<string-array name="general_settings_messageview_visible_refile_actions_values" translatable="false">
<item>delete</item>
<item>archive</item>
<item>move</item>
<item>copy</item>
<item>spam</item>
</string-array>
<string-array name="general_settings_volume_navigation_entries">
<item>@string/volume_navigation_message</item>
<item>@string/volume_navigation_list</item>
</string-array>
<string-array name="general_settings_volume_navigation_values" translatable="false">
<item>message</item>
<item>list</item>
</string-array>
</resources>

View file

@ -10,6 +10,7 @@
<style name="Theme.K9.Dark.Base" parent="Theme.AppCompat" />
<style name="Theme.K9.Light.Common" parent="Theme.K9.Light.Base">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="iconFolder">@drawable/ic_folder_light</item>
<item name="iconListItemMenu">@drawable/dropdown_ic_arrow_normal_holo_light</item>
<item name="iconMenuInfoDetails">@android:drawable/ic_menu_info_details</item>
@ -83,6 +84,7 @@
</style>
<style name="Theme.K9.Dark.Common" parent="Theme.K9.Dark.Base">
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="iconFolder">@drawable/ic_folder_dark</item>
<item name="iconListItemMenu">@drawable/dropdown_ic_arrow_normal_holo_dark</item>
<item name="iconMenuInfoDetails">@android:drawable/ic_menu_info_details</item>

View file

@ -0,0 +1,374 @@
<?xml version="1.0" encoding="utf-8"?>
<!--suppress AndroidElementNotAllowed -->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:title="@string/general_settings_title">
<PreferenceScreen
android:icon="?attr/iconPreferencesDisplay"
android:key="display_preferences"
android:title="@string/display_preferences">
<PreferenceCategory
android:key="global_preferences"
android:title="@string/global_preferences">
<com.fsck.k9.ui.settings.general.LanguagePreference
android:dialogTitle="@string/settings_language_label"
android:entries="@array/settings_language_entries"
android:entryValues="@array/settings_language_values"
android:key="language"
android:summary="%s"
android:title="@string/settings_language_label" />
<ListPreference
android:dialogTitle="@string/settings_theme_label"
android:entries="@array/settings_theme_entries"
android:entryValues="@array/settings_theme_values"
android:key="theme"
android:summary="%s"
android:title="@string/settings_theme_label" />
<CheckBoxPreference
android:key="fixed_message_view_theme"
android:summaryOff="@string/settings_message_theme_selection_summary_off"
android:summaryOn="@string/settings_message_theme_selection_summary_on"
android:title="@string/settings_message_theme_selection_label" />
<ListPreference
android:dependency="fixed_message_view_theme"
android:dialogTitle="@string/settings_message_theme_label"
android:entries="@array/settings_message_theme_entries"
android:entryValues="@array/settings_message_theme_values"
android:key="messageViewTheme"
android:summary="%s"
android:title="@string/settings_message_theme_label" />
<ListPreference
android:dialogTitle="@string/settings_compose_theme_label"
android:entries="@array/settings_message_theme_entries"
android:entryValues="@array/settings_message_theme_values"
android:key="message_compose_theme"
android:summary="%s"
android:title="@string/settings_compose_theme_label" />
<Preference
android:key="font_size"
android:summary="@string/font_size_settings_description"
android:title="@string/font_size_settings_title">
<intent
android:targetClass="com.fsck.k9.activity.setup.FontSizeSettings"
android:targetPackage="@string/application_id" />
</Preference>
<CheckBoxPreference
android:key="animations"
android:summary="@string/animations_summary"
android:title="@string/animations_title" />
</PreferenceCategory>
<PreferenceCategory
android:key="accountlist_preferences"
android:title="@string/accountlist_preferences">
<CheckBoxPreference
android:key="measure_accounts"
android:summary="@string/measure_accounts_summary"
android:title="@string/measure_accounts_title" />
<CheckBoxPreference
android:key="count_search"
android:summary="@string/count_search_summary"
android:title="@string/count_search_title" />
<CheckBoxPreference
android:disableDependentsState="true"
android:key="hide_special_accounts"
android:summary="@string/hide_special_accounts_summary"
android:title="@string/hide_special_accounts_title" />
</PreferenceCategory>
<PreferenceCategory
android:key="folderlist_preferences"
android:title="@string/folderlist_preferences">
<CheckBoxPreference
android:key="folderlist_wrap_folder_name"
android:summary="@string/global_settings_folderlist_wrap_folder_names_summary"
android:title="@string/global_settings_folderlist_wrap_folder_names_label" />
</PreferenceCategory>
<PreferenceCategory
android:key="messagelist_preferences"
android:title="@string/messagelist_preferences">
<ListPreference
android:dialogTitle="@string/global_settings_preview_lines_label"
android:entries="@array/settings_preview_lines_entries"
android:entryValues="@array/settings_preview_lines_values"
android:key="messagelist_preview_lines"
android:summary="%s"
android:title="@string/global_settings_preview_lines_label" />
<CheckBoxPreference
android:key="messagelist_stars"
android:summary="@string/global_settings_flag_summary"
android:title="@string/global_settings_flag_label" />
<CheckBoxPreference
android:key="messagelist_checkboxes"
android:summary="@string/global_settings_checkbox_summary"
android:title="@string/global_settings_checkbox_label" />
<CheckBoxPreference
android:key="messagelist_show_correspondent_names"
android:summary="@string/global_settings_show_correspondent_names_summary"
android:title="@string/global_settings_show_correspondent_names_label" />
<CheckBoxPreference
android:key="messagelist_sender_above_subject"
android:summary="@string/global_settings_sender_above_subject_summary"
android:title="@string/global_settings_sender_above_subject_label" />
<CheckBoxPreference
android:dependency="messagelist_show_correspondent_names"
android:key="messagelist_show_contact_name"
android:summary="@string/global_settings_show_contact_name_summary"
android:title="@string/global_settings_show_contact_name_label" />
<CheckBoxPreference
android:dependency="messagelist_show_contact_name"
android:key="messagelist_change_contact_name_color"
android:summary="@string/global_settings_registered_name_color_changed"
android:title="@string/global_settings_registered_name_color_label" />
<com.takisoft.fix.support.v7.preference.ColorPickerPreference
android:dependency="messagelist_change_contact_name_color"
android:key="messagelist_contact_name_color"
android:title="Contact name color" />
<CheckBoxPreference
android:key="messagelist_show_contact_picture"
android:summary="@string/global_settings_show_contact_picture_summary"
android:title="@string/global_settings_show_contact_picture_label" />
<CheckBoxPreference
android:dependency="messagelist_show_contact_picture"
android:key="messagelist_colorize_missing_contact_pictures"
android:summary="@string/global_settings_colorize_missing_contact_pictures_summary"
android:title="@string/global_settings_colorize_missing_contact_pictures_label" />
<CheckBoxPreference
android:key="messagelist_background_as_unread_indicator"
android:summary="@string/global_settings_background_as_unread_indicator_summary"
android:title="@string/global_settings_background_as_unread_indicator_label" />
<CheckBoxPreference
android:key="threaded_view"
android:summary="@string/global_settings_threaded_view_summary"
android:title="@string/global_settings_threaded_view_label" />
<ListPreference
android:dialogTitle="@string/global_settings_splitview_mode_label"
android:entries="@array/global_settings_splitview_mode_entries"
android:entryValues="@array/global_settings_splitview_mode_values"
android:key="splitview_mode"
android:summary="%s"
android:title="@string/global_settings_splitview_mode_label" />
</PreferenceCategory>
<PreferenceCategory
android:key="messageview_preferences"
android:title="@string/messageview_preferences">
<CheckBoxPreference
android:key="messageview_fixedwidth_font"
android:summary="@string/global_settings_messageview_fixedwidth_summary"
android:title="@string/global_settings_messageview_fixedwidth_label" />
<MultiSelectListPreference
android:dialogTitle="@string/global_settings_messageview_visible_refile_actions_title"
android:entries="@array/general_settings_messageview_visible_refile_actions_entries"
android:entryValues="@array/general_settings_messageview_visible_refile_actions_values"
android:key="messageview_visible_refile_actions"
android:summary="@string/global_settings_messageview_visible_refile_actions_summary"
android:title="@string/global_settings_messageview_visible_refile_actions_title" />
<CheckBoxPreference
android:key="messageview_autofit_width"
android:summary="@string/global_settings_messageview_autofit_width_summary"
android:title="@string/global_settings_messageview_autofit_width_label" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesInteraction"
android:key="interaction_preferences"
android:title="@string/interaction_preferences">
<CheckBoxPreference
android:key="start_integrated_inbox"
android:title="@string/start_integrated_inbox_title" />
<CheckBoxPreference
android:key="gestures"
android:summary="@string/gestures_summary"
android:title="@string/gestures_title" />
<MultiSelectListPreference
android:dialogTitle="@string/volume_navigation_title"
android:entries="@array/general_settings_volume_navigation_entries"
android:entryValues="@array/general_settings_volume_navigation_values"
android:key="volume_navigation"
android:title="@string/volume_navigation_title" />
<CheckBoxPreference
android:key="messageview_return_to_list"
android:summary="@string/global_settings_messageview_return_to_list_summary"
android:title="@string/global_settings_messageview_return_to_list_label" />
<CheckBoxPreference
android:key="messageview_show_next"
android:summary="@string/global_settings_messageview_show_next_summary"
android:title="@string/global_settings_messageview_show_next_label" />
<MultiSelectListPreference
android:dialogTitle="@string/global_settings_confirm_actions_title"
android:entries="@array/general_settings_confirm_action_entries"
android:entryValues="@array/general_settings_confirm_action_values"
android:key="confirm_actions"
android:summary="@string/global_settings_confirm_actions_summary"
android:title="@string/global_settings_confirm_actions_title" />
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesNotifications"
android:key="notification_preferences"
android:title="@string/notifications_title">
<CheckBoxPreference
android:key="quiet_time_enabled"
android:summary="@string/quiet_time_description"
android:title="@string/quiet_time" />
<CheckBoxPreference
android:dependency="quiet_time_enabled"
android:key="disable_notifications_during_quiet_time"
android:summary="@string/quiet_time_notification_description"
android:title="@string/quiet_time_notification" />
<com.takisoft.fix.support.v7.preference.TimePickerPreference
android:dependency="quiet_time_enabled"
android:key="quiet_time_starts"
android:title="@string/quiet_time_starts"
app:pref_hourFormat="h24"
app:pref_summaryHasTime="%s" />
<com.takisoft.fix.support.v7.preference.TimePickerPreference
android:dependency="quiet_time_enabled"
android:key="quiet_time_ends"
android:title="@string/quiet_time_ends"
app:pref_hourFormat="h24"
app:pref_summaryHasTime="%s" />
<ListPreference
android:dialogTitle="@string/global_settings_notification_quick_delete_title"
android:entries="@array/global_settings_notification_quick_delete_entries"
android:entryValues="@array/global_settings_notification_quick_delete_values"
android:key="notification_quick_delete"
android:summary="%s"
android:title="@string/global_settings_notification_quick_delete_title" />
<ListPreference
android:dialogTitle="@string/global_settings_lock_screen_notification_visibility_title"
android:entries="@array/global_settings_lock_screen_notification_visibility_entries"
android:entryValues="@array/global_settings_lock_screen_notification_visibility_values"
android:key="lock_screen_notification_visibility"
android:summary="%s"
android:title="@string/global_settings_lock_screen_notification_visibility_title" />
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesNetwork"
android:key="network_preferences"
android:title="@string/network_preferences">
<ListPreference
android:dialogTitle="@string/background_ops_label"
android:entries="@array/background_ops_entries"
android:entryValues="@array/background_ops_values"
android:key="background_ops"
android:summary="%s"
android:title="@string/background_ops_label" />
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesVarious"
android:key="misc_preferences"
android:title="@string/miscellaneous_preferences">
<Preference
android:key="attachment_default_path"
android:title="@string/settings_attachment_default_path" />
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesPrivacy"
android:key="privacy_preferences"
android:title="@string/privacy_preferences">
<ListPreference
android:entries="@array/global_settings_notification_hide_subject_entries"
android:entryValues="@array/global_settings_notification_hide_subject_values"
android:key="notification_hide_subject"
android:summary="%s"
android:title="@string/global_settings_notification_hide_subject_title" />
<CheckBoxPreference
android:key="privacy_hide_useragent"
android:summary="@string/global_settings_privacy_hide_useragent_detail"
android:title="@string/global_settings_privacy_hide_useragent" />
<CheckBoxPreference
android:key="privacy_hide_timezone"
android:summary="@string/global_settings_privacy_hide_timezone_detail"
android:title="@string/global_settings_privacy_hide_timezone" />
<CheckBoxPreference
android:key="privacy_hide_hostname_when_connecting"
android:summary="@string/global_settings_privacy_hide_hostname_when_connecting_detail"
android:title="@string/global_settings_privacy_hide_hostname_when_connecting" />
</PreferenceScreen>
<PreferenceScreen
android:icon="?attr/iconPreferencesDebug"
android:key="debug_preferences"
android:title="@string/debug_preferences">
<CheckBoxPreference
android:key="debug_logging"
android:summary="@string/debug_enable_debug_logging_summary"
android:title="@string/debug_enable_debug_logging_title" />
<CheckBoxPreference
android:key="sensitive_logging"
android:summary="@string/debug_enable_sensitive_logging_summary"
android:title="@string/debug_enable_sensitive_logging_title" />
</PreferenceScreen>
</PreferenceScreen>