1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-07 11:48:07 -05:00

Improve UI for switching on/off PGP signing and encryption

also do some cleanup in this area - PgpData has to die completely - but do not want to be to radical here
This commit is contained in:
ligi 2015-01-29 19:10:50 +01:00
parent 033c1502db
commit e68bc3b706
3 changed files with 285 additions and 387 deletions

View File

@ -34,6 +34,7 @@ import android.content.Intent;
import android.content.IntentSender.SendIntentException; import android.content.IntentSender.SendIntentException;
import android.content.Loader; import android.content.Loader;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.graphics.PorterDuff;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
@ -58,13 +59,14 @@ import android.webkit.WebViewClient;
import android.widget.AutoCompleteTextView.Validator; import android.widget.AutoCompleteTextView.Validator;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.MultiAutoCompleteTextView; import android.widget.MultiAutoCompleteTextView;
import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -250,6 +252,10 @@ public class MessageCompose extends K9Activity implements OnClickListener,
*/ */
private boolean mSourceMessageProcessed = false; private boolean mSourceMessageProcessed = false;
private int mMaxLoaderId = 0; private int mMaxLoaderId = 0;
private ImageView signIndicator;
private ImageView encryptIndicator;
private Switch signatureSwitch;
private Switch encryptSwitch;
enum Action { enum Action {
COMPOSE, COMPOSE,
@ -301,10 +307,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
private EolConvertingEditText mQuotedText; private EolConvertingEditText mQuotedText;
private MessageWebView mQuotedHTML; private MessageWebView mQuotedHTML;
private InsertableHtmlContent mQuotedHtmlContent; // Container for HTML reply as it's being built. private InsertableHtmlContent mQuotedHtmlContent; // Container for HTML reply as it's being built.
private CheckBox mCryptoSignatureCheckbox;
private CheckBox mEncryptCheckbox;
private TextView mCryptoSignatureUserId;
private TextView mCryptoSignatureUserIdRest;
private PgpData mPgpData = null; private PgpData mPgpData = null;
private String mOpenPgpProvider; private String mOpenPgpProvider;
@ -454,7 +456,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
* Compose a new message as a reply to the given message. If replyAll is true the function * Compose a new message as a reply to the given message. If replyAll is true the function
* is reply all instead of simply reply. * is reply all instead of simply reply.
* @param context * @param context
* @param account
* @param message * @param message
* @param replyAll * @param replyAll
* @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message
@ -765,23 +766,36 @@ public class MessageCompose extends K9Activity implements OnClickListener,
mOpenPgpProvider = mAccount.getOpenPgpProvider(); mOpenPgpProvider = mAccount.getOpenPgpProvider();
if (mOpenPgpProvider != null) { if (mOpenPgpProvider != null) {
mCryptoSignatureCheckbox = (CheckBox)findViewById(R.id.cb_crypto_signature);
signatureSwitch = (Switch) findViewById(R.id.signature_switch);
signIndicator = (ImageView) findViewById(R.id.signature_indicator);
encryptSwitch = (Switch) findViewById(R.id.encrypt_switch);
encryptIndicator = (ImageView) findViewById(R.id.encrypt_indicator);
refreshPgpSwitchUIs();
final OnCheckedChangeListener refreshSwitchListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
refreshPgpSwitchUIs();
updateMessageFormat();
}
};
signatureSwitch.setOnCheckedChangeListener(refreshSwitchListener);
encryptSwitch.setOnCheckedChangeListener(refreshSwitchListener);
final OnCheckedChangeListener updateListener = new OnCheckedChangeListener() { final OnCheckedChangeListener updateListener = new OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
updateMessageFormat(); updateMessageFormat();
} }
}; };
mCryptoSignatureCheckbox.setOnCheckedChangeListener(updateListener);
mCryptoSignatureUserId = (TextView)findViewById(R.id.userId);
mCryptoSignatureUserIdRest = (TextView)findViewById(R.id.userIdRest);
mEncryptCheckbox = (CheckBox)findViewById(R.id.cb_encrypt);
mEncryptCheckbox.setOnCheckedChangeListener(updateListener);
if (mSourceMessageBody != null) { if (mSourceMessageBody != null) {
// mSourceMessageBody is set to something when replying to and forwarding decrypted // mSourceMessageBody is set to something when replying to and forwarding decrypted
// messages, so the sender probably wants the message to be encrypted. // messages, so the sender probably wants the message to be encrypted.
mEncryptCheckbox.setChecked(true); encryptSwitch.setChecked(true);
} }
// New OpenPGP Provider API // New OpenPGP Provider API
@ -791,15 +805,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
mOpenPgpServiceConnection.bindToService(); mOpenPgpServiceConnection.bindToService();
mEncryptLayout.setVisibility(View.VISIBLE); mEncryptLayout.setVisibility(View.VISIBLE);
mCryptoSignatureCheckbox.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CheckBox checkBox = (CheckBox) v;
if (checkBox.isChecked()) {
mPreventDraftSaving = true;
}
}
});
updateMessageFormat(); updateMessageFormat();
} else { } else {
@ -816,12 +821,26 @@ public class MessageCompose extends K9Activity implements OnClickListener,
mFontSizes.setViewTextSize(mQuotedText, fontSize); mFontSizes.setViewTextSize(mQuotedText, fontSize);
mFontSizes.setViewTextSize(mSignatureView, fontSize); mFontSizes.setViewTextSize(mSignatureView, fontSize);
updateMessageFormat(); updateMessageFormat();
setTitle(); setTitle();
} }
private void refreshPgpSwitchUIs() {
final int encryptColor = signatureSwitch.isChecked()? R.color.openpgp_green:R.color.openpgp_orange;
signIndicator.setColorFilter(getResources().getColor(encryptColor),PorterDuff.Mode.SRC_IN);
final int signColor = encryptSwitch.isChecked()? R.color.openpgp_green:R.color.openpgp_orange;
encryptIndicator.setColorFilter(getResources().getColor(signColor), PorterDuff.Mode.SRC_IN);
final int res = encryptSwitch.isChecked() ? R.drawable.status_lock_closed : R.drawable.status_lock_open;
encryptIndicator.setImageResource(res);
if (encryptSwitch.isChecked()) {
mPreventDraftSaving = false;
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
@ -893,7 +912,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
String type = intent.getType(); String type = intent.getType();
if (Intent.ACTION_SEND.equals(action)) { if (Intent.ACTION_SEND.equals(action)) {
Uri stream = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri stream = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (stream != null) { if (stream != null) {
addAttachment(stream, type); addAttachment(stream, type);
} }
@ -975,36 +994,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
mPgpData = new PgpData(); mPgpData = new PgpData();
} }
/**
* Fill the encrypt layout with the latest data about signature key and encryption keys.
*/
public void updateEncryptLayout() {
if (!mPgpData.hasSignatureKey()) {
mCryptoSignatureCheckbox.setText(R.string.btn_crypto_sign);
mCryptoSignatureCheckbox.setChecked(false);
mCryptoSignatureUserId.setVisibility(View.INVISIBLE);
mCryptoSignatureUserIdRest.setVisibility(View.INVISIBLE);
} else {
// if a signature key is selected, then the checkbox itself has no text
mCryptoSignatureCheckbox.setText("");
mCryptoSignatureCheckbox.setChecked(true);
mCryptoSignatureUserId.setVisibility(View.VISIBLE);
mCryptoSignatureUserIdRest.setVisibility(View.VISIBLE);
mCryptoSignatureUserId.setText(R.string.unknown_crypto_signature_user_id);
mCryptoSignatureUserIdRest.setText("");
String userId = mPgpData.getSignatureUserId();
if (userId != null) {
String chunks[] = mPgpData.getSignatureUserId().split(" <", 2);
mCryptoSignatureUserId.setText(chunks[0]);
if (chunks.length > 1) {
mCryptoSignatureUserIdRest.setText("<" + chunks[1]);
}
}
}
updateMessageFormat();
}
@Override @Override
public void onResume() { public void onResume() {
@ -1127,8 +1116,6 @@ public class MessageCompose extends K9Activity implements OnClickListener,
initializeCrypto(); initializeCrypto();
updateFrom(); updateFrom();
updateSignature(); updateSignature();
updateEncryptLayout();
updateMessageFormat(); updateMessageFormat();
} }
@ -1634,7 +1621,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
private void saveIfNeeded() { private void saveIfNeeded() {
if (!mDraftNeedsSaving || mPreventDraftSaving || mPgpData.hasEncryptionKeys() || if (!mDraftNeedsSaving || mPreventDraftSaving || mPgpData.hasEncryptionKeys() ||
mEncryptCheckbox.isChecked() || !mAccount.hasDraftsFolder()) { encryptSwitch.isChecked() || !mAccount.hasDraftsFolder()) {
return; return;
} }
@ -1683,10 +1670,10 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// If not already encrypted but user wants to encrypt... // If not already encrypted but user wants to encrypt...
if (mPgpData.getEncryptedData() == null && if (mPgpData.getEncryptedData() == null &&
(mEncryptCheckbox.isChecked() || mCryptoSignatureCheckbox.isChecked())) { (encryptSwitch.isChecked() || signatureSwitch.isChecked())) {
String[] emailsArray = null; String[] emailsArray = null;
if (mEncryptCheckbox.isChecked()) { if (encryptSwitch.isChecked()) {
// get emails as array // get emails as array
List<String> emails = new ArrayList<String>(); List<String> emails = new ArrayList<String>();
@ -1695,14 +1682,14 @@ public class MessageCompose extends K9Activity implements OnClickListener,
} }
emailsArray = emails.toArray(new String[emails.size()]); emailsArray = emails.toArray(new String[emails.size()]);
} }
if (mEncryptCheckbox.isChecked() && mCryptoSignatureCheckbox.isChecked()) { if (encryptSwitch.isChecked() && signatureSwitch.isChecked()) {
Intent intent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT); Intent intent = new Intent(OpenPgpApi.ACTION_SIGN_AND_ENCRYPT);
intent.putExtra(OpenPgpApi.EXTRA_USER_IDS, emailsArray); intent.putExtra(OpenPgpApi.EXTRA_USER_IDS, emailsArray);
executeOpenPgpMethod(intent); executeOpenPgpMethod(intent);
} else if (mCryptoSignatureCheckbox.isChecked()) { } else if (signatureSwitch.isChecked()) {
Intent intent = new Intent(OpenPgpApi.ACTION_SIGN); Intent intent = new Intent(OpenPgpApi.ACTION_SIGN);
executeOpenPgpMethod(intent); executeOpenPgpMethod(intent);
} else if (mEncryptCheckbox.isChecked()) { } else if (encryptSwitch.isChecked()) {
Intent intent = new Intent(OpenPgpApi.ACTION_ENCRYPT); Intent intent = new Intent(OpenPgpApi.ACTION_ENCRYPT);
intent.putExtra(OpenPgpApi.EXTRA_USER_IDS, emailsArray); intent.putExtra(OpenPgpApi.EXTRA_USER_IDS, emailsArray);
executeOpenPgpMethod(intent); executeOpenPgpMethod(intent);
@ -2350,7 +2337,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
onSend(); onSend();
break; break;
case R.id.save: case R.id.save:
if (mEncryptCheckbox.isChecked()) { if (encryptSwitch.isChecked()) {
showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED);
} else { } else {
onSave(); onSave();
@ -2400,7 +2387,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
@Override @Override
public void onBackPressed() { public void onBackPressed() {
if (mDraftNeedsSaving) { if (mDraftNeedsSaving) {
if (mEncryptCheckbox.isChecked()) { if (encryptSwitch.isChecked()) {
showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED); showDialog(DIALOG_REFUSE_TO_SAVE_DRAFT_MARKED_ENCRYPTED);
} else if (!mAccount.hasDraftsFolder()) { } else if (!mAccount.hasDraftsFolder()) {
showDialog(DIALOG_CONFIRM_DISCARD_ON_BACK); showDialog(DIALOG_CONFIRM_DISCARD_ON_BACK);
@ -3847,7 +3834,7 @@ public class MessageCompose extends K9Activity implements OnClickListener,
// Right now we send a text/plain-only message when the quoted text was edited, no // Right now we send a text/plain-only message when the quoted text was edited, no
// matter what the user selected for the message format. // matter what the user selected for the message format.
messageFormat = SimpleMessageFormat.TEXT; messageFormat = SimpleMessageFormat.TEXT;
} else if (mEncryptCheckbox.isChecked() || mCryptoSignatureCheckbox.isChecked()) { } else if (encryptSwitch.isChecked() || signatureSwitch.isChecked()) {
// Right now we only support PGP inline which doesn't play well with HTML. So force // Right now we only support PGP inline which doesn't play well with HTML. So force
// plain text in those cases. // plain text in those cases.
messageFormat = SimpleMessageFormat.TEXT; messageFormat = SimpleMessageFormat.TEXT;

View File

@ -9,42 +9,14 @@ public class PgpData implements Serializable {
protected long mEncryptionKeyIds[] = null; protected long mEncryptionKeyIds[] = null;
protected long mSignatureKeyId = 0; protected long mSignatureKeyId = 0;
protected String mSignatureUserId = null; protected String mSignatureUserId = null;
protected boolean mSignatureSuccess = false;
protected boolean mSignatureUnknown = false;
protected String mDecryptedData = null; protected String mDecryptedData = null;
protected String mEncryptedData = null; protected String mEncryptedData = null;
// new API // new API
protected OpenPgpSignatureResult mSignatureResult;
public OpenPgpSignatureResult getSignatureResult() {
return mSignatureResult;
}
public void setSignatureResult(OpenPgpSignatureResult signatureResult) {
this.mSignatureResult = signatureResult;
}
public void setSignatureKeyId(long keyId) {
mSignatureKeyId = keyId;
}
public long getSignatureKeyId() {
return mSignatureKeyId;
}
public void setEncryptionKeys(long keyIds[]) { public void setEncryptionKeys(long keyIds[]) {
mEncryptionKeyIds = keyIds; mEncryptionKeyIds = keyIds;
} }
public long[] getEncryptionKeys() {
return mEncryptionKeyIds;
}
public boolean hasSignatureKey() {
return mSignatureKeyId != 0;
}
public boolean hasEncryptionKeys() { public boolean hasEncryptionKeys() {
return (mEncryptionKeyIds != null) && (mEncryptionKeyIds.length > 0); return (mEncryptionKeyIds != null) && (mEncryptionKeyIds.length > 0);
} }
@ -60,32 +32,4 @@ public class PgpData implements Serializable {
public String getDecryptedData() { public String getDecryptedData() {
return mDecryptedData; return mDecryptedData;
} }
public void setDecryptedData(String data) {
mDecryptedData = data;
}
public void setSignatureUserId(String userId) {
mSignatureUserId = userId;
}
public String getSignatureUserId() {
return mSignatureUserId;
}
public boolean getSignatureSuccess() {
return mSignatureSuccess;
}
public void setSignatureSuccess(boolean success) {
mSignatureSuccess = success;
}
public boolean getSignatureUnknown() {
return mSignatureUnknown;
}
public void setSignatureUnknown(boolean unknown) {
mSignatureUnknown = unknown;
}
} }

View File

@ -1,314 +1,281 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"> android:fillViewport="true"
android:scrollbarStyle="insideOverlay">
<ScrollView <LinearLayout
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="0dip" android:layout_height="wrap_content"
android:layout_weight="1" android:orientation="vertical">
android:scrollbarStyle="insideOverlay"
android:fillViewport="true">
<LinearLayout <LinearLayout
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" > android:layout_marginBottom="4dp"
android:background="#45bcbcbc"
android:orientation="vertical"
android:paddingTop="6dp">
<LinearLayout <Button
android:id="@+id/identity"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="4dp" android:layout_marginLeft="6dip"
android:paddingTop="6dp" android:layout_marginRight="6dip"
android:orientation="vertical" android:gravity="center_vertical" />
android:background="#45bcbcbc">
<Button <LinearLayout
android:id="@+id/identity" android:id="@+id/to_wrapper"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:layout_marginLeft="6dip"
android:layout_marginLeft="6dip" android:layout_marginRight="6dip"
android:layout_marginRight="6dip"/> android:baselineAligned="true"
android:gravity="bottom">
<LinearLayout <MultiAutoCompleteTextView
android:id="@+id/to_wrapper" android:id="@+id/to"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="bottom"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip" android:layout_marginRight="6dip"
android:layout_width="fill_parent"> android:layout_weight="1"
android:hint="@string/message_compose_to_hint"
<MultiAutoCompleteTextView
android:id="@+id/to"
android:layout_height="wrap_content"
android:inputType="textEmailAddress|textMultiLine"
android:imeOptions="actionNext"
android:hint="@string/message_compose_to_hint"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dp"
android:layout_marginRight="6dip"
android:layout_weight="1"/>
<ImageButton
android:id="@+id/add_to"
android:contentDescription="@string/message_compose_description_add_to"
android:src="?attr/messageComposeAddContactImage"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="8dip"
android:layout_marginTop="1dip"/>
</LinearLayout>
<LinearLayout
android:id="@+id/cc_wrapper"
android:visibility="gone"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="bottom"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:layout_width="fill_parent">
<MultiAutoCompleteTextView
android:id="@+id/cc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginRight="6dip"
android:inputType="textEmailAddress|textMultiLine"
android:imeOptions="actionNext"
android:hint="@string/message_compose_cc_hint"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<ImageButton
android:id="@+id/add_cc"
android:contentDescription="@string/message_compose_description_add_cc"
android:src="?attr/messageComposeAddContactImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dip"
android:layout_marginTop="1dip"/>
</LinearLayout>
<LinearLayout
android:id="@+id/bcc_wrapper"
android:visibility="gone"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:gravity="bottom"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:layout_width="fill_parent">
<MultiAutoCompleteTextView
android:id="@+id/bcc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:layout_weight="1"
android:inputType="textEmailAddress|textMultiLine"
android:imeOptions="actionNext"
android:hint="@string/message_compose_bcc_hint"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<ImageButton
android:id="@+id/add_bcc"
android:contentDescription="@string/message_compose_description_add_bcc"
android:layout_marginTop="1dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="8dip"
android:src="?attr/messageComposeAddContactImage"/>
</LinearLayout>
<LinearLayout
android:id="@+id/layout_encrypt"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:paddingLeft="6dip"
android:paddingRight="6dip">
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<CheckBox
android:text="@string/btn_crypto_sign"
android:id="@+id/cb_crypto_signature"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingRight="2dip">
<TextView
android:id="@+id/userId"
android:ellipsize="end"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/userIdRest"
android:textSize="10sp"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
<CheckBox
android:text="@string/btn_encrypt"
android:id="@+id/cb_encrypt"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
<EditText
android:id="@+id/subject"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:hint="@string/message_compose_subject_hint"
android:inputType="textEmailSubject|textAutoCorrect|textCapSentences|textImeMultiLine"
android:imeOptions="actionNext" android:imeOptions="actionNext"
android:singleLine="true" android:inputType="textEmailAddress|textMultiLine"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<!-- <ImageButton
Empty container for storing attachments. We'll stick android:id="@+id/add_to"
instances of message_compose_attachment.xml in here. android:layout_width="wrap_content"
-->
<LinearLayout
android:id="@+id/attachments"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" /> android:layout_marginTop="1dip"
android:contentDescription="@string/message_compose_description_add_to"
<View android:padding="8dip"
android:layout_width="fill_parent" android:src="?attr/messageComposeAddContactImage" />
android:layout_height="1dip"
android:background="@drawable/divider_horizontal_email" />
</LinearLayout> </LinearLayout>
<!-- We have to use "wrap_content" (not "0dip") for "layout_height", otherwise the <LinearLayout
EditText won't properly grow in height while the user is typing the message --> android:id="@+id/cc_wrapper"
<view
class="com.fsck.k9.ui.EolConvertingEditText"
android:id="@+id/message_content"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_marginLeft="6dip"
android:gravity="top" android:layout_marginRight="6dip"
android:hint="@string/message_compose_content_hint" android:baselineAligned="true"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences" android:gravity="bottom"
android:imeOptions="actionDone|flagNoEnterAction" android:visibility="gone">
android:minLines="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
<view <MultiAutoCompleteTextView
class="com.fsck.k9.ui.EolConvertingEditText" android:id="@+id/cc"
android:id="@+id/upper_signature" android:layout_width="0dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:minLines="0"
android:hint="@string/message_compose_signature_hint"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/quoted_text_show"
android:text="@string/message_compose_show_quoted_text_action"
android:textSize="16sp"
android:padding="0dip"
android:layout_gravity="right"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<!-- Quoted text bar -->
<RelativeLayout
android:id="@+id/quoted_text_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<view
class="com.fsck.k9.ui.EolConvertingEditText"
android:id="@+id/quoted_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:layout_marginRight="6dip"
android:minLines="3" android:layout_weight="1"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences" android:hint="@string/message_compose_cc_hint"
android:imeOptions="actionNext"
android:inputType="textEmailAddress|textMultiLine"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<com.fsck.k9.view.MessageWebView <ImageButton
android:id="@+id/quoted_html" android:id="@+id/add_cc"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<LinearLayout
android:id="@+id/quoted_text_buttons"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_marginTop="1dip"
android:layout_alignParentRight="true"> android:contentDescription="@string/message_compose_description_add_cc"
android:padding="8dip"
android:src="?attr/messageComposeAddContactImage" />
<ImageButton </LinearLayout>
android:id="@+id/quoted_text_edit"
android:contentDescription="@string/message_compose_description_edit_quoted_text" <LinearLayout
android:id="@+id/bcc_wrapper"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"
android:baselineAligned="true"
android:gravity="bottom"
android:visibility="gone">
<MultiAutoCompleteTextView
android:id="@+id/bcc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:layout_weight="1"
android:hint="@string/message_compose_bcc_hint"
android:imeOptions="actionNext"
android:inputType="textEmailAddress|textMultiLine"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageButton
android:id="@+id/add_bcc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dip"
android:contentDescription="@string/message_compose_description_add_bcc"
android:padding="8dip"
android:src="?attr/messageComposeAddContactImage" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_encrypt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="horizontal">
<Switch
android:id="@+id/signature_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/signature_indicator"
android:paddingRight="8dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="8dip" android:src="@drawable/status_signature_verified_cutout" />
android:background="@drawable/btn_edit" />
<ImageButton <Switch
android:id="@+id/quoted_text_delete" android:id="@+id/encrypt_switch"
android:contentDescription="@string/message_compose_description_delete_quoted_text" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/encrypt_indicator"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/btn_dialog" /> android:src="@drawable/status_lock_closed" />
</LinearLayout> </LinearLayout>
</RelativeLayout>
<view <EditText
class="com.fsck.k9.ui.EolConvertingEditText" android:id="@+id/subject"
android:id="@+id/lower_signature"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="top" android:layout_marginLeft="6dip"
android:minLines="0" android:layout_marginRight="6dip"
android:hint="@string/message_compose_signature_hint" android:hint="@string/message_compose_subject_hint"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences" android:imeOptions="actionNext"
android:inputType="textEmailSubject|textAutoCorrect|textCapSentences|textImeMultiLine"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<!--
Empty container for storing attachments. We'll stick
instances of message_compose_attachment.xml in here.
-->
<LinearLayout
android:id="@+id/attachments"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="@drawable/divider_horizontal_email" />
</LinearLayout> </LinearLayout>
</ScrollView> <!-- We have to use "wrap_content" (not "0dip") for "layout_height", otherwise the
EditText won't properly grow in height while the user is typing the message -->
<view
android:id="@+id/message_content"
class="com.fsck.k9.ui.EolConvertingEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top"
android:hint="@string/message_compose_content_hint"
android:imeOptions="actionDone|flagNoEnterAction"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:minLines="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout> <view
android:id="@+id/upper_signature"
class="com.fsck.k9.ui.EolConvertingEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/message_compose_signature_hint"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:minLines="0"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/quoted_text_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:padding="0dip"
android:text="@string/message_compose_show_quoted_text_action"
android:textSize="16sp" />
<!-- Quoted text bar -->
<RelativeLayout
android:id="@+id/quoted_text_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<view
android:id="@+id/quoted_text"
class="com.fsck.k9.ui.EolConvertingEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:minLines="3"
android:textAppearance="?android:attr/textAppearanceMedium" />
<com.fsck.k9.view.MessageWebView
android:id="@+id/quoted_html"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/quoted_text_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true">
<ImageButton
android:id="@+id/quoted_text_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dip"
android:background="@drawable/btn_edit"
android:contentDescription="@string/message_compose_description_edit_quoted_text" />
<ImageButton
android:id="@+id/quoted_text_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/btn_dialog"
android:contentDescription="@string/message_compose_description_delete_quoted_text" />
</LinearLayout>
</RelativeLayout>
<view
android:id="@+id/lower_signature"
class="com.fsck.k9.ui.EolConvertingEditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/message_compose_signature_hint"
android:inputType="textMultiLine|textAutoCorrect|textCapSentences"
android:minLines="0"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</ScrollView>