From 7a2c68216b24c06ce303af6ab557b3c604c59ca1 Mon Sep 17 00:00:00 2001 From: M66B Date: Mon, 6 May 2019 09:10:13 +0200 Subject: [PATCH] Use pager for advanced options --- .../eu/faircode/email/FragmentOptions.java | 949 ++---------------- .../email/FragmentOptionsBehavior.java | 214 ++++ .../email/FragmentOptionsConnection.java | 173 ++++ .../email/FragmentOptionsDisplay.java | 229 +++++ .../email/FragmentOptionsGeneral.java | 241 +++++ .../faircode/email/FragmentOptionsMisc.java | 202 ++++ .../email/FragmentOptionsNotifications.java | 171 ++++ app/src/main/res/layout/fragment_options.xml | 66 +- .../res/layout/fragment_options_behavior.xml | 223 ++++ .../layout/fragment_options_connection.xml | 123 +++ .../res/layout/fragment_options_display.xml | 291 ++++++ .../res/layout/fragment_options_general.xml | 116 +++ .../main/res/layout/fragment_options_misc.xml | 228 +++++ .../layout/fragment_options_notifications.xml | 159 +++ .../res/layout/include_options_behavior.xml | 227 ----- .../res/layout/include_options_connection.xml | 127 --- .../res/layout/include_options_display.xml | 295 ------ .../res/layout/include_options_general.xml | 120 --- .../main/res/layout/include_options_misc.xml | 232 ----- .../layout/include_options_notifications.xml | 163 --- 20 files changed, 2439 insertions(+), 2110 deletions(-) create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsGeneral.java create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java create mode 100644 app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java create mode 100644 app/src/main/res/layout/fragment_options_behavior.xml create mode 100644 app/src/main/res/layout/fragment_options_connection.xml create mode 100644 app/src/main/res/layout/fragment_options_display.xml create mode 100644 app/src/main/res/layout/fragment_options_general.xml create mode 100644 app/src/main/res/layout/fragment_options_misc.xml create mode 100644 app/src/main/res/layout/fragment_options_notifications.xml delete mode 100644 app/src/main/res/layout/include_options_behavior.xml delete mode 100644 app/src/main/res/layout/include_options_connection.xml delete mode 100644 app/src/main/res/layout/include_options_display.xml delete mode 100644 app/src/main/res/layout/include_options_general.xml delete mode 100644 app/src/main/res/layout/include_options_misc.xml delete mode 100644 app/src/main/res/layout/include_options_notifications.xml diff --git a/app/src/main/java/eu/faircode/email/FragmentOptions.java b/app/src/main/java/eu/faircode/email/FragmentOptions.java index 51eb06f899..596279f79e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptions.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptions.java @@ -19,116 +19,26 @@ package eu.faircode.email; Copyright 2018-2019 by Marcel Bokhorst (M66B) */ -import android.app.Dialog; -import android.app.TimePickerDialog; -import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; -import android.media.RingtoneManager; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.Uri; -import android.os.Build; import android.os.Bundle; -import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.TimePicker; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.constraintlayout.widget.Group; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentTransaction; -import androidx.lifecycle.Lifecycle; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.preference.PreferenceManager; +import androidx.viewpager.widget.ViewPager; -import java.text.SimpleDateFormat; -import java.util.Calendar; - -import static android.app.Activity.RESULT_OK; - -public class FragmentOptions extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { - private SwitchCompat swEnabled; - private Spinner spPollInterval; - private SwitchCompat swSchedule; - private TextView tvScheduleStart; - private TextView tvScheduleEnd; - - private TextView tvConnectionType; - private TextView tvConnectionRoaming; - private SwitchCompat swMetered; - private Spinner spDownload; - private SwitchCompat swRoaming; - - private Spinner spStartup; - private SwitchCompat swDate; - private SwitchCompat swThreading; - private SwitchCompat swAvatars; - private SwitchCompat swIdenticons; - private SwitchCompat swCircular; - private SwitchCompat swNameEmail; - private SwitchCompat swSubjectItalic; - private SwitchCompat swFlags; - private SwitchCompat swPreview; - private SwitchCompat swAddresses; - private SwitchCompat swMonospaced; - private SwitchCompat swHtml; - private SwitchCompat swImages; - private SwitchCompat swActionbar; - - private SwitchCompat swPull; - private SwitchCompat swAutoScroll; - private SwitchCompat swSwipeNav; - private SwitchCompat swAutoExpand; - private SwitchCompat swAutoClose; - private SwitchCompat swAutoNext; - private SwitchCompat swCollapse; - private SwitchCompat swAutoRead; - private SwitchCompat swAutoMove; - private SwitchCompat swAutoResize; - private Spinner spAutoResize; - private TextView tvAutoResize; - private SwitchCompat swPrefixOnce; - private SwitchCompat swAutoSend; - - private SwitchCompat swNotifyPreview; - private CheckBox cbNotifyActionTrash; - private CheckBox cbNotifyActionArchive; - private CheckBox cbNotifyActionSeen; - private CheckBox cbNotifyActionReply; - private SwitchCompat swLight; - private Button btnSound; - - private SwitchCompat swBadge; - private SwitchCompat swSubscriptions; - private SwitchCompat swSearchLocal; - - private SwitchCompat swAuthentication; - private SwitchCompat swParanoid; - private TextView tvParanoidHint; - private SwitchCompat swEnglish; - private SwitchCompat swUpdates; - private SwitchCompat swDebug; - - private TextView tvLastCleanup; - - private Group grpSearchLocal; - private Group grpNotification; +public class FragmentOptions extends FragmentBase { + private ViewPager pager; + private PagerAdapter adapter; static String[] OPTIONS_RESTART = new String[]{ "startup", "date", "threading", "avatars", "identicons", "circular", "name_email", "subject_italic", "flags", "preview", @@ -159,575 +69,74 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O View view = inflater.inflate(R.layout.fragment_options, container, false); - // Get controls - swEnabled = view.findViewById(R.id.swEnabled); - spPollInterval = view.findViewById(R.id.spPollInterval); - swSchedule = view.findViewById(R.id.swSchedule); - tvScheduleStart = view.findViewById(R.id.tvScheduleStart); - tvScheduleEnd = view.findViewById(R.id.tvScheduleEnd); + pager = view.findViewById(R.id.pager); + adapter = new PagerAdapter(getChildFragmentManager()); + pager.setAdapter(adapter); - tvConnectionType = view.findViewById(R.id.tvConnectionType); - tvConnectionRoaming = view.findViewById(R.id.tvConnectionRoaming); - swMetered = view.findViewById(R.id.swMetered); - spDownload = view.findViewById(R.id.spDownload); - swRoaming = view.findViewById(R.id.swRoaming); - - spStartup = view.findViewById(R.id.spStartup); - swDate = view.findViewById(R.id.swDate); - swThreading = view.findViewById(R.id.swThreading); - swAvatars = view.findViewById(R.id.swAvatars); - swIdenticons = view.findViewById(R.id.swIdenticons); - swCircular = view.findViewById(R.id.swCircular); - swNameEmail = view.findViewById(R.id.swNameEmail); - swSubjectItalic = view.findViewById(R.id.swSubjectItalic); - swFlags = view.findViewById(R.id.swFlags); - swPreview = view.findViewById(R.id.swPreview); - swAddresses = view.findViewById(R.id.swAddresses); - swMonospaced = view.findViewById(R.id.swMonospaced); - swHtml = view.findViewById(R.id.swHtml); - swImages = view.findViewById(R.id.swImages); - swActionbar = view.findViewById(R.id.swActionbar); - - swPull = view.findViewById(R.id.swPull); - swAutoScroll = view.findViewById(R.id.swAutoScroll); - swSwipeNav = view.findViewById(R.id.swSwipeNav); - swAutoExpand = view.findViewById(R.id.swAutoExpand); - swAutoClose = view.findViewById(R.id.swAutoClose); - swAutoNext = view.findViewById(R.id.swAutoNext); - swCollapse = view.findViewById(R.id.swCollapse); - swAutoRead = view.findViewById(R.id.swAutoRead); - swAutoMove = view.findViewById(R.id.swAutoMove); - swAutoResize = view.findViewById(R.id.swAutoResize); - spAutoResize = view.findViewById(R.id.spAutoResize); - tvAutoResize = view.findViewById(R.id.tvAutoResize); - swPrefixOnce = view.findViewById(R.id.swPrefixOnce); - swAutoSend = view.findViewById(R.id.swAutoSend); - - swNotifyPreview = view.findViewById(R.id.swNotifyPreview); - cbNotifyActionTrash = view.findViewById(R.id.cbNotifyActionTrash); - cbNotifyActionArchive = view.findViewById(R.id.cbNotifyActionArchive); - cbNotifyActionReply = view.findViewById(R.id.cbNotifyActionReply); - cbNotifyActionSeen = view.findViewById(R.id.cbNotifyActionSeen); - swLight = view.findViewById(R.id.swLight); - btnSound = view.findViewById(R.id.btnSound); - - swBadge = view.findViewById(R.id.swBadge); - swSubscriptions = view.findViewById(R.id.swSubscriptions); - swSearchLocal = view.findViewById(R.id.swSearchLocal); - swEnglish = view.findViewById(R.id.swEnglish); - swAuthentication = view.findViewById(R.id.swAuthentication); - swParanoid = view.findViewById(R.id.swParanoid); - tvParanoidHint = view.findViewById(R.id.tvParanoidHint); - swUpdates = view.findViewById(R.id.swUpdates); - swDebug = view.findViewById(R.id.swDebug); - - tvLastCleanup = view.findViewById(R.id.tvLastCleanup); - - grpSearchLocal = view.findViewById(R.id.grpSearchLocal); - grpNotification = view.findViewById(R.id.grpNotification); - - // Wire controls - - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - - setOptions(); - - // General - - swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + addBackPressedListener(new ActivityBase.IBackPressedListener() { @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("enabled", checked).apply(); - spPollInterval.setEnabled(checked); - swSchedule.setEnabled(checked); - ServiceSynchronize.reload(getContext(), true, "enabled=" + checked); - } - }); - - spPollInterval.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long id) { - Object tag = adapterView.getTag(); - int current = (tag == null ? 0 : (Integer) tag); - int[] values = getResources().getIntArray(R.array.pollIntervalValues); - int value = values[position]; - if (value != current) { - adapterView.setTag(value); - prefs.edit().putInt("poll_interval", value).apply(); - WorkerPoll.init(getContext()); - ServiceSynchronize.reload(getContext(), "poll"); - } - } - - @Override - public void onNothingSelected(AdapterView parent) { - prefs.edit().remove("poll_interval").apply(); - WorkerPoll.init(getContext()); - ServiceSynchronize.reload(getContext(), "poll"); - } - }); - - swSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - if (checked) { - if (Helper.isPro(getContext())) { - prefs.edit().putBoolean("schedule", true).apply(); - ServiceSynchronize.reschedule(getContext()); - } else { - swSchedule.setChecked(false); - FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); - fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro"); - fragmentTransaction.commit(); - } - } else { - prefs.edit().putBoolean("schedule", false).apply(); - ServiceSynchronize.reload(getContext(), "schedule=" + checked); + public boolean onBackPressed() { + if (pager.getCurrentItem() == 0) + return false; + else { + pager.setCurrentItem(pager.getCurrentItem() - 1); + return true; } } }); - tvScheduleStart.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Bundle args = new Bundle(); - args.putBoolean("start", true); - DialogFragment timePicker = new TimePickerFragment(); - timePicker.setArguments(args); - timePicker.show(getFragmentManager(), "timePicker"); - } - }); - - tvScheduleEnd.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Bundle args = new Bundle(); - args.putBoolean("start", false); - DialogFragment timePicker = new TimePickerFragment(); - timePicker.setArguments(args); - timePicker.show(getFragmentManager(), "timePicker"); - } - }); - - // Connection - - swMetered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("metered", checked).apply(); - ServiceSynchronize.reload(getContext(), "metered=" + checked); - } - }); - - spDownload.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long id) { - int[] values = getResources().getIntArray(R.array.downloadValues); - prefs.edit().putInt("download", values[position]).apply(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - prefs.edit().remove("download").apply(); - } - }); - - swRoaming.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("roaming", checked).apply(); - ServiceSynchronize.reload(getContext(), "roaming=" + checked); - } - }); - - // Display - - spStartup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long id) { - String[] values = getResources().getStringArray(R.array.startupValues); - prefs.edit().putString("startup", values[position]).apply(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - prefs.edit().remove("startup").apply(); - } - }); - - swDate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("date", checked).apply(); - } - }); - - swThreading.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("threading", checked).apply(); - } - }); - - swAvatars.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("avatars", checked).apply(); - ContactInfo.clearCache(); - } - }); - - swIdenticons.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("identicons", checked).apply(); - ContactInfo.clearCache(); - } - }); - - swCircular.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("circular", checked).apply(); - ContactInfo.clearCache(); - } - }); - - swNameEmail.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("name_email", checked).apply(); - } - }); - - swSubjectItalic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("subject_italic", checked).apply(); - } - }); - - swFlags.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("flags", checked).apply(); - } - }); - - swPreview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("preview", checked).apply(); - } - }); - - swAddresses.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("addresses", checked).apply(); - } - }); - - swMonospaced.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("monospaced", checked).apply(); - } - }); - - swHtml.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autohtml", checked).apply(); - } - }); - - swImages.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoimages", checked).apply(); - } - }); - - swActionbar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("actionbar", checked).apply(); - } - }); - - // Behavior - - swPull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("pull", checked).apply(); - } - }); - - swAutoScroll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoscroll", checked).apply(); - } - }); - - swSwipeNav.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("swipenav", checked).apply(); - } - }); - - swAutoExpand.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoexpand", checked).apply(); - } - }); - - swAutoClose.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoclose", checked).apply(); - swAutoNext.setEnabled(!checked); - } - }); - - swAutoNext.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autonext", checked).apply(); - } - }); - - swCollapse.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("collapse", checked).apply(); - } - }); - - swAutoRead.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoread", checked).apply(); - } - }); - - swAutoMove.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("automove", !checked).apply(); - } - }); - - swAutoResize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autoresize", checked).apply(); - spAutoResize.setEnabled(checked); - } - }); - - spAutoResize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int position, long id) { - int[] values = getResources().getIntArray(R.array.resizeValues); - prefs.edit().putInt("resize", values[position]).apply(); - tvAutoResize.setText(getString(R.string.title_advanced_resize_pixels, values[position])); - } - - @Override - public void onNothingSelected(AdapterView parent) { - prefs.edit().remove("resize").apply(); - } - }); - - swPrefixOnce.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("prefix_once", checked).apply(); - } - }); - - swAutoSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("autosend", !checked).apply(); - } - }); - - // Notifications - - swNotifyPreview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("notify_preview", checked).apply(); - } - }); - - cbNotifyActionTrash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - prefs.edit().putBoolean("notify_trash", checked).apply(); - } - }); - - cbNotifyActionArchive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - prefs.edit().putBoolean("notify_archive", checked).apply(); - } - }); - - cbNotifyActionReply.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - prefs.edit().putBoolean("notify_reply", checked).apply(); - } - }); - - cbNotifyActionSeen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean checked) { - prefs.edit().putBoolean("notify_seen", checked).apply(); - } - }); - - swLight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("light", checked).apply(); - } - }); - - btnSound.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - String sound = prefs.getString("sound", null); - Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.title_advanced_sound)); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false); - intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, sound == null ? null : Uri.parse(sound)); - startActivityForResult(Helper.getChooser(getContext(), intent), ActivitySetup.REQUEST_SOUND); - } - }); - - // Misc - - swBadge.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("badge", checked).apply(); - ServiceSynchronize.reload(getContext(), "badge"); - } - }); - - swSubscriptions.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("subscriptions", checked).apply(); - } - }); - - swSearchLocal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("search_local", checked).apply(); - } - }); - - - final Intent faq = new Intent(Intent.ACTION_VIEW); - faq.setData(Uri.parse(Helper.FAQ_URI + "#user-content-faq86")); - faq.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (faq.resolveActivity(getContext().getPackageManager()) != null) { - tvParanoidHint.getPaint().setUnderlineText(true); - tvParanoidHint.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(faq); - } - }); - } - - swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("english", checked).commit(); // apply won't work here - - Intent intent = new Intent(getContext(), ActivityMain.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity(intent); - Runtime.getRuntime().exit(0); - } - }); - - swAuthentication.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("authentication", checked).apply(); - } - }); - - swParanoid.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("paranoid", checked).apply(); - } - }); - - swUpdates.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("updates", checked).apply(); - } - }); - - swDebug.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { - prefs.edit().putBoolean("debug", checked).apply(); - ServiceSynchronize.reload(getContext(), "debug=" + checked); - } - }); - - long last_cleanup = prefs.getLong("last_cleanup", -1); - java.text.DateFormat df = SimpleDateFormat.getDateTimeInstance(); - tvLastCleanup.setText( - getString(R.string.title_advanced_last_cleanup, - last_cleanup < 0 ? "-" : df.format(last_cleanup))); - - PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this); - return view; } - @Override - public void onResume() { - super.onResume(); + private class PagerAdapter extends FragmentStatePagerAdapter { + public PagerAdapter(FragmentManager fm) { + super(fm); + } - ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - cm.registerNetworkCallback(builder.build(), networkCallback); - } + @Override + public Fragment getItem(int position) { + switch (position) { + case 0: + return new FragmentOptionsGeneral(); + case 1: + return new FragmentOptionsConnection(); + case 2: + return new FragmentOptionsDisplay(); + case 3: + return new FragmentOptionsBehavior(); + case 4: + return new FragmentOptionsNotifications(); + case 5: + return new FragmentOptionsMisc(); + default: + throw new IllegalArgumentException(); + } + } - @Override - public void onPause() { - ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - cm.unregisterNetworkCallback(networkCallback); + @Override + public int getCount() { + return 6; + } - super.onPause(); - } - - @Override - public void onDestroyView() { - PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this); - super.onDestroyView(); + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return getString(R.string.title_advanced_section_general); + case 1: + return getString(R.string.title_advanced_section_connection); + case 2: + return getString(R.string.title_advanced_section_display); + case 3: + return getString(R.string.title_advanced_section_behavior); + case 4: + return getString(R.string.title_advanced_section_notifications); + case 5: + return getString(R.string.title_advanced_section_misc); + default: + throw new IllegalArgumentException(); + } + } } @Override @@ -754,236 +163,6 @@ public class FragmentOptions extends FragmentBase implements SharedPreferences.O editor.remove(option); editor.apply(); - setOptions(); - } - - private void setOptions() { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - - // General - - swEnabled.setChecked(prefs.getBoolean("enabled", true)); - spPollInterval.setEnabled(swEnabled.isChecked()); - swSchedule.setEnabled(swEnabled.isChecked()); - - int pollInterval = prefs.getInt("poll_interval", 0); - int[] pollIntervalValues = getResources().getIntArray(R.array.pollIntervalValues); - for (int pos = 0; pos < pollIntervalValues.length; pos++) - if (pollIntervalValues[pos] == pollInterval) { - spPollInterval.setTag(pollInterval); - spPollInterval.setSelection(pos); - break; - } - - swSchedule.setChecked(prefs.getBoolean("schedule", false)); - tvScheduleStart.setText(formatHour(getContext(), prefs.getInt("schedule_start", 0))); - tvScheduleEnd.setText(formatHour(getContext(), prefs.getInt("schedule_end", 0))); - - // Connection - - swMetered.setChecked(prefs.getBoolean("metered", true)); - - int download = prefs.getInt("download", MessageHelper.DEFAULT_ATTACHMENT_DOWNLOAD_SIZE); - int[] downloadValues = getResources().getIntArray(R.array.downloadValues); - for (int pos = 0; pos < downloadValues.length; pos++) - if (downloadValues[pos] == download) { - spDownload.setSelection(pos); - break; - } - - swRoaming.setChecked(prefs.getBoolean("roaming", true)); - - // Display - - boolean compact = prefs.getBoolean("compact", false); - - String startup = prefs.getString("startup", "unified"); - String[] startupValues = getResources().getStringArray(R.array.startupValues); - for (int pos = 0; pos < startupValues.length; pos++) - if (startupValues[pos].equals(startup)) { - spStartup.setSelection(pos); - break; - } - - swDate.setChecked(prefs.getBoolean("date", true)); - swThreading.setChecked(prefs.getBoolean("threading", true)); - swAvatars.setChecked(prefs.getBoolean("avatars", true)); - swIdenticons.setChecked(prefs.getBoolean("identicons", false)); - swCircular.setChecked(prefs.getBoolean("circular", true)); - swNameEmail.setChecked(prefs.getBoolean("name_email", !compact)); - swSubjectItalic.setChecked(prefs.getBoolean("subject_italic", true)); - swFlags.setChecked(prefs.getBoolean("flags", true)); - swPreview.setChecked(prefs.getBoolean("preview", false)); - swAddresses.setChecked(prefs.getBoolean("addresses", false)); - swMonospaced.setChecked(prefs.getBoolean("monospaced", false)); - swHtml.setChecked(prefs.getBoolean("autohtml", false)); - swImages.setChecked(prefs.getBoolean("autoimages", false)); - swActionbar.setChecked(prefs.getBoolean("actionbar", true)); - - // Behavior - - swPull.setChecked(prefs.getBoolean("pull", true)); - swAutoScroll.setChecked(prefs.getBoolean("autoscroll", false)); - swSwipeNav.setChecked(prefs.getBoolean("swipenav", true)); - swAutoExpand.setChecked(prefs.getBoolean("autoexpand", true)); - swAutoClose.setChecked(prefs.getBoolean("autoclose", true)); - swAutoNext.setChecked(prefs.getBoolean("autonext", false)); - swAutoNext.setEnabled(!swAutoClose.isChecked()); - swCollapse.setChecked(prefs.getBoolean("collapse", false)); - swAutoRead.setChecked(prefs.getBoolean("autoread", false)); - swAutoMove.setChecked(!prefs.getBoolean("automove", false)); - swAutoResize.setChecked(prefs.getBoolean("autoresize", true)); - - int resize = prefs.getInt("resize", FragmentCompose.REDUCED_IMAGE_SIZE); - int[] resizeValues = getResources().getIntArray(R.array.resizeValues); - for (int pos = 0; pos < resizeValues.length; pos++) - if (resizeValues[pos] == resize) { - spAutoResize.setSelection(pos); - tvAutoResize.setText(getString(R.string.title_advanced_resize_pixels, resizeValues[pos])); - break; - } - spAutoResize.setEnabled(swAutoResize.isChecked()); - - swPrefixOnce.setChecked(prefs.getBoolean("prefix_once", false)); - swAutoSend.setChecked(!prefs.getBoolean("autosend", false)); - - // Notifications - - swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true)); - swNotifyPreview.setEnabled(Helper.isPro(getContext())); - cbNotifyActionTrash.setChecked(prefs.getBoolean("notify_trash", true)); - cbNotifyActionArchive.setChecked(prefs.getBoolean("notify_archive", true)); - cbNotifyActionReply.setChecked(prefs.getBoolean("notify_reply", false)); - cbNotifyActionSeen.setChecked(prefs.getBoolean("notify_seen", true)); - swLight.setChecked(prefs.getBoolean("light", false)); - - grpNotification.setVisibility(Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? View.VISIBLE : View.GONE); - - // Misc - - swBadge.setChecked(prefs.getBoolean("badge", true)); - swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false)); - swEnglish.setChecked(prefs.getBoolean("english", false)); - swSearchLocal.setChecked(prefs.getBoolean("search_local", false)); - swAuthentication.setChecked(prefs.getBoolean("authentication", false)); - swParanoid.setChecked(prefs.getBoolean("paranoid", true)); - swUpdates.setChecked(prefs.getBoolean("updates", true)); - swUpdates.setVisibility(Helper.isPlayStoreInstall(getContext()) ? View.GONE : View.VISIBLE); - swDebug.setChecked(prefs.getBoolean("debug", false)); - - grpSearchLocal.setVisibility(Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M ? View.GONE : View.VISIBLE); - } - - private String formatHour(Context context, int minutes) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.HOUR_OF_DAY, minutes / 60); - cal.set(Calendar.MINUTE, minutes % 60); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - return Helper.getTimeInstance(context, SimpleDateFormat.SHORT).format(cal.getTime()); - } - - public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - Bundle args = getArguments(); - boolean start = args.getBoolean("start"); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - int minutes = prefs.getInt("schedule_" + (start ? "start" : "end"), 0); - - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.HOUR_OF_DAY, minutes / 60); - cal.set(Calendar.MINUTE, minutes % 60); - cal.set(Calendar.SECOND, 0); - cal.set(Calendar.MILLISECOND, 0); - - return new TimePickerDialog(getActivity(), this, - cal.get(Calendar.HOUR_OF_DAY), - cal.get(Calendar.MINUTE), - DateFormat.is24HourFormat(getActivity())); - } - - public void onTimeSet(TimePicker view, int hour, int minute) { - Bundle args = getArguments(); - boolean start = args.getBoolean("start"); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt("schedule_" + (start ? "start" : "end"), hour * 60 + minute); - editor.putBoolean("schedule", true); - editor.apply(); - - ServiceSynchronize.reschedule(getContext()); - } - } - - private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { - @Override - public void onAvailable(Network network) { - showConnectionType(); - } - - @Override - public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { - showConnectionType(); - } - - @Override - public void onLost(Network network) { - showConnectionType(); - } - }; - - private void showConnectionType() { - FragmentActivity activity = getActivity(); - if (activity == null) - return; - - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { - Helper.NetworkState networkState = Helper.getNetworkState(getContext()); - - tvConnectionType.setText(networkState.isUnmetered() ? R.string.title_legend_unmetered : R.string.title_legend_metered); - tvConnectionType.setVisibility(networkState.isConnected() ? View.VISIBLE : View.GONE); - tvConnectionRoaming.setVisibility(networkState.isRoaming() ? View.VISIBLE : View.GONE); - } - } - }); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - Log.i("Result class=" + this.getClass().getSimpleName() + - " request=" + requestCode + " result=" + resultCode + " data=" + data); - - if (requestCode == ActivitySetup.REQUEST_SOUND) - if (resultCode == RESULT_OK) { - Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); - Log.i("Selected ringtone=" + uri); - if (uri != null && "file".equals(uri.getScheme())) - uri = null; - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - if (uri == null) - prefs.edit().remove("sound").apply(); - else - prefs.edit().putString("sound", uri.toString()).apply(); - } - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - if ("enabled".equals(key)) - swEnabled.setChecked(prefs.getBoolean(key, true)); - else if ("schedule".equals(key)) - swSchedule.setChecked(prefs.getBoolean(key, false)); - else if ("schedule_start".equals(key)) - tvScheduleStart.setText(formatHour(getContext(), prefs.getInt(key, 0))); - else if ("schedule_end".equals(key)) - tvScheduleEnd.setText(formatHour(getContext(), prefs.getInt(key, 0))); + //setOptions(); } } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java new file mode 100644 index 0000000000..f9cf05d388 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java @@ -0,0 +1,214 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CompoundButton; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.preference.PreferenceManager; + +public class FragmentOptionsBehavior extends FragmentBase { + private SwitchCompat swPull; + private SwitchCompat swAutoScroll; + private SwitchCompat swSwipeNav; + private SwitchCompat swAutoExpand; + private SwitchCompat swAutoClose; + private SwitchCompat swAutoNext; + private SwitchCompat swCollapse; + private SwitchCompat swAutoRead; + private SwitchCompat swAutoMove; + private SwitchCompat swAutoResize; + private Spinner spAutoResize; + private TextView tvAutoResize; + private SwitchCompat swPrefixOnce; + private SwitchCompat swAutoSend; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_behavior, container, false); + + // Get controls + + swPull = view.findViewById(R.id.swPull); + swAutoScroll = view.findViewById(R.id.swAutoScroll); + swSwipeNav = view.findViewById(R.id.swSwipeNav); + swAutoExpand = view.findViewById(R.id.swAutoExpand); + swAutoClose = view.findViewById(R.id.swAutoClose); + swAutoNext = view.findViewById(R.id.swAutoNext); + swCollapse = view.findViewById(R.id.swCollapse); + swAutoRead = view.findViewById(R.id.swAutoRead); + swAutoMove = view.findViewById(R.id.swAutoMove); + swAutoResize = view.findViewById(R.id.swAutoResize); + spAutoResize = view.findViewById(R.id.spAutoResize); + tvAutoResize = view.findViewById(R.id.tvAutoResize); + swPrefixOnce = view.findViewById(R.id.swPrefixOnce); + swAutoSend = view.findViewById(R.id.swAutoSend); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + swPull.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("pull", checked).apply(); + } + }); + + swAutoScroll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoscroll", checked).apply(); + } + }); + + swSwipeNav.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("swipenav", checked).apply(); + } + }); + + swAutoExpand.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoexpand", checked).apply(); + } + }); + + swAutoClose.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoclose", checked).apply(); + swAutoNext.setEnabled(!checked); + } + }); + + swAutoNext.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autonext", checked).apply(); + } + }); + + swCollapse.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("collapse", checked).apply(); + } + }); + + swAutoRead.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoread", checked).apply(); + } + }); + + swAutoMove.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("automove", !checked).apply(); + } + }); + + swAutoResize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoresize", checked).apply(); + spAutoResize.setEnabled(checked); + } + }); + + spAutoResize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long id) { + int[] values = getResources().getIntArray(R.array.resizeValues); + prefs.edit().putInt("resize", values[position]).apply(); + tvAutoResize.setText(getString(R.string.title_advanced_resize_pixels, values[position])); + } + + @Override + public void onNothingSelected(AdapterView parent) { + prefs.edit().remove("resize").apply(); + } + }); + + swPrefixOnce.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("prefix_once", checked).apply(); + } + }); + + swAutoSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autosend", !checked).apply(); + } + }); + + return view; + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + swPull.setChecked(prefs.getBoolean("pull", true)); + swAutoScroll.setChecked(prefs.getBoolean("autoscroll", false)); + swSwipeNav.setChecked(prefs.getBoolean("swipenav", true)); + swAutoExpand.setChecked(prefs.getBoolean("autoexpand", true)); + swAutoClose.setChecked(prefs.getBoolean("autoclose", true)); + swAutoNext.setChecked(prefs.getBoolean("autonext", false)); + swAutoNext.setEnabled(!swAutoClose.isChecked()); + swCollapse.setChecked(prefs.getBoolean("collapse", false)); + swAutoRead.setChecked(prefs.getBoolean("autoread", false)); + swAutoMove.setChecked(!prefs.getBoolean("automove", false)); + swAutoResize.setChecked(prefs.getBoolean("autoresize", true)); + + int resize = prefs.getInt("resize", FragmentCompose.REDUCED_IMAGE_SIZE); + int[] resizeValues = getResources().getIntArray(R.array.resizeValues); + for (int pos = 0; pos < resizeValues.length; pos++) + if (resizeValues[pos] == resize) { + spAutoResize.setSelection(pos); + tvAutoResize.setText(getString(R.string.title_advanced_resize_pixels, resizeValues[pos])); + break; + } + spAutoResize.setEnabled(swAutoResize.isChecked()); + + swPrefixOnce.setChecked(prefs.getBoolean("prefix_once", false)); + swAutoSend.setChecked(!prefs.getBoolean("autosend", false)); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java new file mode 100644 index 0000000000..aad1842171 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java @@ -0,0 +1,173 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.content.Context; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CompoundButton; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.FragmentActivity; +import androidx.lifecycle.Lifecycle; +import androidx.preference.PreferenceManager; + +public class FragmentOptionsConnection extends FragmentBase { + private TextView tvConnectionType; + private TextView tvConnectionRoaming; + private SwitchCompat swMetered; + private Spinner spDownload; + private SwitchCompat swRoaming; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_connection, container, false); + + // Get controls + + tvConnectionType = view.findViewById(R.id.tvConnectionType); + tvConnectionRoaming = view.findViewById(R.id.tvConnectionRoaming); + swMetered = view.findViewById(R.id.swMetered); + spDownload = view.findViewById(R.id.spDownload); + swRoaming = view.findViewById(R.id.swRoaming); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + swMetered.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("metered", checked).apply(); + ServiceSynchronize.reload(getContext(), "metered=" + checked); + } + }); + + spDownload.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long id) { + int[] values = getResources().getIntArray(R.array.downloadValues); + prefs.edit().putInt("download", values[position]).apply(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + prefs.edit().remove("download").apply(); + } + }); + + swRoaming.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("roaming", checked).apply(); + ServiceSynchronize.reload(getContext(), "roaming=" + checked); + } + }); + + return view; + } + + @Override + public void onResume() { + super.onResume(); + + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkRequest.Builder builder = new NetworkRequest.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + cm.registerNetworkCallback(builder.build(), networkCallback); + } + + @Override + public void onPause() { + ConnectivityManager cm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE); + cm.unregisterNetworkCallback(networkCallback); + + super.onPause(); + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + swMetered.setChecked(prefs.getBoolean("metered", true)); + + int download = prefs.getInt("download", MessageHelper.DEFAULT_ATTACHMENT_DOWNLOAD_SIZE); + int[] downloadValues = getResources().getIntArray(R.array.downloadValues); + for (int pos = 0; pos < downloadValues.length; pos++) + if (downloadValues[pos] == download) { + spDownload.setSelection(pos); + break; + } + + swRoaming.setChecked(prefs.getBoolean("roaming", true)); + } + + private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() { + @Override + public void onAvailable(Network network) { + showConnectionType(); + } + + @Override + public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { + showConnectionType(); + } + + @Override + public void onLost(Network network) { + showConnectionType(); + } + }; + + private void showConnectionType() { + FragmentActivity activity = getActivity(); + if (activity == null) + return; + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { + Helper.NetworkState networkState = Helper.getNetworkState(getContext()); + + tvConnectionType.setText(networkState.isUnmetered() ? R.string.title_legend_unmetered : R.string.title_legend_metered); + tvConnectionType.setVisibility(networkState.isConnected() ? View.VISIBLE : View.GONE); + tvConnectionRoaming.setVisibility(networkState.isRoaming() ? View.VISIBLE : View.GONE); + } + } + }); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java new file mode 100644 index 0000000000..a0c923b971 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsDisplay.java @@ -0,0 +1,229 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CompoundButton; +import android.widget.Spinner; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.preference.PreferenceManager; + +public class FragmentOptionsDisplay extends FragmentBase { + private Spinner spStartup; + private SwitchCompat swDate; + private SwitchCompat swThreading; + private SwitchCompat swAvatars; + private SwitchCompat swIdenticons; + private SwitchCompat swCircular; + private SwitchCompat swNameEmail; + private SwitchCompat swSubjectItalic; + private SwitchCompat swFlags; + private SwitchCompat swPreview; + private SwitchCompat swAddresses; + private SwitchCompat swMonospaced; + private SwitchCompat swHtml; + private SwitchCompat swImages; + private SwitchCompat swActionbar; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_display, container, false); + + // Get controls + + spStartup = view.findViewById(R.id.spStartup); + swDate = view.findViewById(R.id.swDate); + swThreading = view.findViewById(R.id.swThreading); + swAvatars = view.findViewById(R.id.swAvatars); + swIdenticons = view.findViewById(R.id.swIdenticons); + swCircular = view.findViewById(R.id.swCircular); + swNameEmail = view.findViewById(R.id.swNameEmail); + swSubjectItalic = view.findViewById(R.id.swSubjectItalic); + swFlags = view.findViewById(R.id.swFlags); + swPreview = view.findViewById(R.id.swPreview); + swAddresses = view.findViewById(R.id.swAddresses); + swMonospaced = view.findViewById(R.id.swMonospaced); + swHtml = view.findViewById(R.id.swHtml); + swImages = view.findViewById(R.id.swImages); + swActionbar = view.findViewById(R.id.swActionbar); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + spStartup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long id) { + String[] values = getResources().getStringArray(R.array.startupValues); + prefs.edit().putString("startup", values[position]).apply(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + prefs.edit().remove("startup").apply(); + } + }); + + swDate.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("date", checked).apply(); + } + }); + + swThreading.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("threading", checked).apply(); + } + }); + + swAvatars.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("avatars", checked).apply(); + ContactInfo.clearCache(); + } + }); + + swIdenticons.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("identicons", checked).apply(); + ContactInfo.clearCache(); + } + }); + + swCircular.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("circular", checked).apply(); + ContactInfo.clearCache(); + } + }); + + swNameEmail.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("name_email", checked).apply(); + } + }); + + swSubjectItalic.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("subject_italic", checked).apply(); + } + }); + + swFlags.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("flags", checked).apply(); + } + }); + + swPreview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("preview", checked).apply(); + } + }); + + swAddresses.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("addresses", checked).apply(); + } + }); + + swMonospaced.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("monospaced", checked).apply(); + } + }); + + swHtml.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autohtml", checked).apply(); + } + }); + + swImages.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("autoimages", checked).apply(); + } + }); + + swActionbar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("actionbar", checked).apply(); + } + }); + + return view; + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + boolean compact = prefs.getBoolean("compact", false); + + String startup = prefs.getString("startup", "unified"); + String[] startupValues = getResources().getStringArray(R.array.startupValues); + for (int pos = 0; pos < startupValues.length; pos++) + if (startupValues[pos].equals(startup)) { + spStartup.setSelection(pos); + break; + } + + swDate.setChecked(prefs.getBoolean("date", true)); + swThreading.setChecked(prefs.getBoolean("threading", true)); + swAvatars.setChecked(prefs.getBoolean("avatars", true)); + swIdenticons.setChecked(prefs.getBoolean("identicons", false)); + swCircular.setChecked(prefs.getBoolean("circular", true)); + swNameEmail.setChecked(prefs.getBoolean("name_email", !compact)); + swSubjectItalic.setChecked(prefs.getBoolean("subject_italic", true)); + swFlags.setChecked(prefs.getBoolean("flags", true)); + swPreview.setChecked(prefs.getBoolean("preview", false)); + swAddresses.setChecked(prefs.getBoolean("addresses", false)); + swMonospaced.setChecked(prefs.getBoolean("monospaced", false)); + swHtml.setChecked(prefs.getBoolean("autohtml", false)); + swImages.setChecked(prefs.getBoolean("autoimages", false)); + swActionbar.setChecked(prefs.getBoolean("actionbar", true)); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsGeneral.java b/app/src/main/java/eu/faircode/email/FragmentOptionsGeneral.java new file mode 100644 index 0000000000..cd95fe8b14 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsGeneral.java @@ -0,0 +1,241 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.app.Dialog; +import android.app.TimePickerDialog; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.CompoundButton; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.TimePicker; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentTransaction; +import androidx.preference.PreferenceManager; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +public class FragmentOptionsGeneral extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { + private SwitchCompat swEnabled; + private Spinner spPollInterval; + private SwitchCompat swSchedule; + private TextView tvScheduleStart; + private TextView tvScheduleEnd; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_general, container, false); + + // Get controls + + swEnabled = view.findViewById(R.id.swEnabled); + spPollInterval = view.findViewById(R.id.spPollInterval); + swSchedule = view.findViewById(R.id.swSchedule); + tvScheduleStart = view.findViewById(R.id.tvScheduleStart); + tvScheduleEnd = view.findViewById(R.id.tvScheduleEnd); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + // General + + swEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("enabled", checked).apply(); + spPollInterval.setEnabled(checked); + swSchedule.setEnabled(checked); + ServiceSynchronize.reload(getContext(), true, "enabled=" + checked); + } + }); + + spPollInterval.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int position, long id) { + Object tag = adapterView.getTag(); + int current = (tag == null ? 0 : (Integer) tag); + int[] values = getResources().getIntArray(R.array.pollIntervalValues); + int value = values[position]; + if (value != current) { + adapterView.setTag(value); + prefs.edit().putInt("poll_interval", value).apply(); + WorkerPoll.init(getContext()); + ServiceSynchronize.reload(getContext(), "poll"); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + prefs.edit().remove("poll_interval").apply(); + WorkerPoll.init(getContext()); + ServiceSynchronize.reload(getContext(), "poll"); + } + }); + + swSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + if (checked) { + if (Helper.isPro(getContext())) { + prefs.edit().putBoolean("schedule", true).apply(); + ServiceSynchronize.reschedule(getContext()); + } else { + swSchedule.setChecked(false); + FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); + fragmentTransaction.replace(R.id.content_frame, new FragmentPro()).addToBackStack("pro"); + fragmentTransaction.commit(); + } + } else { + prefs.edit().putBoolean("schedule", false).apply(); + ServiceSynchronize.reload(getContext(), "schedule=" + checked); + } + } + }); + + tvScheduleStart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putBoolean("start", true); + DialogFragment timePicker = new TimePickerFragment(); + timePicker.setArguments(args); + timePicker.show(getFragmentManager(), "timePicker"); + } + }); + + tvScheduleEnd.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle args = new Bundle(); + args.putBoolean("start", false); + DialogFragment timePicker = new TimePickerFragment(); + timePicker.setArguments(args); + timePicker.show(getFragmentManager(), "timePicker"); + } + }); + + + PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this); + + return view; + } + + @Override + public void onDestroyView() { + PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this); + super.onDestroyView(); + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + swEnabled.setChecked(prefs.getBoolean("enabled", true)); + spPollInterval.setEnabled(swEnabled.isChecked()); + swSchedule.setEnabled(swEnabled.isChecked()); + + int pollInterval = prefs.getInt("poll_interval", 0); + int[] pollIntervalValues = getResources().getIntArray(R.array.pollIntervalValues); + for (int pos = 0; pos < pollIntervalValues.length; pos++) + if (pollIntervalValues[pos] == pollInterval) { + spPollInterval.setTag(pollInterval); + spPollInterval.setSelection(pos); + break; + } + + swSchedule.setChecked(prefs.getBoolean("schedule", false)); + tvScheduleStart.setText(formatHour(getContext(), prefs.getInt("schedule_start", 0))); + tvScheduleEnd.setText(formatHour(getContext(), prefs.getInt("schedule_end", 0))); + } + + private String formatHour(Context context, int minutes) { + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, minutes / 60); + cal.set(Calendar.MINUTE, minutes % 60); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return Helper.getTimeInstance(context, SimpleDateFormat.SHORT).format(cal.getTime()); + } + + public static class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener { + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Bundle args = getArguments(); + boolean start = args.getBoolean("start"); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + int minutes = prefs.getInt("schedule_" + (start ? "start" : "end"), 0); + + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, minutes / 60); + cal.set(Calendar.MINUTE, minutes % 60); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + return new TimePickerDialog(getActivity(), this, + cal.get(Calendar.HOUR_OF_DAY), + cal.get(Calendar.MINUTE), + DateFormat.is24HourFormat(getActivity())); + } + + public void onTimeSet(TimePicker view, int hour, int minute) { + Bundle args = getArguments(); + boolean start = args.getBoolean("start"); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt("schedule_" + (start ? "start" : "end"), hour * 60 + minute); + editor.putBoolean("schedule", true); + editor.apply(); + + ServiceSynchronize.reschedule(getContext()); + } + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if ("enabled".equals(key)) + swEnabled.setChecked(prefs.getBoolean(key, true)); + else if ("schedule".equals(key)) + swSchedule.setChecked(prefs.getBoolean(key, false)); + else if ("schedule_start".equals(key)) + tvScheduleStart.setText(formatHour(getContext(), prefs.getInt(key, 0))); + else if ("schedule_end".equals(key)) + tvScheduleEnd.setText(formatHour(getContext(), prefs.getInt(key, 0))); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java new file mode 100644 index 0000000000..d27df104f0 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsMisc.java @@ -0,0 +1,202 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.constraintlayout.widget.Group; +import androidx.preference.PreferenceManager; + +import java.text.SimpleDateFormat; + +public class FragmentOptionsMisc extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { + private SwitchCompat swBadge; + private SwitchCompat swSubscriptions; + private SwitchCompat swSearchLocal; + private SwitchCompat swEnglish; + private SwitchCompat swAuthentication; + private SwitchCompat swParanoid; + private TextView tvParanoidHint; + private SwitchCompat swUpdates; + private SwitchCompat swDebug; + + private TextView tvLastCleanup; + + private Group grpSearchLocal; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_misc, container, false); + + // Get controls + + swBadge = view.findViewById(R.id.swBadge); + swSubscriptions = view.findViewById(R.id.swSubscriptions); + swSearchLocal = view.findViewById(R.id.swSearchLocal); + swEnglish = view.findViewById(R.id.swEnglish); + swAuthentication = view.findViewById(R.id.swAuthentication); + swParanoid = view.findViewById(R.id.swParanoid); + tvParanoidHint = view.findViewById(R.id.tvParanoidHint); + swUpdates = view.findViewById(R.id.swUpdates); + swDebug = view.findViewById(R.id.swDebug); + + tvLastCleanup = view.findViewById(R.id.tvLastCleanup); + + grpSearchLocal = view.findViewById(R.id.grpSearchLocal); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + swBadge.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("badge", checked).apply(); + ServiceSynchronize.reload(getContext(), "badge"); + } + }); + + swSubscriptions.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("subscriptions", checked).apply(); + } + }); + + swSearchLocal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("search_local", checked).apply(); + } + }); + + swEnglish.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("english", checked).commit(); // apply won't work here + + Intent intent = new Intent(getContext(), ActivityMain.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + Runtime.getRuntime().exit(0); + } + }); + + swAuthentication.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("authentication", checked).apply(); + } + }); + + swParanoid.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("paranoid", checked).apply(); + } + }); + + final Intent faq = new Intent(Intent.ACTION_VIEW); + faq.setData(Uri.parse(Helper.FAQ_URI + "#user-content-faq86")); + faq.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (faq.resolveActivity(getContext().getPackageManager()) != null) { + tvParanoidHint.getPaint().setUnderlineText(true); + tvParanoidHint.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(faq); + } + }); + } + + swUpdates.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("updates", checked).apply(); + } + }); + + swDebug.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("debug", checked).apply(); + ServiceSynchronize.reload(getContext(), "debug=" + checked); + } + }); + + setLastCleanup(prefs.getLong("last_cleanup", -1)); + + PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this); + + return view; + } + + @Override + public void onDestroyView() { + PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this); + super.onDestroyView(); + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + swBadge.setChecked(prefs.getBoolean("badge", true)); + swSubscriptions.setChecked(prefs.getBoolean("subscriptions", false)); + swSearchLocal.setChecked(prefs.getBoolean("search_local", false)); + swEnglish.setChecked(prefs.getBoolean("english", false)); + swAuthentication.setChecked(prefs.getBoolean("authentication", false)); + swParanoid.setChecked(prefs.getBoolean("paranoid", true)); + swUpdates.setChecked(prefs.getBoolean("updates", true)); + swUpdates.setVisibility(Helper.isPlayStoreInstall(getContext()) ? View.GONE : View.VISIBLE); + swDebug.setChecked(prefs.getBoolean("debug", false)); + + grpSearchLocal.setVisibility(Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M ? View.GONE : View.VISIBLE); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + if ("last_cleanup".equals(key)) + setLastCleanup(prefs.getLong(key, -1)); + } + + private void setLastCleanup(long time) { + java.text.DateFormat df = SimpleDateFormat.getDateTimeInstance(); + tvLastCleanup.setText( + getString(R.string.title_advanced_last_cleanup, + time < 0 ? "-" : df.format(time))); + } +} diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java new file mode 100644 index 0000000000..13a8396b82 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java @@ -0,0 +1,171 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2019 by Marcel Bokhorst (M66B) +*/ + +import android.content.Intent; +import android.content.SharedPreferences; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.constraintlayout.widget.Group; +import androidx.preference.PreferenceManager; + +import static android.app.Activity.RESULT_OK; + +public class FragmentOptionsNotifications extends FragmentBase { + private SwitchCompat swNotifyPreview; + private CheckBox cbNotifyActionTrash; + private CheckBox cbNotifyActionArchive; + private CheckBox cbNotifyActionSeen; + private CheckBox cbNotifyActionReply; + private SwitchCompat swLight; + private Button btnSound; + + private Group grpNotification; + + @Override + @Nullable + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + setSubtitle(R.string.title_advanced); + + View view = inflater.inflate(R.layout.fragment_options_notifications, container, false); + + // Get controls + + swNotifyPreview = view.findViewById(R.id.swNotifyPreview); + cbNotifyActionTrash = view.findViewById(R.id.cbNotifyActionTrash); + cbNotifyActionArchive = view.findViewById(R.id.cbNotifyActionArchive); + cbNotifyActionReply = view.findViewById(R.id.cbNotifyActionReply); + cbNotifyActionSeen = view.findViewById(R.id.cbNotifyActionSeen); + swLight = view.findViewById(R.id.swLight); + btnSound = view.findViewById(R.id.btnSound); + + grpNotification = view.findViewById(R.id.grpNotification); + + // Wire controls + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + setOptions(); + + swNotifyPreview.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("notify_preview", checked).apply(); + } + }); + + cbNotifyActionTrash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean checked) { + prefs.edit().putBoolean("notify_trash", checked).apply(); + } + }); + + cbNotifyActionArchive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean checked) { + prefs.edit().putBoolean("notify_archive", checked).apply(); + } + }); + + cbNotifyActionReply.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean checked) { + prefs.edit().putBoolean("notify_reply", checked).apply(); + } + }); + + cbNotifyActionSeen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean checked) { + prefs.edit().putBoolean("notify_seen", checked).apply(); + } + }); + + swLight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("light", checked).apply(); + } + }); + + btnSound.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String sound = prefs.getString("sound", null); + Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.title_advanced_sound)); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false); + intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, sound == null ? null : Uri.parse(sound)); + startActivityForResult(Helper.getChooser(getContext(), intent), ActivitySetup.REQUEST_SOUND); + } + }); + + return view; + } + + private void setOptions() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + + swNotifyPreview.setChecked(prefs.getBoolean("notify_preview", true)); + swNotifyPreview.setEnabled(Helper.isPro(getContext())); + cbNotifyActionTrash.setChecked(prefs.getBoolean("notify_trash", true)); + cbNotifyActionArchive.setChecked(prefs.getBoolean("notify_archive", true)); + cbNotifyActionReply.setChecked(prefs.getBoolean("notify_reply", false)); + cbNotifyActionSeen.setChecked(prefs.getBoolean("notify_seen", true)); + swLight.setChecked(prefs.getBoolean("light", false)); + + grpNotification.setVisibility(Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O ? View.VISIBLE : View.GONE); + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.i("Result class=" + this.getClass().getSimpleName() + + " request=" + requestCode + " result=" + resultCode + " data=" + data); + + if (requestCode == ActivitySetup.REQUEST_SOUND) + if (resultCode == RESULT_OK) { + Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); + Log.i("Selected ringtone=" + uri); + if (uri != null && "file".equals(uri.getScheme())) + uri = null; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + if (uri == null) + prefs.edit().remove("sound").apply(); + else + prefs.edit().putString("sound", uri.toString()).apply(); + } + } +} diff --git a/app/src/main/res/layout/fragment_options.xml b/app/src/main/res/layout/fragment_options.xml index 657d1a2c65..5fc391fa3c 100644 --- a/app/src/main/res/layout/fragment_options.xml +++ b/app/src/main/res/layout/fragment_options.xml @@ -6,72 +6,16 @@ android:layout_height="match_parent" tools:context=".ActivitySetup"> - - - - - - - - - - - - - - - - + android:layout_gravity="top" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_behavior.xml b/app/src/main/res/layout/fragment_options_behavior.xml new file mode 100644 index 0000000000..b9fd3bc113 --- /dev/null +++ b/app/src/main/res/layout/fragment_options_behavior.xml @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_connection.xml b/app/src/main/res/layout/fragment_options_connection.xml new file mode 100644 index 0000000000..8f8ddaa849 --- /dev/null +++ b/app/src/main/res/layout/fragment_options_connection.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_display.xml b/app/src/main/res/layout/fragment_options_display.xml new file mode 100644 index 0000000000..05c5284909 --- /dev/null +++ b/app/src/main/res/layout/fragment_options_display.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_general.xml b/app/src/main/res/layout/fragment_options_general.xml new file mode 100644 index 0000000000..8798fc9645 --- /dev/null +++ b/app/src/main/res/layout/fragment_options_general.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_misc.xml b/app/src/main/res/layout/fragment_options_misc.xml new file mode 100644 index 0000000000..d8d8c6fdba --- /dev/null +++ b/app/src/main/res/layout/fragment_options_misc.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_options_notifications.xml b/app/src/main/res/layout/fragment_options_notifications.xml new file mode 100644 index 0000000000..638ace0aeb --- /dev/null +++ b/app/src/main/res/layout/fragment_options_notifications.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +