Pixel perfect: Message view
Still waiting for a few missing assets, but it's done other than that. The divider change is already merged; new layouts all use the framework style. It's basically all layout changes, except for: - Now the recepient address line has "Show details", which shows a dialog with all to/cc/bcc addresses with the timestamp. - Now invite response buttons are checkboxes. (But the basic behavior doesn't change -- once you check a response, the message will be gone, so you can't change the response later.) Copied message_header_bg from gmail manuall. It'll look silly without it. Bug 3138021 Bug 3307021 Change-Id: I6f7eb91d6104c3143a5c58b0c4c6c19929cea477
This commit is contained in:
parent
07f5f60b8f
commit
a826d3fb03
BIN
res/drawable-hdpi/message_header_bg.png
Normal file
BIN
res/drawable-hdpi/message_header_bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1007 B |
BIN
res/drawable-mdpi/message_header_bg.png
Normal file
BIN
res/drawable-mdpi/message_header_bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB |
172
res/layout-xlarge/message_view_attachment.xml
Normal file
172
res/layout-xlarge/message_view_attachment.xml
Normal file
@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<!-- xlarge -->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dip"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<!-- STOPSHIP default icon is not final -->
|
||||
<ImageView
|
||||
android:id="@+id/attachment_icon"
|
||||
android:layout_width="64dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0"
|
||||
android:src="@drawable/attached_image_placeholder"
|
||||
android:scaleType="fitCenter"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:showDividers="middle"
|
||||
android:dividerPadding="16dip"
|
||||
>
|
||||
<RelativeLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="32dip"
|
||||
android:layout_marginRight="16dip"
|
||||
>
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:max="100"
|
||||
android:visibility="invisible"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/attachment_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_above="@id/progress"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:gravity="right|bottom"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/attachment_name"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_toLeftOf="@id/attachment_info"
|
||||
android:layout_above="@id/progress"
|
||||
android:textSize="18dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="middle"
|
||||
android:gravity="left|bottom"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Buttons -->
|
||||
<LinearLayout
|
||||
android:layout_width="224dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0"
|
||||
android:orientation="horizontal"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:showDividers="middle"
|
||||
android:dividerPadding="16dip"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/load"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_attachment_load_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_attachment_cancel_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/view"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_attachment_view_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/save"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_attachment_save_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -43,72 +43,71 @@
|
||||
<TextView
|
||||
android:id="@+id/subject"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="40dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="30dip"
|
||||
android:layout_marginLeft="30dip"
|
||||
android:layout_marginRight="30dip"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="none"
|
||||
android:layout_marginTop="0dip"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:textSize="18dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
||||
<!-- Horizontal line below subject -->
|
||||
<View
|
||||
android:id="@+id/top_divider"
|
||||
android:layout_width="0dip"
|
||||
android:layout_below="@id/subject"
|
||||
android:layout_alignLeft="@id/subject"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:layout_marginTop="8dip"
|
||||
android:layout_marginBottom="16dip"
|
||||
style="@style/message_view_horizontal_divider"
|
||||
android:gravity="left|center_vertical"
|
||||
/>
|
||||
|
||||
<!-- Badge -->
|
||||
<ImageButton
|
||||
android:id="@+id/badge"
|
||||
android:layout_width="60dip"
|
||||
android:layout_height="60dip"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_alignTop="@id/top_divider"
|
||||
android:layout_width="64dip"
|
||||
android:layout_height="64dip"
|
||||
android:layout_below="@id/subject"
|
||||
android:layout_alignLeft="@id/subject"
|
||||
android:padding="0dip"
|
||||
android:scaleType="fitCenter"
|
||||
/>
|
||||
|
||||
<!-- Presence icon -->
|
||||
<ImageView
|
||||
android:id="@+id/presence"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/top_divider"
|
||||
<!-- Background for sender name and buttons -->
|
||||
<View
|
||||
android:id="@+id/header_background"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="64dip"
|
||||
android:layout_below="@id/subject"
|
||||
android:layout_toRightOf="@id/badge"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="12dip"
|
||||
android:src="@drawable/presence_inactive"
|
||||
android:background="@drawable/quickcontact_presence_bg"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:background="@drawable/message_header_bg"
|
||||
/>
|
||||
<!-- Fold -->
|
||||
<ImageView
|
||||
android:id="@+id/header_background_fold"
|
||||
android:layout_width="32dip"
|
||||
android:layout_height="20dip"
|
||||
android:layout_below="@id/header_background"
|
||||
android:layout_alignRight="@id/header_background"
|
||||
android:src="@drawable/message_header_fold"
|
||||
android:padding="0dip"
|
||||
/>
|
||||
|
||||
<!--
|
||||
reply, reply-all, forward, Star
|
||||
They can all be gone; don't refer to them from other views.
|
||||
Instead refer to this outer layout.
|
||||
These buttons can all be gone at runtime, so don't refer to individual buttons from
|
||||
other views. Instead refer to this outer layout.
|
||||
-->
|
||||
<LinearLayout
|
||||
android:id="@+id/forward_reply_buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="24dip"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:layout_below="@id/top_divider"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dip"
|
||||
android:layout_marginLeft="8dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:layout_alignTop="@id/header_background"
|
||||
android:layout_alignRight="@id/header_background"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<ImageButton
|
||||
android:id="@+id/reply"
|
||||
android:layout_width="32dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_height="32dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:src="@drawable/ic_reply"
|
||||
android:visibility="gone"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
@ -116,9 +115,8 @@
|
||||
<ImageButton
|
||||
android:id="@+id/reply_all"
|
||||
android:layout_width="32dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_height="32dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:src="@drawable/ic_reply_all"
|
||||
android:visibility="gone"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
@ -126,9 +124,8 @@
|
||||
<ImageButton
|
||||
android:id="@+id/forward"
|
||||
android:layout_width="32dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_height="32dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:src="@drawable/ic_forward"
|
||||
android:visibility="gone"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
@ -136,151 +133,127 @@
|
||||
<ImageButton
|
||||
android:id="@+id/favorite"
|
||||
android:layout_width="32dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_height="32dip"
|
||||
android:src="@drawable/ic_star_none_holo_light"
|
||||
android:visibility="gone"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Sender display name -->
|
||||
<TextView
|
||||
android:id="@+id/from_name"
|
||||
|
||||
<!-- presence, sender address, sender name: make them center_vertical -->
|
||||
<LinearLayout
|
||||
android:id="@+id/presence_from_name"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/top_divider"
|
||||
android:layout_toRightOf="@id/presence"
|
||||
android:layout_height="0dip"
|
||||
android:layout_marginLeft="32dip"
|
||||
android:layout_marginRight="16dip"
|
||||
android:layout_alignTop="@id/header_background"
|
||||
android:layout_alignBottom="@id/header_background"
|
||||
android:layout_alignLeft="@id/header_background"
|
||||
android:layout_toLeftOf="@id/forward_reply_buttons"
|
||||
android:textSize="18dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@+id/presence_from_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="left|center_vertical"
|
||||
>
|
||||
<!-- Presence icon -->
|
||||
<ImageView
|
||||
android:id="@+id/presence"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:src="@android:drawable/presence_offline"
|
||||
/>
|
||||
|
||||
<!-- Sender display name -->
|
||||
<TextView
|
||||
android:id="@+id/from_name"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:textSize="18dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="left|center_vertical"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- From address -->
|
||||
<TextView
|
||||
android:id="@+id/from_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:paddingRight="6dip"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Addresses, timestamp -->
|
||||
<Button
|
||||
android:id="@+id/show_details"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dip"
|
||||
android:layout_below="@id/header_background"
|
||||
android:layout_toLeftOf="@id/header_background_fold"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/message_view_show_details"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_ternary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
|
||||
<!-- From address -->
|
||||
<TextView
|
||||
android:id="@+id/from_address"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignLeft="@id/presence"
|
||||
android:layout_below="@id/presence"
|
||||
android:layout_toLeftOf="@id/forward_reply_buttons"
|
||||
android:layout_marginTop="2dip"
|
||||
android:layout_marginBottom="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:paddingRight="6dip"
|
||||
/>
|
||||
|
||||
<!-- To: and timestamp -->
|
||||
<TextView
|
||||
android:text="@string/message_view_show_details"
|
||||
android:id="@+id/datetime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/from_address"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:layout_height="40dip"
|
||||
android:layout_below="@id/header_background"
|
||||
android:layout_toLeftOf="@id/show_details"
|
||||
android:layout_marginRight="48dip"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:textColor="@color/text_ternary_color"
|
||||
android:singleLine="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/to_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/datetime"
|
||||
android:layout_alignLeft="@id/from_address"
|
||||
android:layout_marginRight="4dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:text="@string/message_compose_to_label"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/to"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@id/datetime"
|
||||
android:layout_toRightOf="@id/to_label"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
/>
|
||||
|
||||
<!-- Cc -->
|
||||
<LinearLayout
|
||||
android:id="@+id/cc_container"
|
||||
android:id="@+id/addresses"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/to_label"
|
||||
android:layout_alignLeft="@id/to_label"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:text="@string/message_compose_cc_label"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/cc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Bcc -->
|
||||
<LinearLayout
|
||||
android:id="@+id/bcc_container"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/cc_container"
|
||||
android:layout_alignLeft="@id/to_label"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:text="@string/message_compose_bcc_label"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/bcc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
</LinearLayout>
|
||||
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"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:id="@+id/below_header_divider"
|
||||
android:id="@+id/below_address_divider"
|
||||
android:layout_width="0dip"
|
||||
android:layout_below="@id/bcc_container"
|
||||
android:layout_alignLeft="@id/bcc_container"
|
||||
android:layout_alignRight="@id/subject"
|
||||
android:layout_marginTop="8dip"
|
||||
android:layout_marginBottom="2dip"
|
||||
android:layout_below="@id/show_details"
|
||||
android:layout_alignLeft="@id/addresses"
|
||||
android:layout_alignRight="@id/show_details"
|
||||
style="@style/message_view_horizontal_divider"
|
||||
/>
|
||||
|
||||
@ -291,60 +264,87 @@
|
||||
<LinearLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:layout_below="@id/below_header_divider"
|
||||
android:layout_alignLeft="@id/below_header_divider"
|
||||
android:layout_alignRight="@id/below_header_divider"
|
||||
android:layout_below="@id/below_address_divider"
|
||||
android:layout_alignLeft="@id/badge"
|
||||
android:layout_alignRight="@id/header_background"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<!-- Tabs -->
|
||||
<!-- Tabs + divider -->
|
||||
<!-- Can't use a RelativeLayout, because tabs can be GONE -->
|
||||
<LinearLayout
|
||||
android:id="@+id/message_tabs_section"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="6dip"
|
||||
android:paddingRight="6dip"
|
||||
android:divider="?android:attr/dividerHorizontal"
|
||||
android:showDividers="beginning|middle|end"
|
||||
android:dividerPadding="8dip"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/show_message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/message_view_show_message_action"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_invite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/message_view_show_invite_action"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_attachments"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<!-- filler -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dip"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<Button
|
||||
android:id="@+id/show_message"
|
||||
android:layout_width="128dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/message_view_show_message_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_invite"
|
||||
android:layout_width="128dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/message_view_show_invite_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_attachments"
|
||||
android:layout_width="128dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
/>
|
||||
<!-- filler -->
|
||||
<View
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_pictures"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_show_pictures_action"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_ternary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<View
|
||||
android:layout_width="48dip"
|
||||
android:layout_height="0dip"
|
||||
/>
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/show_pictures"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/message_view_show_pictures_action"
|
||||
style="@android:style/Widget.Holo.Light.Tab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginBottom="16dip"
|
||||
style="@style/message_view_horizontal_divider"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
@ -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"
|
||||
/>
|
||||
</ScrollView>
|
||||
|
||||
|
139
res/layout-xlarge/message_view_invitation.xml
Normal file
139
res/layout-xlarge/message_view_invitation.xml
Normal file
@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<!-- xlarge -->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/invite_section"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/message_view_info_back_color"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
style="@style/message_view_horizontal_divider"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dip"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<!-- STOPSHIP Put icon here -->
|
||||
<ImageView
|
||||
android:layout_width="64dip"
|
||||
android:layout_height="64dip"
|
||||
android:layout_weight="0"
|
||||
android:src="@null"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_width="200dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="64dip"
|
||||
android:orientation="horizontal"
|
||||
android:divider="?android:attr/dividerVertical"
|
||||
android:showDividers="middle"
|
||||
android:dividerPadding="16dip"
|
||||
>
|
||||
<RelativeLayout
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
>
|
||||
<CheckBox
|
||||
android:id="@+id/accept"
|
||||
android:layout_width="104dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="32dip"
|
||||
android:text="@string/message_view_invite_accept"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
<CheckBox
|
||||
android:id="@+id/maybe"
|
||||
android:layout_width="104dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@id/accept"
|
||||
android:layout_marginLeft="24dip"
|
||||
android:text="@string/message_view_invite_maybe"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
<CheckBox
|
||||
android:id="@+id/decline"
|
||||
android:layout_width="104dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_toRightOf="@id/maybe"
|
||||
android:layout_marginLeft="24dip"
|
||||
android:text="@string/message_view_invite_decline"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
/>
|
||||
|
||||
<!-- "Going?" -->
|
||||
<TextView
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_above="@id/accept"
|
||||
android:layout_marginLeft="32dip"
|
||||
android:layout_marginRight="32dip"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/message_view_invite_text"
|
||||
android:textSize="18dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:gravity="left|bottom"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
||||
<Button
|
||||
android:id="@+id/invite_link"
|
||||
android:layout_width="192dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dip"
|
||||
android:layout_marginRight="16dip"
|
||||
style="@android:style/Widget.Holo.Button.Borderless"
|
||||
android:padding="0dip"
|
||||
android:text="@string/message_view_invite_view"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_primary_color"
|
||||
android:textStyle="bold"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
style="@style/message_view_horizontal_divider"
|
||||
/>
|
||||
</LinearLayout>
|
@ -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.
|
||||
-->
|
||||
|
||||
<!-- Non-xlarge -->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
|
98
res/layout/message_view_details.xml
Normal file
98
res/layout/message_view_details.xml
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<TableLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:stretchColumns="2"
|
||||
android:shrinkColumns="2"
|
||||
>
|
||||
<TableRow
|
||||
android:id="@+id/date_row"
|
||||
>
|
||||
<TextView
|
||||
android:layout_column="1"
|
||||
android:text="@string/message_view_date_label"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/date"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:singleLine="false"
|
||||
/>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:id="@+id/to_row"
|
||||
>
|
||||
<TextView
|
||||
android:layout_column="1"
|
||||
android:text="@string/message_view_to_label"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/to"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
/>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:id="@+id/cc_row"
|
||||
>
|
||||
<TextView
|
||||
android:layout_column="1"
|
||||
android:text="@string/message_view_cc_label"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/cc"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
/>
|
||||
</TableRow>
|
||||
<TableRow
|
||||
android:id="@+id/bcc_row"
|
||||
>
|
||||
<TextView
|
||||
android:layout_column="1"
|
||||
android:text="@string/message_view_bcc_label"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/bcc"
|
||||
android:padding="8dip"
|
||||
android:textSize="14dip"
|
||||
android:textColor="@color/text_secondary_color"
|
||||
/>
|
||||
</TableRow>
|
||||
</TableLayout>
|
@ -46,7 +46,7 @@
|
||||
/>
|
||||
<ImageView
|
||||
android:id="@+id/presence"
|
||||
android:src="@drawable/presence_inactive"
|
||||
android:src="@android:drawable/presence_offline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dip"
|
||||
@ -116,71 +116,17 @@
|
||||
android:layout_marginLeft="4dip"
|
||||
android:singleLine="true" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<TextView
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_view_to_label" />
|
||||
<TextView
|
||||
android:id="@+id/to"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1.0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="none" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/cc_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<TextView
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_view_cc_label" />
|
||||
<TextView
|
||||
android:id="@+id/cc"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1.0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="none" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/bcc_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
<TextView
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/message_view_bcc_label" />
|
||||
<TextView
|
||||
android:id="@+id/bcc"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1.0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="none" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/addresses"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1.0"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:singleLine="false"
|
||||
android:ellipsize="none" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
@ -14,6 +14,8 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!-- Non-xlarge -->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/invite_section"
|
||||
@ -84,7 +86,7 @@
|
||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
<CheckBox
|
||||
android:id="@+id/accept"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -98,7 +100,7 @@
|
||||
android:focusable="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
<CheckBox
|
||||
android:id="@+id/maybe"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -112,7 +114,7 @@
|
||||
android:focusable="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
<CheckBox
|
||||
android:id="@+id/decline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -32,6 +32,7 @@
|
||||
<!-- Standard text colors -->
|
||||
<color name="text_primary_color">#ffffff</color>
|
||||
<color name="text_secondary_color">#666666</color>
|
||||
<color name="text_ternary_color">#888888</color>
|
||||
|
||||
<!-- STOPSHIP Use same color as EditText tray? -->
|
||||
<color name="divider_color">#ff808080</color>
|
||||
@ -57,4 +58,6 @@
|
||||
<color name="widget_unread_count_color">#4d4d4d</color>
|
||||
<color name="widget_default_text_color">#000000</color>
|
||||
<color name="widget_light_text_color">#666666</color>
|
||||
|
||||
<color name="message_view_info_back_color">#deecfa</color>
|
||||
</resources>
|
||||
|
@ -111,6 +111,8 @@
|
||||
<string name="add_cc_bcc_action">+ Cc/Bcc</string>
|
||||
<!-- Menu item -->
|
||||
<string name="add_attachment_action">Add attachment</string>
|
||||
<!-- Generic button [CHAR LIMIT=16] -->
|
||||
<string name="close_action">Close</string>
|
||||
<!-- Menu item (debug screen) -->
|
||||
<string name="dump_settings_action">Dump settings</string>
|
||||
<!-- Appears in choose attachment dialog title -->
|
||||
@ -300,6 +302,8 @@
|
||||
<!-- Label for CC field in read message view -->
|
||||
<string name="message_view_cc_label">Cc:</string>
|
||||
<string name="message_view_bcc_label">Bcc:</string>
|
||||
<!-- Label for the date field. [CHAR LIMIT=20]-->
|
||||
<string name="message_view_date_label">Date:</string>
|
||||
<!-- Button name to view an attachment (in another activity) [CHAR LIMIT=10]-->
|
||||
<string name="message_view_attachment_view_action">View</string>
|
||||
<!-- Button name, to load an attachment from the mail server [CHAR LIMIT=10]-->
|
||||
@ -351,6 +355,10 @@ save attachment.</string>
|
||||
<!-- Toast shown following a meeting invite reply, declined -->
|
||||
<string name="message_view_invite_toast_no">You have declined this invitation</string>
|
||||
<!--Confirmation dialog title shown when user tries to delete messages. [CHAR LIMIT=16] -->
|
||||
<!-- Link label to show to/cc/bcc of the curent message [CHAR LIMIT=32] -->
|
||||
<string name="message_view_show_details">Show details</string>
|
||||
<!-- Title of the dialog box to show to/cc/bcc of the message. [CHAR LIMIT=32] -->
|
||||
<string name="message_view_message_details_dialog_title">Message Details</string>
|
||||
|
||||
<!-- Title of the EML viewer activity. [CHAR LIMIT=32] -->
|
||||
<string name="eml_view_title">Viewing
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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<ContactStatusLoader.Result> {
|
||||
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[] {
|
||||
|
@ -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()) {
|
||||
|
@ -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<Void, Void, Void>() {
|
||||
@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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This class represent email address.
|
||||
*
|
||||
*
|
||||
* RFC822 email address may have following format.
|
||||
* "name" <address> (comment)
|
||||
* "name" <address>
|
||||
@ -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));
|
||||
|
@ -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}.
|
||||
*/
|
||||
|
@ -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, "
|
||||
+ "<noname2@dom2.com>, "
|
||||
+ "simple name <address3@dom3.org>, "
|
||||
@ -39,19 +39,21 @@ public class AddressUnitTests extends AndroidTestCase {
|
||||
+ "\u65E5\u672C\u8A9E <address6@co.jp>,"
|
||||
+ "\"\u65E5\u672C\u8A9E\" <address7@co.jp>,"
|
||||
+ "\uD834\uDF01\uD834\uDF46 <address8@ne.jp>,"
|
||||
+ "\"\uD834\uDF01\uD834\uDF46\" <address9@ne.jp>";
|
||||
private static final int MULTI_ADDRESSES_COUNT = 9;
|
||||
+ "\"\uD834\uDF01\uD834\uDF46\" <address9@ne.jp>,"
|
||||
+ "noname@dom.com <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 = "<user2@dom2.com>";
|
||||
|
||||
|
||||
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 <address1@dom1.net>, " +
|
||||
"\"name,2\" <address2@dom2.org>");
|
||||
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 <address1@dom1.jp>, " +
|
||||
"\"\u3042\u3044\u3046,\u3048\u304A\" <address2@dom2.jp>");
|
||||
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 <address1@dom1.net>, " +
|
||||
"\"\uD834\uDF01\uD834\uDF46,\uD834\uDF22\" <address2@dom2.com>");
|
||||
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\" <address4@dom4.org>", addresses[3].toString());
|
||||
assertEquals("quoted name", "\"big \"G\"\" <bigG@dom5.net>", addresses[4].toString());
|
||||
assertEquals("utf-16 name", "\u65E5\u672C\u8A9E <address6@co.jp>",
|
||||
addresses[5].toString());
|
||||
addresses[5].toString());
|
||||
assertEquals("utf-16 quoted name", "\u65E5\u672C\u8A9E <address7@co.jp>",
|
||||
addresses[6].toString());
|
||||
addresses[6].toString());
|
||||
assertEquals("utf-32 name", "\uD834\uDF01\uD834\uDF46 <address8@ne.jp>",
|
||||
addresses[7].toString());
|
||||
addresses[7].toString());
|
||||
assertEquals("utf-32 quoted name", "\uD834\uDF01\uD834\uDF46 <address9@ne.jp>",
|
||||
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 <address3@dom3.org>,"
|
||||
@ -379,7 +382,8 @@ public class AddressUnitTests extends AndroidTestCase {
|
||||
+ "\u65E5\u672C\u8A9E <address6@co.jp>,"
|
||||
+ "\u65E5\u672C\u8A9E <address7@co.jp>,"
|
||||
+ "\uD834\uDF01\uD834\uDF46 <address8@ne.jp>,"
|
||||
+ "\uD834\uDF01\uD834\uDF46 <address9@ne.jp>",
|
||||
+ "\uD834\uDF01\uD834\uDF46 <address9@ne.jp>,"
|
||||
+ "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("<address6@co.jp>", "\"\u65E5\u672C\u8A9E\"");
|
||||
Address utf32Name = new Address("<address8@ne.jp>", "\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\" <address4@dom4.org>", dquoteName.toHeader());
|
||||
assertEquals("quoted name", "\"big \\\"G\\\"\" <bigG@dom5.net>", quotedName.toHeader());
|
||||
assertEquals("utf-16 name", "=?UTF-8?B?5pel5pys6Kqe?= <address6@co.jp>",
|
||||
utf16Name.toHeader());
|
||||
utf16Name.toHeader());
|
||||
assertEquals("utf-32 name", "=?UTF-8?B?8J2MgfCdjYY=?= <address8@ne.jp>",
|
||||
utf32Name.toHeader());
|
||||
utf32Name.toHeader());
|
||||
assertEquals("name == address", "\"address@dom.org\" <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("<address6@co.jp>", "\"\u65E5\u672C\u8A9E\"");
|
||||
Address utf32Name = new Address("<address8@ne.jp>", "\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=?= <address8@ne.jp>",
|
||||
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(""));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user