|
|
@ -79,6 +79,7 @@ import android.widget.EditText;
|
|
|
|
import android.widget.FilterQueryProvider;
|
|
|
|
import android.widget.FilterQueryProvider;
|
|
|
|
import android.widget.ImageButton;
|
|
|
|
import android.widget.ImageButton;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
|
|
|
|
import android.widget.ListView;
|
|
|
|
import android.widget.MultiAutoCompleteTextView;
|
|
|
|
import android.widget.MultiAutoCompleteTextView;
|
|
|
|
import android.widget.Spinner;
|
|
|
|
import android.widget.Spinner;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.TextView;
|
|
|
@ -86,6 +87,7 @@ import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
import androidx.annotation.Nullable;
|
|
|
|
|
|
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import androidx.constraintlayout.widget.Group;
|
|
|
|
import androidx.constraintlayout.widget.Group;
|
|
|
|
import androidx.cursoradapter.widget.SimpleCursorAdapter;
|
|
|
|
import androidx.cursoradapter.widget.SimpleCursorAdapter;
|
|
|
|
import androidx.exifinterface.media.ExifInterface;
|
|
|
|
import androidx.exifinterface.media.ExifInterface;
|
|
|
@ -752,6 +754,7 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
menu.findItem(R.id.menu_image).setVisible(state == State.LOADED && !style);
|
|
|
|
menu.findItem(R.id.menu_image).setVisible(state == State.LOADED && !style);
|
|
|
|
menu.findItem(R.id.menu_attachment).setVisible(state == State.LOADED && !style);
|
|
|
|
menu.findItem(R.id.menu_attachment).setVisible(state == State.LOADED && !style);
|
|
|
|
menu.findItem(R.id.menu_clear).setVisible(state == State.LOADED);
|
|
|
|
menu.findItem(R.id.menu_clear).setVisible(state == State.LOADED);
|
|
|
|
|
|
|
|
menu.findItem(R.id.menu_contact_group).setVisible(state == State.LOADED);
|
|
|
|
menu.findItem(R.id.menu_encrypt).setVisible(state == State.LOADED);
|
|
|
|
menu.findItem(R.id.menu_encrypt).setVisible(state == State.LOADED);
|
|
|
|
menu.findItem(R.id.menu_send_after).setVisible(state == State.LOADED);
|
|
|
|
menu.findItem(R.id.menu_send_after).setVisible(state == State.LOADED);
|
|
|
|
|
|
|
|
|
|
|
@ -759,6 +762,7 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
menu.findItem(R.id.menu_image).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_image).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_attachment).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_attachment).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_clear).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_clear).setEnabled(!busy);
|
|
|
|
|
|
|
|
menu.findItem(R.id.menu_contact_group).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_encrypt).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_encrypt).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_send_after).setEnabled(!busy);
|
|
|
|
menu.findItem(R.id.menu_send_after).setEnabled(!busy);
|
|
|
|
|
|
|
|
|
|
|
@ -794,6 +798,9 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
case R.id.menu_clear:
|
|
|
|
case R.id.menu_clear:
|
|
|
|
onMenuStyle(item.getItemId());
|
|
|
|
onMenuStyle(item.getItemId());
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case R.id.menu_contact_group:
|
|
|
|
|
|
|
|
onMenuContactGroup();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
case R.id.menu_encrypt:
|
|
|
|
case R.id.menu_encrypt:
|
|
|
|
onMenuEncrypt();
|
|
|
|
onMenuEncrypt();
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
@ -943,6 +950,148 @@ public class FragmentCompose extends FragmentBase {
|
|
|
|
etBody.setSelection(end);
|
|
|
|
etBody.setSelection(end);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void onMenuContactGroup() {
|
|
|
|
|
|
|
|
View dview = LayoutInflater.from(getContext()).inflate(R.layout.dialog_contact_group, null);
|
|
|
|
|
|
|
|
final ListView lvGroup = dview.findViewById(R.id.lvGroup);
|
|
|
|
|
|
|
|
final Spinner spTarget = dview.findViewById(R.id.spTarget);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Cursor groups = resolver.query(
|
|
|
|
|
|
|
|
ContactsContract.Groups.CONTENT_URI,
|
|
|
|
|
|
|
|
new String[]{
|
|
|
|
|
|
|
|
ContactsContract.Groups._ID,
|
|
|
|
|
|
|
|
ContactsContract.Groups.TITLE
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
null, null, ContactsContract.Groups.TITLE
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(
|
|
|
|
|
|
|
|
getContext(),
|
|
|
|
|
|
|
|
R.layout.spinner_item1_dropdown,
|
|
|
|
|
|
|
|
groups,
|
|
|
|
|
|
|
|
new String[]{ContactsContract.Groups.TITLE},
|
|
|
|
|
|
|
|
new int[]{android.R.id.text1},
|
|
|
|
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lvGroup.setAdapter(adapter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final AlertDialog dialog = new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
|
|
|
|
|
|
|
|
.setTitle(R.string.title_insert_contact_group)
|
|
|
|
|
|
|
|
.setView(dview)
|
|
|
|
|
|
|
|
.create();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lvGroup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
|
|
|
|
|
dialog.dismiss();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int target = spTarget.getSelectedItemPosition();
|
|
|
|
|
|
|
|
Cursor cursor = (Cursor) adapter.getItem(position);
|
|
|
|
|
|
|
|
long group = cursor.getLong(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (target > 0)
|
|
|
|
|
|
|
|
grpAddresses.setVisibility(View.VISIBLE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bundle args = new Bundle();
|
|
|
|
|
|
|
|
args.putLong("id", working);
|
|
|
|
|
|
|
|
args.putInt("target", target);
|
|
|
|
|
|
|
|
args.putLong("group", group);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new SimpleTask<EntityMessage>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
protected EntityMessage onExecute(Context context, Bundle args) throws Throwable {
|
|
|
|
|
|
|
|
long id = args.getLong("id");
|
|
|
|
|
|
|
|
int target = args.getInt("target");
|
|
|
|
|
|
|
|
long group = args.getLong("group");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Address> selected = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try (Cursor cursor = context.getContentResolver().query(
|
|
|
|
|
|
|
|
ContactsContract.Data.CONTENT_URI,
|
|
|
|
|
|
|
|
new String[]{ContactsContract.Data.CONTACT_ID},
|
|
|
|
|
|
|
|
ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID + "= ?" + " AND "
|
|
|
|
|
|
|
|
+ ContactsContract.CommonDataKinds.GroupMembership.MIMETYPE + "='"
|
|
|
|
|
|
|
|
+ ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE + "'",
|
|
|
|
|
|
|
|
new String[]{String.valueOf(group)}, null)) {
|
|
|
|
|
|
|
|
while (cursor != null && cursor.moveToNext()) {
|
|
|
|
|
|
|
|
try (Cursor contact = resolver.query(
|
|
|
|
|
|
|
|
ContactsContract.CommonDataKinds.Email.CONTENT_URI,
|
|
|
|
|
|
|
|
new String[]{
|
|
|
|
|
|
|
|
ContactsContract.Contacts.DISPLAY_NAME,
|
|
|
|
|
|
|
|
ContactsContract.CommonDataKinds.Email.DATA
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
ContactsContract.Data.CONTACT_ID + " = ?",
|
|
|
|
|
|
|
|
new String[]{cursor.getString(0)},
|
|
|
|
|
|
|
|
null)) {
|
|
|
|
|
|
|
|
if (contact != null && contact.moveToNext()) {
|
|
|
|
|
|
|
|
String name = contact.getString(0);
|
|
|
|
|
|
|
|
String email = contact.getString(1);
|
|
|
|
|
|
|
|
selected.add(new InternetAddress(email, name));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EntityMessage draft;
|
|
|
|
|
|
|
|
DB db = DB.getInstance(context);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
db.beginTransaction();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draft = db.message().getMessage(id);
|
|
|
|
|
|
|
|
if (draft == null)
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Address[] address = null;
|
|
|
|
|
|
|
|
if (target == 0)
|
|
|
|
|
|
|
|
address = draft.to;
|
|
|
|
|
|
|
|
else if (target == 1)
|
|
|
|
|
|
|
|
address = draft.cc;
|
|
|
|
|
|
|
|
else if (target == 2)
|
|
|
|
|
|
|
|
address = draft.bcc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<Address> list = new ArrayList<>();
|
|
|
|
|
|
|
|
if (address != null)
|
|
|
|
|
|
|
|
list.addAll(Arrays.asList(address));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
list.addAll(selected);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (target == 0)
|
|
|
|
|
|
|
|
draft.to = list.toArray(new Address[0]);
|
|
|
|
|
|
|
|
else if (target == 1)
|
|
|
|
|
|
|
|
draft.cc = list.toArray(new Address[0]);
|
|
|
|
|
|
|
|
else if (target == 2)
|
|
|
|
|
|
|
|
draft.bcc = list.toArray(new Address[0]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db.message().updateMessage(draft);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db.setTransactionSuccessful();
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
db.endTransaction();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return draft;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
protected void onExecuted(Bundle args, EntityMessage draft) {
|
|
|
|
|
|
|
|
if (draft != null) {
|
|
|
|
|
|
|
|
etTo.setText(MessageHelper.formatAddressesCompose(draft.to));
|
|
|
|
|
|
|
|
etCc.setText(MessageHelper.formatAddressesCompose(draft.cc));
|
|
|
|
|
|
|
|
etBcc.setText(MessageHelper.formatAddressesCompose(draft.bcc));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
protected void onException(Bundle args, Throwable ex) {
|
|
|
|
|
|
|
|
Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}.execute(getContext(), getViewLifecycleOwner(), args, "compose:picked");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dialog.show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void onMenuEncrypt() {
|
|
|
|
private void onMenuEncrypt() {
|
|
|
|
encrypt = !encrypt;
|
|
|
|
encrypt = !encrypt;
|
|
|
|
getActivity().invalidateOptionsMenu();
|
|
|
|
getActivity().invalidateOptionsMenu();
|
|
|
|