diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 8373bc8c73..64cbec3981 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -35,7 +35,8 @@ import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; -import android.database.CursorWrapper; +import android.database.MatrixCursor; +import android.database.MergeCursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; @@ -453,24 +454,19 @@ public class FragmentCompose extends FragmentBase { Helper.setViewsEnabled(view, false); final DB db = DB.getInstance(getContext()); - final boolean contacts = Helper.hasPermission(getContext(), Manifest.permission.READ_CONTACTS); SimpleCursorAdapter cadapter = new SimpleCursorAdapter( getContext(), R.layout.spinner_item2_dropdown, null, - contacts - ? new String[]{ - ContactsContract.Contacts.DISPLAY_NAME, - ContactsContract.CommonDataKinds.Email.DATA} - : new String[]{"name", "email"}, + new String[]{"name", "email"}, new int[]{android.R.id.text1, android.R.id.text2}, 0); cadapter.setCursorToStringConverter(new SimpleCursorAdapter.CursorToStringConverter() { public CharSequence convertToString(Cursor cursor) { - int colName = cursor.getColumnIndex(contacts ? ContactsContract.Contacts.DISPLAY_NAME : "name"); - int colEmail = cursor.getColumnIndex(contacts ? ContactsContract.CommonDataKinds.Email.DATA : "email"); + int colName = cursor.getColumnIndex("name"); + int colEmail = cursor.getColumnIndex("email"); String name = cursor.getString(colName); String email = cursor.getString(colEmail); StringBuilder sb = new StringBuilder(); @@ -484,20 +480,19 @@ public class FragmentCompose extends FragmentBase { } }); - etTo.setAdapter(cadapter); - etCc.setAdapter(cadapter); - etBcc.setAdapter(cadapter); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + boolean suggest_local = prefs.getBoolean("suggest_local", false); - etTo.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); - etCc.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); - etBcc.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); + cadapter.setFilterQueryProvider(new FilterQueryProvider() { + public Cursor runQuery(CharSequence typed) { + Log.i("Searching provided contact=" + typed); - if (contacts) - cadapter.setFilterQueryProvider(new FilterQueryProvider() { - public Cursor runQuery(CharSequence typed) { - Log.i("Searching provided contact=" + typed); - String wildcard = "%" + typed + "%"; - return new CursorWrapper(resolver.query( + String wildcard = "%" + typed + "%"; + boolean contacts = Helper.hasPermission(getContext(), Manifest.permission.READ_CONTACTS); + MatrixCursor provided = new MatrixCursor(new String[]{"_id", "name", "email"}); + + if (contacts) { + Cursor cursor = resolver.query( ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ ContactsContract.CommonDataKinds.Email.CONTACT_ID, @@ -510,47 +505,29 @@ public class FragmentCompose extends FragmentBase { new String[]{wildcard, wildcard}, "CASE WHEN " + ContactsContract.Contacts.DISPLAY_NAME + " NOT LIKE '%@%' THEN 0 ELSE 1 END" + ", " + ContactsContract.Contacts.DISPLAY_NAME + " COLLATE NOCASE" + - ", " + ContactsContract.CommonDataKinds.Email.DATA + " COLLATE NOCASE")) { + ", " + ContactsContract.CommonDataKinds.Email.DATA + " COLLATE NOCASE"); + while (cursor != null && cursor.moveToNext()) + provided.newRow() + .add(cursor.getLong(0)) + .add(cursor.getString(1)) + .add(cursor.getString(2)); - @Override - public String[] getColumnNames() { - String[] names = super.getColumnNames(); - names[0] = "_id"; - return names; - } - - @Override - public String getColumnName(int index) { - if (index == 0) - return "_id"; - return super.getColumnName(index); - } - - @Override - public int getColumnIndex(String name) { - if ("_id".equals(name)) - return 0; - return super.getColumnIndex(name); - } - - @Override - public int getColumnIndexOrThrow(String name) throws IllegalArgumentException { - if ("_id".equals(name)) - return 0; - return super.getColumnIndexOrThrow(name); - } - }; + if (!suggest_local) + return provided; } - }); - else - cadapter.setFilterQueryProvider(new FilterQueryProvider() { - @Override - public Cursor runQuery(CharSequence typed) { - Log.i("Searching local contact=" + typed); - String wildcard = "%" + typed + "%"; - return db.contact().searchContacts(null, null, wildcard); - } - }); + + Cursor local = db.contact().searchContacts(null, null, wildcard); + return new MergeCursor(new Cursor[]{provided, local}); + } + }); + + etTo.setAdapter(cadapter); + etCc.setAdapter(cadapter); + etBcc.setAdapter(cadapter); + + etTo.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); + etCc.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); + etBcc.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer()); rvAttachment.setHasFixedSize(false); LinearLayoutManager llm = new LinearLayoutManager(getContext()); diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java b/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java index f689152a18..d19766ed05 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsSend.java @@ -40,6 +40,7 @@ import androidx.preference.PreferenceManager; public class FragmentOptionsSend extends FragmentBase implements SharedPreferences.OnSharedPreferenceChangeListener { private SwitchCompat swKeyboard; + private SwitchCompat swSuggestLocal; private SwitchCompat swPrefixOnce; private SwitchCompat swPlainOnly; private SwitchCompat swUsenetSignature; @@ -51,7 +52,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc private Spinner spSendDelayed; private final static String[] RESET_OPTIONS = new String[]{ - "keyboard", "prefix_once", "plain_only", "usenet_signature", "autoresize", "resize", "lookup_mx", "autosend", "send_delayed" + "keyboard", "suggest_local", "prefix_once", "plain_only", "usenet_signature", "autoresize", "resize", "lookup_mx", "autosend", "send_delayed" }; @Override @@ -65,6 +66,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc // Get controls swKeyboard = view.findViewById(R.id.swKeyboard); + swSuggestLocal = view.findViewById(R.id.swSuggestLocal); swPrefixOnce = view.findViewById(R.id.swPrefixOnce); swPlainOnly = view.findViewById(R.id.swPlainOnly); swUsenetSignature = view.findViewById(R.id.swUsenetSignature); @@ -88,6 +90,13 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc } }); + swSuggestLocal.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("suggest_local", checked).apply(); + } + }); + swPrefixOnce.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { @@ -204,6 +213,7 @@ public class FragmentOptionsSend extends FragmentBase implements SharedPreferenc SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); swKeyboard.setChecked(prefs.getBoolean("keyboard", true)); + swSuggestLocal.setChecked(prefs.getBoolean("suggest_local", false)); swPrefixOnce.setChecked(prefs.getBoolean("prefix_once", true)); swPlainOnly.setChecked(prefs.getBoolean("plain_only", false)); swUsenetSignature.setChecked(prefs.getBoolean("usenet_signature", false)); diff --git a/app/src/main/res/layout/fragment_options_send.xml b/app/src/main/res/layout/fragment_options_send.xml index b941931560..0420d46d78 100644 --- a/app/src/main/res/layout/fragment_options_send.xml +++ b/app/src/main/res/layout/fragment_options_send.xml @@ -31,6 +31,29 @@ app:layout_constraintTop_toTopOf="parent" app:switchPadding="12dp" /> + + + + Delete old unread messages Check if old messages were removed from the server Synchronize folder list + Manage folder subscriptions + Synchronize subscribed folders only Show keyboard by default + Suggest locally stored contacts Prefix subject only once on replying or forwarding Send plain text only by default Usenet signature convention @@ -303,12 +306,11 @@ Some providers don\'t support this properly, which, for example, may result in all messages being synchronized This will transfer extra data and consume extra battery power, especially if a lot of messages are stored on the device Disabling this will reduce data and battery usage somewhat, but will disable updating the list of folders too - Manage folder subscriptions - Synchronize subscribed folders only - - This will check if DNS MX records exist This will slow down synchronizing messages + In addition to contacts provided by Android + This will check if DNS MX records exist + Metered connections are generally mobile connections or paid Wi-Fi hotspots Disabling this option will disable receiving and sending messages on mobile internet connections Assuming no roaming within the EU