diff --git a/res/drawable-hdpi/message_header_bg.png b/res/drawable-hdpi/message_header_bg.png
new file mode 100644
index 000000000..9306813e3
Binary files /dev/null and b/res/drawable-hdpi/message_header_bg.png differ
diff --git a/res/drawable-hdpi/presence_inactive.png b/res/drawable-hdpi/presence_inactive.png
deleted file mode 100644
index d96d351da..000000000
Binary files a/res/drawable-hdpi/presence_inactive.png and /dev/null differ
diff --git a/res/drawable-mdpi/message_header_bg.png b/res/drawable-mdpi/message_header_bg.png
new file mode 100644
index 000000000..9a161844e
Binary files /dev/null and b/res/drawable-mdpi/message_header_bg.png differ
diff --git a/res/drawable-mdpi/presence_inactive.png b/res/drawable-mdpi/presence_inactive.png
deleted file mode 100755
index 4b07247cd..000000000
Binary files a/res/drawable-mdpi/presence_inactive.png and /dev/null differ
diff --git a/res/layout-xlarge/message_view_attachment.xml b/res/layout-xlarge/message_view_attachment.xml
new file mode 100644
index 000000000..e47b350d2
--- /dev/null
+++ b/res/layout-xlarge/message_view_attachment.xml
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout-xlarge/message_view_fragment.xml b/res/layout-xlarge/message_view_fragment.xml
index 7935fc525..d49245556 100644
--- a/res/layout-xlarge/message_view_fragment.xml
+++ b/res/layout-xlarge/message_view_fragment.xml
@@ -43,72 +43,71 @@
-
-
-
-
-
-
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="40dip"
+ android:layout_below="@id/header_background"
+ android:layout_alignLeft="@id/badge"
+ android:layout_toLeftOf="@id/datetime"
+ android:layout_marginRight="16dip"
+ android:gravity="center_vertical"
+ android:textSize="14dip"
+ android:textColor="@color/text_ternary_color"
+ android:singleLine="true"
+ android:ellipsize="end"
+ />
@@ -291,60 +264,87 @@
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
-
@@ -385,8 +385,9 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="4dip"
- android:background="#ffffff"
+ android:background="@color/message_view_info_back_color"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="beginning|middle|end"
/>
diff --git a/res/layout-xlarge/message_view_invitation.xml b/res/layout-xlarge/message_view_invitation.xml
new file mode 100644
index 000000000..4ff3112b0
--- /dev/null
+++ b/res/layout-xlarge/message_view_invitation.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/message_view_attachment.xml b/res/layout/message_view_attachment.xml
index 515f2a511..71acc39be 100644
--- a/res/layout/message_view_attachment.xml
+++ b/res/layout/message_view_attachment.xml
@@ -4,9 +4,9 @@
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
-
+
http://www.apache.org/licenses/LICENSE-2.0
-
+
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,6 +14,8 @@
limitations under the License.
-->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/message_view_fragment.xml b/res/layout/message_view_fragment.xml
index c769cf3c4..4785c550f 100644
--- a/res/layout/message_view_fragment.xml
+++ b/res/layout/message_view_fragment.xml
@@ -46,7 +46,7 @@
/>
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/res/layout/message_view_invitation.xml b/res/layout/message_view_invitation.xml
index f5b347ab1..b2df131cc 100644
--- a/res/layout/message_view_invitation.xml
+++ b/res/layout/message_view_invitation.xml
@@ -14,6 +14,8 @@
limitations under the License.
-->
+
+
-
-
-
#ffffff
#666666
+ #888888
#ff808080
@@ -57,4 +58,6 @@
#4d4d4d
#000000
#666666
+
+ #deecfa
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b76139600..c56d87969 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -111,6 +111,8 @@
+ Cc/Bcc
Add attachment
+
+ Close
Dump settings
@@ -300,6 +302,8 @@
Cc:
Bcc:
+
+ Date:
View
@@ -351,6 +355,10 @@ save attachment.
You have declined this invitation
+
+ Show details
+
+ Message Details
Viewing
diff --git a/src/com/android/email/Utility.java b/src/com/android/email/Utility.java
index d20fa89fc..20fda2655 100644
--- a/src/com/android/email/Utility.java
+++ b/src/com/android/email/Utility.java
@@ -33,11 +33,11 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
-import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.database.CursorWrapper;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@@ -47,7 +47,11 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.provider.OpenableColumns;
import android.telephony.TelephonyManager;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
+import android.text.style.StyleSpan;
import android.util.Base64;
import android.util.Log;
import android.widget.AbsListView;
@@ -1172,6 +1176,20 @@ public class Utility {
return name;
}
+ /**
+ * Append a bold span to a {@link SpannableStringBuilder}.
+ */
+ public static SpannableStringBuilder appendBold(SpannableStringBuilder ssb, String text) {
+ if (!TextUtils.isEmpty(text)) {
+ SpannableString ss = new SpannableString(text);
+ ss.setSpan(new StyleSpan(Typeface.BOLD), 0, ss.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append(ss);
+ }
+
+ return ssb;
+ }
+
/**
* Stringify a cursor for logging purpose.
*/
diff --git a/src/com/android/email/activity/ContactStatusLoader.java b/src/com/android/email/activity/ContactStatusLoader.java
index bef168f1e..d6e1d1ea5 100644
--- a/src/com/android/email/activity/ContactStatusLoader.java
+++ b/src/com/android/email/activity/ContactStatusLoader.java
@@ -16,7 +16,6 @@
package com.android.email.activity;
-import com.android.email.R;
import com.android.email.Utility;
import android.content.AsyncTaskLoader;
@@ -37,7 +36,7 @@ import android.util.Log;
* Loader to load presence statuses and the contact photoes.
*/
public class ContactStatusLoader extends AsyncTaskLoader {
- public static final int PRESENCE_UNKNOWN_RESOURCE_ID = R.drawable.presence_inactive;
+ public static final int PRESENCE_UNKNOWN_RESOURCE_ID = android.R.drawable.presence_offline;
/** email address -> photo id, presence */
/* package */ static final String[] PROJECTION_PHOTO_ID_PRESENCE = new String[] {
diff --git a/src/com/android/email/activity/MessageViewFragment.java b/src/com/android/email/activity/MessageViewFragment.java
index 99ba4edb7..5ad3e6e9a 100644
--- a/src/com/android/email/activity/MessageViewFragment.java
+++ b/src/com/android/email/activity/MessageViewFragment.java
@@ -36,8 +36,9 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.ImageView;
-import android.widget.TextView;
import java.security.InvalidParameterException;
@@ -47,7 +48,8 @@ import java.security.InvalidParameterException;
*
* See {@link MessageViewBase} for the class relation diagram.
*/
-public class MessageViewFragment extends MessageViewFragmentBase {
+public class MessageViewFragment extends MessageViewFragmentBase
+ implements CheckBox.OnCheckedChangeListener {
private ImageView mFavoriteIcon;
private View mInviteSection;
@@ -56,9 +58,9 @@ public class MessageViewFragment extends MessageViewFragmentBase {
private View mForwardButton;
// calendar meeting invite answers
- private TextView mMeetingYes;
- private TextView mMeetingMaybe;
- private TextView mMeetingNo;
+ private CheckBox mMeetingYes;
+ private CheckBox mMeetingMaybe;
+ private CheckBox mMeetingNo;
private MessageCommandButtonView mCommandButtons;
private int mPreviousMeetingResponse = -1;
@@ -163,9 +165,9 @@ public class MessageViewFragment extends MessageViewFragmentBase {
mReplyButton = view.findViewById(R.id.reply);
mReplyAllButton = view.findViewById(R.id.reply_all);
mForwardButton = view.findViewById(R.id.forward);
- mMeetingYes = (TextView) view.findViewById(R.id.accept);
- mMeetingMaybe = (TextView) view.findViewById(R.id.maybe);
- mMeetingNo = (TextView) view.findViewById(R.id.decline);
+ mMeetingYes = (CheckBox) view.findViewById(R.id.accept);
+ mMeetingMaybe = (CheckBox) view.findViewById(R.id.maybe);
+ mMeetingNo = (CheckBox) view.findViewById(R.id.decline);
// Star is only visible on this fragment (as opposed to MessageFileViewFragment.)
view.findViewById(R.id.favorite).setVisibility(View.VISIBLE);
@@ -174,9 +176,9 @@ public class MessageViewFragment extends MessageViewFragmentBase {
mReplyButton.setOnClickListener(this);
mReplyAllButton.setOnClickListener(this);
mForwardButton.setOnClickListener(this);
- mMeetingYes.setOnClickListener(this);
- mMeetingMaybe.setOnClickListener(this);
- mMeetingNo.setOnClickListener(this);
+ mMeetingYes.setOnCheckedChangeListener(this);
+ mMeetingMaybe.setOnCheckedChangeListener(this);
+ mMeetingNo.setOnCheckedChangeListener(this);
view.findViewById(R.id.invite_link).setOnClickListener(this);
// Show the command buttons at the bottom.
@@ -244,7 +246,9 @@ public class MessageViewFragment extends MessageViewFragmentBase {
@Override
protected void resetView() {
super.resetView();
- // TODO Hide command buttons. (Careful when to re-show it)
+ mMeetingYes.setChecked(false);
+ mMeetingNo.setChecked(false);
+ mMeetingMaybe.setChecked(false);
}
@Override
@@ -362,18 +366,6 @@ public class MessageViewFragment extends MessageViewFragmentBase {
onClickFavorite();
return;
- case R.id.accept:
- onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_ACCEPTED,
- R.string.message_view_invite_toast_yes);
- return;
- case R.id.maybe:
- onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_TENTATIVE,
- R.string.message_view_invite_toast_maybe);
- return;
- case R.id.decline:
- onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_DECLINED,
- R.string.message_view_invite_toast_no);
- return;
case R.id.invite_link:
onInviteLinkClicked();
return;
@@ -381,6 +373,25 @@ public class MessageViewFragment extends MessageViewFragmentBase {
super.onClick(view);
}
+ @Override
+ public void onCheckedChanged(CompoundButton view, boolean isChecked) {
+ if (!isChecked) return;
+ switch (view.getId()) {
+ case R.id.accept:
+ onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_ACCEPTED,
+ R.string.message_view_invite_toast_yes);
+ return;
+ case R.id.maybe:
+ onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_TENTATIVE,
+ R.string.message_view_invite_toast_maybe);
+ return;
+ case R.id.decline:
+ onRespondToInvite(EmailServiceConstants.MEETING_REQUEST_DECLINED,
+ R.string.message_view_invite_toast_no);
+ return;
+ }
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
diff --git a/src/com/android/email/activity/MessageViewFragmentBase.java b/src/com/android/email/activity/MessageViewFragmentBase.java
index ec524691e..7bc30c1aa 100644
--- a/src/com/android/email/activity/MessageViewFragmentBase.java
+++ b/src/com/android/email/activity/MessageViewFragmentBase.java
@@ -45,6 +45,7 @@ import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -55,6 +56,7 @@ import android.os.Environment;
import android.os.Handler;
import android.provider.ContactsContract;
import android.provider.ContactsContract.QuickContact;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
@@ -105,11 +107,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
private TextView mFromNameView;
private TextView mFromAddressView;
private TextView mDateTimeView;
- private TextView mToView;
- private TextView mCcView;
- private View mCcContainerView;
- private TextView mBccView;
- private View mBccContainerView;
+ private TextView mAddressesView;
private WebView mMessageContentView;
private LinearLayout mAttachments;
private View mTabSection;
@@ -117,6 +115,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
private ImageView mSenderPresenceView;
private View mMainView;
private View mLoadingProgress;
+ private Button mShowDetailsButton;
private TextView mMessageTab;
private TextView mAttachmentTab;
@@ -289,11 +288,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
mSubjectView = (TextView) view.findViewById(R.id.subject);
mFromNameView = (TextView) view.findViewById(R.id.from_name);
mFromAddressView = (TextView) view.findViewById(R.id.from_address);
- mToView = (TextView) view.findViewById(R.id.to);
- mCcView = (TextView) view.findViewById(R.id.cc);
- mCcContainerView = view.findViewById(R.id.cc_container);
- mBccView = (TextView) view.findViewById(R.id.bcc);
- mBccContainerView = view.findViewById(R.id.bcc_container);
+ mAddressesView = (TextView) view.findViewById(R.id.addresses);
mDateTimeView = (TextView) view.findViewById(R.id.datetime);
mMessageContentView = (WebView) view.findViewById(R.id.message_content);
mAttachments = (LinearLayout) view.findViewById(R.id.attachments);
@@ -302,6 +297,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
mSenderPresenceView = (ImageView) view.findViewById(R.id.presence);
mMainView = view.findViewById(R.id.main_panel);
mLoadingProgress = view.findViewById(R.id.loading_progress);
+ mShowDetailsButton = (Button) view.findViewById(R.id.show_details);
mFromNameView.setOnClickListener(this);
mFromAddressView.setOnClickListener(this);
@@ -318,6 +314,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
mAttachmentTab.setOnClickListener(this);
mShowPicturesTab.setOnClickListener(this);
mInviteTab.setOnClickListener(this);
+ mShowDetailsButton.setOnClickListener(this);
mAttachmentsScroll = view.findViewById(R.id.attachments_scroll);
mInviteScroll = view.findViewById(R.id.invite_scroll);
@@ -560,8 +557,10 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
makeVisible(mMessageTab, messageTabVisible);
makeVisible(mInviteTab, (tabFlags & TAB_FLAGS_HAS_INVITE) != 0);
makeVisible(mAttachmentTab, (tabFlags & TAB_FLAGS_HAS_ATTACHMENT) != 0);
- makeVisible(mShowPicturesTab, (tabFlags & TAB_FLAGS_HAS_PICTURES) != 0);
- mShowPicturesTab.setEnabled((tabFlags & TAB_FLAGS_PICTURE_LOADED) == 0);
+
+ final boolean hasPictures = (tabFlags & TAB_FLAGS_HAS_PICTURES) != 0;
+ final boolean pictureLoaded = (tabFlags & TAB_FLAGS_PICTURE_LOADED) != 0;
+ makeVisible(mShowPicturesTab, hasPictures && !pictureLoaded);
mAttachmentTab.setText(mContext.getResources().getQuantityString(
R.plurals.message_view_show_attachments_action,
@@ -725,7 +724,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
if (AttachmentDownloadService.getQueueSize() == 0) {
// Set to invisible; if the button is still in this state one second from now, we'll
// assume the download won't start right away, and we make the cancel button visible
- attachment.cancelButton.setVisibility(View.INVISIBLE);
+ attachment.cancelButton.setVisibility(View.GONE);
// Create the timed task that will change the button state
new AsyncTask() {
@Override
@@ -737,7 +736,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
}
@Override
protected void onPostExecute(Void result) {
- if (attachment.cancelButton.getVisibility() == View.INVISIBLE) {
+ if (attachment.cancelButton.getVisibility() != View.VISIBLE) {
attachment.cancelButton.setVisibility(View.VISIBLE);
}
}
@@ -757,23 +756,21 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
attachment.loadButton.setVisibility(View.VISIBLE);
attachment.cancelButton.setVisibility(View.GONE);
ProgressBar bar = attachment.progressView;
- bar.setVisibility(View.GONE);
+ bar.setVisibility(View.INVISIBLE);
}
}
/**
- * Called by ControllerResults. Show the "View" and "Save" buttons; hide "Load"
+ * Called by ControllerResults. Show the "View" and "Save" buttons; hide "Load" and "Stop"
*
* @param attachmentId the attachment that was just downloaded
*/
private void doFinishLoadAttachment(long attachmentId) {
AttachmentInfo info = findAttachmentInfo(attachmentId);
if (info != null) {
- info.loadButton.setVisibility(View.INVISIBLE);
info.loadButton.setVisibility(View.GONE);
- if (!TextUtils.isEmpty(info.name)) {
- info.saveButton.setVisibility(View.VISIBLE);
- }
+ info.cancelButton.setVisibility(View.GONE);
+ info.saveButton.setVisibility(TextUtils.isEmpty(info.name) ? View.GONE : View.VISIBLE);
info.viewButton.setVisibility(View.VISIBLE);
}
}
@@ -789,6 +786,19 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
}
}
+ private void onShowDetails() {
+ if (mMessage == null) {
+ return; // shouldn't happen
+ }
+ String date = formatDate(mMessage.mTimeStamp, true);
+ String to = Address.toString(Address.unpack(mMessage.mTo));
+ String cc = Address.toString(Address.unpack(mMessage.mCc));
+ String bcc = Address.toString(Address.unpack(mMessage.mBcc));
+ MessageViewMessageDetailsDialog dialog = MessageViewMessageDetailsDialog.newInstance(
+ getActivity(), date, to, cc, bcc);
+ dialog.show(getActivity().getFragmentManager(), null);
+ }
+
@Override
public void onClick(View view) {
if (!isMessageOpen()) {
@@ -825,6 +835,9 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
case R.id.show_pictures:
onShowPicturesInHtml();
break;
+ case R.id.show_details:
+ onShowDetails();
+ break;
}
}
@@ -1132,7 +1145,7 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
attachmentProgress.setProgress(100);
attachmentSave.setVisibility(View.VISIBLE);
attachmentView.setVisibility(View.VISIBLE);
- attachmentLoad.setVisibility(View.INVISIBLE);
+ attachmentLoad.setVisibility(View.GONE);
attachmentCancel.setVisibility(View.GONE);
Bitmap previewIcon = getPreviewIcon(attachmentInfo);
@@ -1141,8 +1154,9 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
}
} else {
// Show "Load"; hide "View" and "Save"
- attachmentSave.setVisibility(View.INVISIBLE);
- attachmentView.setVisibility(View.INVISIBLE);
+ attachmentSave.setVisibility(View.GONE);
+ attachmentView.setVisibility(View.GONE);
+
// If the attachment is queued, show the indeterminate progress bar. From this point,.
// any progress changes will cause this to be replaced by the normal progress bar
if (AttachmentDownloadService.isAttachmentQueued(attachment.mId)){
@@ -1227,24 +1241,43 @@ public abstract class MessageViewFragmentBase extends Fragment implements View.O
mFromNameView.setText(" ");
mFromAddressView.setText(" ");
}
- mDateTimeView.setText(formatDate(message.mTimeStamp));
- mToView.setText(Address.toFriendly(Address.unpack(message.mTo)));
- String friendlyCc = Address.toFriendly(Address.unpack(message.mCc));
- mCcView.setText(friendlyCc);
- mCcContainerView.setVisibility((friendlyCc != null) ? View.VISIBLE : View.GONE);
- String friendlyBcc = Address.toFriendly(Address.unpack(message.mBcc));
- mBccView.setText(friendlyBcc);
- mBccContainerView.setVisibility((friendlyBcc != null) ? View.VISIBLE : View.GONE);
+ mDateTimeView.setText(formatDate(message.mTimeStamp, false));
+
+ // To/Cc/Bcc
+ final Resources res = mContext.getResources();
+ final SpannableStringBuilder ssb = new SpannableStringBuilder();
+ final String friendlyTo = Address.toFriendly(Address.unpack(message.mTo));
+ final String friendlyCc = Address.toFriendly(Address.unpack(message.mCc));
+ final String friendlyBcc = Address.toFriendly(Address.unpack(message.mBcc));
+
+ if (!TextUtils.isEmpty(friendlyTo)) {
+ Utility.appendBold(ssb, res.getString(R.string.message_view_to_label));
+ ssb.append(" ");
+ ssb.append(friendlyTo);
+ }
+ if (!TextUtils.isEmpty(friendlyCc)) {
+ ssb.append(" ");
+ Utility.appendBold(ssb, res.getString(R.string.message_view_cc_label));
+ ssb.append(" ");
+ ssb.append(friendlyCc);
+ }
+ if (!TextUtils.isEmpty(friendlyBcc)) {
+ ssb.append(" ");
+ Utility.appendBold(ssb, res.getString(R.string.message_view_bcc_label));
+ ssb.append(" ");
+ ssb.append(friendlyBcc);
+ }
+ mAddressesView.setText(ssb);
}
- private String formatDate(long millis) {
+ private String formatDate(long millis, boolean withYear) {
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
DateUtils.formatDateRange(mContext, formatter, millis, millis,
DateUtils.FORMAT_SHOW_DATE
| DateUtils.FORMAT_ABBREV_ALL
| DateUtils.FORMAT_SHOW_TIME
- | DateUtils.FORMAT_NO_YEAR);
+ | (withYear ? DateUtils.FORMAT_SHOW_YEAR : DateUtils.FORMAT_NO_YEAR));
return sb.toString();
}
diff --git a/src/com/android/email/activity/MessageViewMessageDetailsDialog.java b/src/com/android/email/activity/MessageViewMessageDetailsDialog.java
new file mode 100644
index 000000000..4194684a6
--- /dev/null
+++ b/src/com/android/email/activity/MessageViewMessageDetailsDialog.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.email.activity;
+
+import com.android.email.R;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * "Message Details" dialog box.
+ */
+public class MessageViewMessageDetailsDialog extends DialogFragment {
+ private static final String BUNDLE_DATE = "date";
+ private static final String BUNDLE_TO = "to";
+ private static final String BUNDLE_CC = "cc";
+ private static final String BUNDLE_BCC = "bcc";
+ private static final String TextView = null;
+
+ public static MessageViewMessageDetailsDialog newInstance(Activity parent, String date,
+ String to, String cc, String bcc) {
+ MessageViewMessageDetailsDialog dialog = new MessageViewMessageDetailsDialog();
+ Bundle args = new Bundle();
+ args.putString(BUNDLE_DATE, date);
+ args.putString(BUNDLE_TO, to);
+ args.putString(BUNDLE_CC, cc);
+ args.putString(BUNDLE_BCC, bcc);
+ dialog.setArguments(args);
+ return dialog;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Activity activity = getActivity();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity).setTitle(
+ activity.getResources().getString(
+ R.string.message_view_message_details_dialog_title));
+ builder.setNegativeButton(R.string.close_action, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dismiss();
+ }
+ });
+ builder.setView(initView());
+
+ return builder.show();
+ }
+
+ private View initView() {
+ View root = getActivity().getLayoutInflater().inflate(R.layout.message_view_details, null);
+ Bundle args = getArguments();
+
+ setText(root, args.getString(BUNDLE_DATE), R.id.date, R.id.date_row);
+ setText(root, args.getString(BUNDLE_TO), R.id.to, R.id.to_row);
+ setText(root, args.getString(BUNDLE_CC), R.id.cc, R.id.cc_row);
+ setText(root, args.getString(BUNDLE_BCC), R.id.bcc, R.id.bcc_row);
+
+ return root;
+ }
+
+ private static void setText(View root, String text, int textViewId, int rowViewId) {
+ if (TextUtils.isEmpty(text)) {
+ root.findViewById(rowViewId).setVisibility(View.GONE);
+ return;
+ }
+ ((TextView) root.findViewById(textViewId)).setText(text);
+ }
+}
diff --git a/src/com/android/email/mail/Address.java b/src/com/android/email/mail/Address.java
index 4fb1c32c9..9453a61ba 100644
--- a/src/com/android/email/mail/Address.java
+++ b/src/com/android/email/mail/Address.java
@@ -32,7 +32,7 @@ import java.util.regex.Pattern;
/**
* This class represent email address.
- *
+ *
* RFC822 email address may have following format.
* "name" (comment)
* "name"
@@ -85,7 +85,7 @@ public class Address {
/**
* Get name part as UTF-16 string. No surrounding double quote, and no MIME/base64 encoding.
- *
+ *
* @return Name part of email address. Returns null if it is omitted.
*/
public String getPersonal() {
@@ -95,7 +95,7 @@ public class Address {
/**
* Set name part from UTF-16 string. Optional surrounding double quote will be removed.
* It will be also unquoted and MIME/base64 decoded.
- *
+ *
* @param Personal name part of email address as UTF-16 string. Null is acceptable.
*/
public void setPersonal(String personal) {
@@ -133,7 +133,7 @@ public class Address {
/**
* Parse a comma-delimited list of addresses in RFC822 format and return an
* array of Address objects.
- *
+ *
* @param addressList Address list in comma-delimited string.
* @return An array of 0 or more Addresses.
*/
@@ -158,8 +158,8 @@ public class Address {
}
return addresses.toArray(new Address[] {});
}
-
- /**
+
+ /**
* Checks whether a string email address is valid.
* E.g. name@domain.com is valid.
*/
@@ -195,12 +195,12 @@ public class Address {
/**
* Get human readable address string.
* Do not use this for email header.
- *
+ *
* @return Human readable address string. Not quoted and not encoded.
*/
@Override
public String toString() {
- if (mPersonal != null) {
+ if (mPersonal != null && !mPersonal.equals(mAddress)) {
if (mPersonal.matches(".*[\\(\\)<>@,;:\\\\\".\\[\\]].*")) {
return Utility.quoteString(mPersonal) + " <" + mAddress + ">";
} else {
@@ -213,7 +213,7 @@ public class Address {
/**
* Get human readable comma-delimited address string.
- *
+ *
* @param addresses Address array
* @return Human readable comma-delimited address string.
*/
@@ -231,10 +231,10 @@ public class Address {
}
return sb.toString();
}
-
+
/**
* Get RFC822/MIME compatible address string.
- *
+ *
* @return RFC822/MIME compatible address string.
* It may be surrounded by double quote or quoted and MIME/base64 encoded if necessary.
*/
@@ -248,7 +248,7 @@ public class Address {
/**
* Get RFC822/MIME compatible comma-delimited address string.
- *
+ *
* @param addresses Address array
* @return RFC822/MIME compatible comma-delimited address string.
* it may be surrounded by double quoted or quoted and MIME/base64 encoded if necessary.
@@ -268,11 +268,11 @@ public class Address {
}
return sb.toString();
}
-
+
/**
* Get Human friendly address string.
- *
- * @return the personal part of this Address, or the address part if the
+ *
+ * @return the personal part of this Address, or the address part if the
* personal part is not available
*/
public String toFriendly() {
@@ -282,11 +282,11 @@ public class Address {
return mAddress;
}
}
-
+
/**
- * Creates a comma-delimited list of addresses in the "friendly" format (see toFriendly() for
+ * Creates a comma-delimited list of addresses in the "friendly" format (see toFriendly() for
* details on the per-address conversion).
- *
+ *
* @param addresses Array of Address[] values
* @return A comma-delimited string listing all of the addresses supplied. Null if source
* was null or empty.
@@ -466,7 +466,7 @@ public class Address {
else {
address =
Utility.fastUrlDecode(addressList.substring(pairStartIndex, addressEndIndex));
- personal =
+ personal =
Utility.fastUrlDecode(addressList.substring(addressEndIndex + 1, pairEndIndex));
}
addresses.add(new Address(address, personal));
diff --git a/tests/src/com/android/email/UtilityUnitTests.java b/tests/src/com/android/email/UtilityUnitTests.java
index 25a3c2d60..eef5a542c 100644
--- a/tests/src/com/android/email/UtilityUnitTests.java
+++ b/tests/src/com/android/email/UtilityUnitTests.java
@@ -27,6 +27,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
+import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
@@ -37,6 +38,7 @@ import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ListView;
@@ -479,6 +481,16 @@ public class UtilityUnitTests extends AndroidTestCase {
Utility.CloseTraceCursorWrapper.log(null);
}
+ public void testAppendBold() {
+ SpannableStringBuilder ssb = new SpannableStringBuilder();
+ ssb.append("no");
+
+ assertEquals(ssb, Utility.appendBold(ssb, "BO"));
+
+ assertEquals("noBO", ssb.toString());
+ // TODO check style -- but how?
+ }
+
/**
* A {@link ListView} used by {@link #testListStateSaver}.
*/
diff --git a/tests/src/com/android/email/mail/AddressUnitTests.java b/tests/src/com/android/email/mail/AddressUnitTests.java
index 87d1452c3..ba4f50012 100644
--- a/tests/src/com/android/email/mail/AddressUnitTests.java
+++ b/tests/src/com/android/email/mail/AddressUnitTests.java
@@ -29,8 +29,8 @@ import java.io.UnsupportedEncodingException;
*/
@SmallTest
public class AddressUnitTests extends AndroidTestCase {
-
- private static final String MULTI_ADDRESSES_LIST =
+
+ private static final String MULTI_ADDRESSES_LIST =
"noname1@dom1.com, "
+ ", "
+ "simple name , "
@@ -39,19 +39,21 @@ public class AddressUnitTests extends AndroidTestCase {
+ "\u65E5\u672C\u8A9E ,"
+ "\"\u65E5\u672C\u8A9E\" ,"
+ "\uD834\uDF01\uD834\uDF46 ,"
- + "\"\uD834\uDF01\uD834\uDF46\" ";
- private static final int MULTI_ADDRESSES_COUNT = 9;
+ + "\"\uD834\uDF01\uD834\uDF46\" ,"
+ + "noname@dom.com " // personal == address
+ ;
+ private static final int MULTI_ADDRESSES_COUNT = 10;
private static final Address PACK_ADDR_1 = new Address("john@gmail.com", "John Doe");
private static final Address PACK_ADDR_2 = new Address("foo@bar.com", null);
private static final Address PACK_ADDR_3 = new Address("mar.y+test@gmail.com", "Mar-y, B; B*arr");
private static final Address[][] PACK_CASES = {
- {PACK_ADDR_2}, {PACK_ADDR_1},
- {PACK_ADDR_1, PACK_ADDR_2}, {PACK_ADDR_2, PACK_ADDR_1},
- {PACK_ADDR_1, PACK_ADDR_3}, {PACK_ADDR_2, PACK_ADDR_2},
+ {PACK_ADDR_2}, {PACK_ADDR_1},
+ {PACK_ADDR_1, PACK_ADDR_2}, {PACK_ADDR_2, PACK_ADDR_1},
+ {PACK_ADDR_1, PACK_ADDR_3}, {PACK_ADDR_2, PACK_ADDR_2},
{PACK_ADDR_1, PACK_ADDR_2, PACK_ADDR_3}, {PACK_ADDR_3, PACK_ADDR_1, PACK_ADDR_2}
};
-
+
Address mAddress1;
Address mAddress2;
Address mAddress3;
@@ -95,61 +97,61 @@ public class AddressUnitTests extends AndroidTestCase {
public void testSetAddress() {
String bareAddress = "user1@dom1.com";
String bracketAddress = "";
-
+
Address address = new Address(bareAddress);
assertEquals("bare address", "user1@dom1.com", address.getAddress());
-
+
address.setAddress(bracketAddress);
assertEquals("bracket address", "user2@dom2.com", address.getAddress());
}
-
+
/**
* Test for empty setPersonal().
*/
public void testNullPersonal() {
Address address = new Address("user1@dom1.org");
assertNull("no name", address.getPersonal());
-
+
address.setPersonal(null);
assertNull("null name", address.getPersonal());
-
+
address.setPersonal("");
assertNull("empty name", address.getPersonal());
-
+
address.setPersonal("\"\"");
assertNull("quoted empty address", address.getPersonal());
}
-
+
/**
* Test for setPersonal().
*/
public void testSetPersonal() {
Address address = new Address("user1@dom1.net", "simple name");
assertEquals("simple name", "simple name", address.getPersonal());
-
+
address.setPersonal("big \\\"G\\\"");
assertEquals("quoted name", "big \"G\"", address.getPersonal());
-
+
address.setPersonal("=?UTF-8?Q?big \"G\"?=");
assertEquals("quoted printable name", "big \"G\"", address.getPersonal());
-
+
address.setPersonal("=?UTF-8?B?YmlnICJHIg==?=");
assertEquals("base64 encoded name", "big \"G\"", address.getPersonal());
}
-
+
/**
* Test for setPersonal() with utf-16 and utf-32.
*/
public void testSetPersonalMultipleEncodings() {
Address address = new Address("user1@dom1.co.jp", "=?UTF-8?B?5bK45pys?=");
assertEquals("base64 utf-16 name", "\u5CB8\u672C", address.getPersonal());
-
+
address.setPersonal("\"=?UTF-8?Q?=E5=B2=B8=E6=9C=AC?=\"");
assertEquals("quoted printable utf-16 name", "\u5CB8\u672C", address.getPersonal());
-
+
address.setPersonal("=?ISO-2022-JP?B?GyRCNF9LXBsoQg==?=");
assertEquals("base64 jis encoded name", "\u5CB8\u672C", address.getPersonal());
-
+
address.setPersonal("\"=?UTF-8?B?8J2MgfCdjYY=?=\"");
assertEquals("base64 utf-32 name", "\uD834\uDF01\uD834\uDF46", address.getPersonal());
@@ -157,28 +159,28 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("quoted printable utf-32 name",
"\uD834\uDF01\uD834\uDF46", address.getPersonal());
}
-
+
/**
* TODO: more in-depth tests for parse()
*/
-
+
/**
* Simple quick checks of empty-input edge conditions for parse()
- *
+ *
* NOTE: This is not a claim that these edge cases are "correct", only to maintain consistent
* behavior while I am changing some of the code in the function under test.
*/
public void testEmptyParse() {
Address[] result;
-
+
// null input => empty array
result = Address.parse(null);
assertTrue("parsing null address", result != null && result.length == 0);
-
+
// empty string input => empty array
result = Address.parse("");
assertTrue("parsing zero-length", result != null && result.length == 0);
-
+
// spaces
result = Address.parse(" ");
assertTrue("parsing spaces", result != null && result.length == 0);
@@ -187,7 +189,7 @@ public class AddressUnitTests extends AndroidTestCase {
result = Address.parse(" , ");
assertTrue("parsing spaces with comma", result != null && result.length == 0);
}
-
+
/**
* Test parsing for single address.
*/
@@ -212,7 +214,7 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("address with quoted name", "address4@dom4.org", address4[0].getAddress());
assertEquals("name of address with quoted name", "first,last", address4[0].getPersonal());
}
-
+
/**
* Test parsing for illegal address.
*/
@@ -222,7 +224,7 @@ public class AddressUnitTests extends AndroidTestCase {
Address[] address2 = Address.parse("address2@");
assertEquals("no domain", 0, address2.length);
-
+
Address[] address3 = Address.parse("@dom3.com");
assertEquals("no local part", 0, address3.length);
@@ -238,7 +240,7 @@ public class AddressUnitTests extends AndroidTestCase {
Address[] address7 = Address.parse("address7@.dom7.org");
assertEquals("domain starts with dot", 0, address7.length);
}
-
+
/**
* Test parsing for address part.
*/
@@ -252,7 +254,7 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("bracket address", "address2@dom2.com", addresses[1].getAddress());
assertNull("bracket address name", addresses[1].getPersonal());
}
-
+
/**
* Test parsing for simple name part.
*/
@@ -261,14 +263,14 @@ public class AddressUnitTests extends AndroidTestCase {
"name 1 , " +
"\"name,2\" ");
assertEquals("address count", 2, addresses.length);
-
+
assertEquals("bare name address", "address1@dom1.net", addresses[0].getAddress());
assertEquals("bare name", "name 1", addresses[0].getPersonal());
assertEquals("double quoted name address", "address2@dom2.org", addresses[1].getAddress());
assertEquals("double quoted name", "name,2", addresses[1].getPersonal());
}
-
+
/**
* Test parsing for utf-16 name part.
*/
@@ -277,7 +279,7 @@ public class AddressUnitTests extends AndroidTestCase {
"\u3042\u3044\u3046 \u3048\u304A , " +
"\"\u3042\u3044\u3046,\u3048\u304A\" ");
assertEquals("address count", 2, addresses.length);
-
+
assertEquals("bare utf-16 name address", "address1@dom1.jp", addresses[0].getAddress());
assertEquals("bare utf-16 name",
"\u3042\u3044\u3046 \u3048\u304A", addresses[0].getPersonal());
@@ -287,7 +289,7 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted utf-16 name",
"\u3042\u3044\u3046,\u3048\u304A", addresses[1].getPersonal());
}
-
+
/**
* Test parsing for utf-32 name part.
*/
@@ -296,7 +298,7 @@ public class AddressUnitTests extends AndroidTestCase {
"\uD834\uDF01\uD834\uDF46 \uD834\uDF22 , " +
"\"\uD834\uDF01\uD834\uDF46,\uD834\uDF22\" ");
assertEquals("address count", 2, addresses.length);
-
+
assertEquals("bare utf-32 name address", "address1@dom1.net", addresses[0].getAddress());
assertEquals("bare utf-32 name",
"\uD834\uDF01\uD834\uDF46 \uD834\uDF22", addresses[0].getPersonal());
@@ -306,15 +308,15 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted utf-32 name",
"\uD834\uDF01\uD834\uDF46,\uD834\uDF22", addresses[1].getPersonal());
}
-
+
/**
* Test parsing for multi addresses.
*/
public void testParseMulti() {
Address[] addresses = Address.parse(MULTI_ADDRESSES_LIST);
-
+
assertEquals("multi addrsses count", MULTI_ADDRESSES_COUNT, addresses.length);
-
+
assertEquals("no name 1 address", "noname1@dom1.com", addresses[0].getAddress());
assertNull("no name 1 name", addresses[0].getPersonal());
assertEquals("no name 2 address", "noname2@dom2.com", addresses[1].getAddress());
@@ -325,24 +327,24 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted name name", "name,4", addresses[3].getPersonal());
assertEquals("quoted name address", "bigG@dom5.net", addresses[4].getAddress());
assertEquals("quoted name name", "big \"G\"", addresses[4].getPersonal());
- assertEquals("utf-16 name address", "address6@co.jp", addresses[5].getAddress());
- assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", addresses[5].getPersonal());
- assertEquals("utf-16 quoted name address", "address7@co.jp", addresses[6].getAddress());
+ assertEquals("utf-16 name address", "address6@co.jp", addresses[5].getAddress());
+ assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", addresses[5].getPersonal());
+ assertEquals("utf-16 quoted name address", "address7@co.jp", addresses[6].getAddress());
assertEquals("utf-16 quoted name name", "\u65E5\u672C\u8A9E",
- addresses[6].getPersonal());
- assertEquals("utf-32 name address", "address8@ne.jp", addresses[7].getAddress());
- assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", addresses[7].getPersonal());
- assertEquals("utf-32 quoted name address", "address9@ne.jp", addresses[8].getAddress());
+ addresses[6].getPersonal());
+ assertEquals("utf-32 name address", "address8@ne.jp", addresses[7].getAddress());
+ assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", addresses[7].getPersonal());
+ assertEquals("utf-32 quoted name address", "address9@ne.jp", addresses[8].getAddress());
assertEquals("utf-32 quoted name name", "\uD834\uDF01\uD834\uDF46",
- addresses[8].getPersonal());
+ addresses[8].getPersonal());
}
-
+
/**
* Test various combinations of the toString (single) method
*/
public void testToStringSingle() {
Address[] addresses = Address.parse(MULTI_ADDRESSES_LIST);
-
+
assertEquals("multi addrsses count", MULTI_ADDRESSES_COUNT, addresses.length);
// test for toString() results.
@@ -352,25 +354,26 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted name", "\"name,4\" ", addresses[3].toString());
assertEquals("quoted name", "\"big \"G\"\" ", addresses[4].toString());
assertEquals("utf-16 name", "\u65E5\u672C\u8A9E ",
- addresses[5].toString());
+ addresses[5].toString());
assertEquals("utf-16 quoted name", "\u65E5\u672C\u8A9E ",
- addresses[6].toString());
+ addresses[6].toString());
assertEquals("utf-32 name", "\uD834\uDF01\uD834\uDF46 ",
- addresses[7].toString());
+ addresses[7].toString());
assertEquals("utf-32 quoted name", "\uD834\uDF01\uD834\uDF46 ",
- addresses[8].toString());
+ addresses[8].toString());
+ assertEquals("name==address", "noname@dom.com", addresses[9].toString());
}
-
+
/**
* Test various combinations of the toString (multi) method
*/
public void testToStringMulti() {
Address[] addresses = Address.parse(MULTI_ADDRESSES_LIST);
-
+
assertEquals("multi addrsses count", MULTI_ADDRESSES_COUNT, addresses.length);
String line = Address.toString(addresses);
- assertEquals("toString multi",
+ assertEquals("toString multi",
"noname1@dom1.com,"
+ "noname2@dom2.com,"
+ "simple name ,"
@@ -379,7 +382,8 @@ public class AddressUnitTests extends AndroidTestCase {
+ "\u65E5\u672C\u8A9E ,"
+ "\u65E5\u672C\u8A9E ,"
+ "\uD834\uDF01\uD834\uDF46 ,"
- + "\uD834\uDF01\uD834\uDF46 ",
+ + "\uD834\uDF01\uD834\uDF46 ,"
+ + "noname@dom.com",
line);
}
@@ -410,7 +414,8 @@ public class AddressUnitTests extends AndroidTestCase {
Address quotedName = new Address("bigG@dom5.net", "big \"G\"");
Address utf16Name = new Address("", "\"\u65E5\u672C\u8A9E\"");
Address utf32Name = new Address("", "\uD834\uDF01\uD834\uDF46");
-
+ Address sameName = new Address("address@dom.org", "address@dom.org");
+
// test for internal states.
assertEquals("no name 1 address", "noname1@dom1.com", noName1.getAddress());
assertNull("no name 1 name", noName1.getPersonal());
@@ -422,10 +427,12 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted name name", "name,4", dquoteName.getPersonal());
assertEquals("quoted name address", "bigG@dom5.net", quotedName.getAddress());
assertEquals("quoted name name", "big \"G\"", quotedName.getPersonal());
- assertEquals("utf-16 name address", "address6@co.jp", utf16Name.getAddress());
- assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", utf16Name.getPersonal());
- assertEquals("utf-32 name address", "address8@ne.jp", utf32Name.getAddress());
- assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", utf32Name.getPersonal());
+ assertEquals("utf-16 name address", "address6@co.jp", utf16Name.getAddress());
+ assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", utf16Name.getPersonal());
+ assertEquals("utf-32 name address", "address8@ne.jp", utf32Name.getAddress());
+ assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", utf32Name.getPersonal());
+ assertEquals("name == address address", "address@dom.org", sameName.getAddress());
+ assertEquals("name == address name", "address@dom.org", sameName.getPersonal());
// Test for toHeader() results.
assertEquals("no name 1", "noname1@dom1.com", noName1.toHeader());
@@ -434,11 +441,13 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted name", "\"name,4\" ", dquoteName.toHeader());
assertEquals("quoted name", "\"big \\\"G\\\"\" ", quotedName.toHeader());
assertEquals("utf-16 name", "=?UTF-8?B?5pel5pys6Kqe?= ",
- utf16Name.toHeader());
+ utf16Name.toHeader());
assertEquals("utf-32 name", "=?UTF-8?B?8J2MgfCdjYY=?= ",
- utf32Name.toHeader());
+ utf32Name.toHeader());
+ assertEquals("name == address", "\"address@dom.org\" ",
+ sameName.toHeader());
}
-
+
/**
* Test various combinations of the toHeader (multi) method
*/
@@ -450,7 +459,7 @@ public class AddressUnitTests extends AndroidTestCase {
Address quotedName = new Address("bigG@dom5.net", "big \"G\"");
Address utf16Name = new Address("", "\"\u65E5\u672C\u8A9E\"");
Address utf32Name = new Address("", "\uD834\uDF01\uD834\uDF46");
-
+
// test for internal states.
assertEquals("no name 1 address", "noname1@dom1.com", noName1.getAddress());
assertNull("no name 1 name", noName1.getPersonal());
@@ -462,10 +471,10 @@ public class AddressUnitTests extends AndroidTestCase {
assertEquals("double quoted name name", "name,4", dquoteName.getPersonal());
assertEquals("quoted name address", "bigG@dom5.net", quotedName.getAddress());
assertEquals("quoted name name", "big \"G\"", quotedName.getPersonal());
- assertEquals("utf-16 name address", "address6@co.jp", utf16Name.getAddress());
- assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", utf16Name.getPersonal());
- assertEquals("utf-32 name address", "address8@ne.jp", utf32Name.getAddress());
- assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", utf32Name.getPersonal());
+ assertEquals("utf-16 name address", "address6@co.jp", utf16Name.getAddress());
+ assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", utf16Name.getPersonal());
+ assertEquals("utf-32 name address", "address8@ne.jp", utf32Name.getAddress());
+ assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", utf32Name.getPersonal());
Address[] addresses = new Address[] {
noName1, noName2, simpleName, dquoteName, quotedName, utf16Name, utf32Name,
@@ -482,62 +491,62 @@ public class AddressUnitTests extends AndroidTestCase {
+ "=?UTF-8?B?8J2MgfCdjYY=?= ",
line);
}
-
+
/**
* Test various combinations of the toFriendly (single) method
*/
- public void testToFriendlySingle() {
+ public void testToFriendlySingle() {
assertEquals("personal1", mAddress1.toFriendly());
assertEquals("address2", mAddress2.toFriendly());
assertEquals("address3", mAddress3.toFriendly());
}
-
+
/**
* Test various combinations of the toFriendly (array) method
*/
- public void testToFriendlyArray() {
+ public void testToFriendlyArray() {
Address[] list1 = null;
Address[] list2 = new Address[0];
Address[] list3 = new Address[] { mAddress1 };
Address[] list4 = new Address[] { mAddress1, mAddress2, mAddress3 };
-
+
assertEquals(null, Address.toFriendly(list1));
assertEquals(null, Address.toFriendly(list2));
assertEquals("personal1", Address.toFriendly(list3));
assertEquals("personal1,address2,address3", Address.toFriendly(list4));
}
-
+
/**
* Simple quick checks of empty-input edge conditions for pack()
- *
+ *
* NOTE: This is not a claim that these edge cases are "correct", only to maintain consistent
* behavior while I am changing some of the code in the function under test.
*/
public void testEmptyPack() {
String result;
-
+
// null input => null string
result = Address.pack(null);
assertNull("packing null", result);
-
+
// zero-length input => empty string
result = Address.pack(new Address[] { });
assertEquals("packing empty array", "", result);
}
-
+
/**
* Simple quick checks of empty-input edge conditions for unpack()
- *
+ *
* NOTE: This is not a claim that these edge cases are "correct", only to maintain consistent
* behavior while I am changing some of the code in the function under test.
*/
public void testEmptyUnpack() {
Address[] result;
-
+
// null input => empty array
result = Address.unpack(null);
assertTrue("unpacking null address", result != null && result.length == 0);
-
+
// empty string input => empty array
result = Address.unpack("");
assertTrue("unpacking zero-length", result != null && result.length == 0);
@@ -642,7 +651,7 @@ public class AddressUnitTests extends AndroidTestCase {
for (String address : valid) {
assertTrue(address, Address.isValidAddress(address));
}
-
+
// isAllValid() must accept empty address list as valid
assertTrue("Empty address list is valid", Address.isAllValid(""));
}