Merge "Use overridden method for finding item position" into jb-ub-mail
diff --git a/res/layout/compose.xml b/res/layout/compose.xml
index fce9d5d..62bc081 100644
--- a/res/layout/compose.xml
+++ b/res/layout/compose.xml
@@ -59,6 +59,9 @@
<include layout="@layout/compose_subject"/>
</LinearLayout>
+ <!-- Body -->
+ <include layout="@layout/compose_body"/>
+
<!-- Attachments -->
<com.android.mail.compose.AttachmentsView android:id="@+id/attachments"
android:layout_height="wrap_content"
@@ -69,11 +72,10 @@
android:paddingRight="5dip"
android:paddingBottom="0dip"
android:paddingLeft="5dip"
- android:visibility="gone">
+ android:visibility="gone"
+ android:focusable="true">
<include layout="@layout/compose_attachments" />
</com.android.mail.compose.AttachmentsView>
- <!-- Body -->
- <include layout="@layout/compose_body"/>
<!-- Quoted text -->
<com.android.mail.compose.QuotedTextView android:id="@+id/quoted_text_view"
diff --git a/res/layout/compose_attachment_tile.xml b/res/layout/compose_attachment_tile.xml
index 66030c8..8f2538d 100644
--- a/res/layout/compose_attachment_tile.xml
+++ b/res/layout/compose_attachment_tile.xml
@@ -20,7 +20,9 @@
android:id="@+id/attachment_tile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/attachment_bg_holo">
+ android:background="@drawable/attachment_bg_holo"
+ android:focusable="true"
+ android:focusableInTouchMode="true">
<ImageView
android:id="@+id/attachment_tile_image"
diff --git a/res/layout/compose_attachments.xml b/res/layout/compose_attachments.xml
index 4293ee3..d778b16 100644
--- a/res/layout/compose_attachments.xml
+++ b/res/layout/compose_attachments.xml
@@ -17,60 +17,6 @@
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
- <GridLayout
- android:id="@+id/attachment_collapse_view"
- android:layout_width="match_parent"
- android:layout_height="48dip"
- android:columnCount="2"
- android:orientation="horizontal"
- android:rowCount="2"
- android:visibility="visible" >
-
- <TextView
- android:id="@+id/attachment_collapse_text"
- android:layout_width="0dip"
- android:layout_height="wrap_content"
- android:layout_column="0"
- android:layout_gravity="fill_horizontal|center_vertical"
- android:layout_marginLeft="8dip"
- android:layout_row="0"
- android:ellipsize="end"
- android:singleLine="true"
- android:textAllCaps="true"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="@color/conv_header_text_light" />
-
- <ImageView
- android:id="@+id/attachment_collapse_caret"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_column="1"
- android:layout_gravity="center_vertical"
- android:layout_marginRight="8dip"
- android:layout_row="0"
- android:src="@drawable/ic_menu_expander_minimized_holo_light" />
-
- <View
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:layout_column="0"
- android:layout_columnSpan="2"
- android:layout_gravity="fill"
- android:layout_row="0"
- android:layout_rowSpan="2"
- android:background="?android:attr/selectableItemBackground" />
-
- <View
- android:layout_width="0dip"
- android:layout_height="1dip"
- android:layout_column="0"
- android:layout_columnSpan="2"
- android:layout_gravity="fill_horizontal"
- android:layout_row="1"
- android:layout_rowSpan="1"
- android:background="@color/compose_attachment_title_background_color" />
- </GridLayout>
-
<com.android.mail.ui.AttachmentTileGrid
android:id="@+id/attachment_tile_grid"
android:layout_width="match_parent"
diff --git a/res/layout/conversation_message_upper_header_text.xml b/res/layout/conversation_message_upper_header_text.xml
index 4b57cd7..c044cb5 100644
--- a/res/layout/conversation_message_upper_header_text.xml
+++ b/res/layout/conversation_message_upper_header_text.xml
@@ -34,7 +34,7 @@
android:layout_alignParentRight="true"
android:visibility="gone"
android:minHeight="24dp"
- android:gravity="bottom"
+ android:layout_marginTop="4dp"
android:lines="1"
style="@style/MessageHeaderExtraSmallStyle" />
<ImageView
@@ -42,7 +42,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/upper_date"
- android:layout_marginTop="4dp"
+ android:layout_marginTop="2dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:src="@drawable/ic_attachment_holo_light" />
@@ -52,9 +52,7 @@
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/attachment"
android:layout_alignParentLeft="true"
- android:layout_alignBaseline="@id/upper_date"
style="@style/MessageSenderNameStyle"
- android:layout_marginTop="0dip"
android:singleLine="true" />
<ImageView
android:id="@+id/presence"
diff --git a/res/layout/quoted_text.xml b/res/layout/quoted_text.xml
index aab3f3a..5f8e78f 100644
--- a/res/layout/quoted_text.xml
+++ b/res/layout/quoted_text.xml
@@ -20,9 +20,19 @@
android:layout_height="wrap_content"
android:layout_width="match_parent">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="2dip"
+ android:background="#babebe"
+ android:id="@+id/upper_quotedtext_divider_bar"
+ android:visibility="gone" />
+
<LinearLayout android:layout_width="match_parent"
android:layout_height="48dip"
- android:id="@+id/quoted_text_button_bar">
+ android:id="@+id/quoted_text_button_bar"
+ android:layout_below="@id/upper_quotedtext_divider_bar"
+ android:layout_alignWithParentIfMissing="true"
+ android:layout_alignParentTop="true">
<RelativeLayout android:layout_width="0dip"
android:layout_weight="1"
@@ -65,7 +75,9 @@
android:textAllCaps="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@null"/>
+ android:background="@null"
+ android:focusable="true"
+ android:focusableInTouchMode="true"/>
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 633a9c1..1015738 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -50,9 +50,9 @@
<!-- Compose screen button. Add an attachment to this message [CHAR LIMIT=20] -->
<string name="add_file_attachment">Attach file</string>
<!-- Compose screen button. Add a photo attachment to this message [CHAR LIMIT=20] -->
- <string name="add_photo_attachment">Attach Picture</string>
+ <string name="add_photo_attachment">Attach picture</string>
<!-- Compose screen button. Add a video attachment to this message [CHAR LIMIT=20] -->
- <string name="add_video_attachment">Attach Video</string>
+ <string name="add_video_attachment">Attach video</string>
<!-- Button name: save this message as draft [CHAR LIMIT=25]-->
<string name="save_draft">Save draft</string>
<!-- Button name: discard this message [CHAR LIMIT=15] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 77c5ee2..5cbd057 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -268,7 +268,6 @@
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/message_sender_name</item>
- <item name="android:layout_marginTop">4dip</item>
</style>
<style name="MessageSenderEmailStyle">
diff --git a/src/com/android/mail/compose/AttachmentsView.java b/src/com/android/mail/compose/AttachmentsView.java
index 8b2e01b..9c0cb75 100644
--- a/src/com/android/mail/compose/AttachmentsView.java
+++ b/src/com/android/mail/compose/AttachmentsView.java
@@ -15,11 +15,8 @@
*/
package com.android.mail.compose;
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
@@ -28,23 +25,17 @@
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
-import android.widget.GridLayout;
-import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.TextView;
import com.android.mail.R;
import com.android.mail.providers.Account;
import com.android.mail.providers.Attachment;
-import com.android.mail.providers.Message;
import com.android.mail.ui.AttachmentTile;
import com.android.mail.ui.AttachmentTileGrid;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
-import com.android.mail.utils.Utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
@@ -55,22 +46,13 @@
/*
* View for displaying attachments in the compose screen.
*/
-class AttachmentsView extends LinearLayout implements OnClickListener, TransitionListener {
+class AttachmentsView extends LinearLayout {
private static final String LOG_TAG = LogTag.getLogTag();
- private final Resources mResources;
-
private ArrayList<Attachment> mAttachments;
- private AttachmentDeletedListener mChangeListener;
+ private AttachmentAddedOrDeletedListener mChangeListener;
private AttachmentTileGrid mTileGrid;
private LinearLayout mAttachmentLayout;
- private GridLayout mCollapseLayout;
- private TextView mCollapseText;
- private ImageView mCollapseCaret;
- private LayoutTransition mComposeLayoutTransition;
-
- private boolean mIsExpanded;
- private long mChangingDelay;
public AttachmentsView(Context context) {
this(context, null);
@@ -79,7 +61,6 @@
public AttachmentsView(Context context, AttributeSet attrs) {
super(context, attrs);
mAttachments = Lists.newArrayList();
- mResources = context.getResources();
}
@Override
@@ -88,37 +69,11 @@
mTileGrid = (AttachmentTileGrid) findViewById(R.id.attachment_tile_grid);
mAttachmentLayout = (LinearLayout) findViewById(R.id.attachment_bar_list);
- mCollapseLayout = (GridLayout) findViewById(R.id.attachment_collapse_view);
- mCollapseText = (TextView) findViewById(R.id.attachment_collapse_text);
- mCollapseCaret = (ImageView) findViewById(R.id.attachment_collapse_caret);
-
- mCollapseLayout.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View view) {
- switch (view.getId()) {
- case R.id.attachment_collapse_view:
- if (mIsExpanded) {
- collapseView();
- mComposeLayoutTransition.setStartDelay(
- LayoutTransition.CHANGING, mChangingDelay);
- } else {
- expandView();
- mComposeLayoutTransition.setStartDelay(LayoutTransition.CHANGING, 0l);
- }
- if (Utils.isRunningJellybeanOrLater()) {
- mComposeLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
- }
- break;
- }
}
public void expandView() {
mTileGrid.setVisibility(VISIBLE);
mAttachmentLayout.setVisibility(VISIBLE);
- setupCollapsibleView(false);
- mIsExpanded = true;
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
@@ -127,38 +82,11 @@
}
}
- public void collapseView() {
- mTileGrid.setVisibility(GONE);
- mAttachmentLayout.setVisibility(GONE);
-
- // If there are some attachments, show the preview
- if (!mAttachments.isEmpty()) {
- setupCollapsibleView(true);
- mCollapseLayout.setVisibility(VISIBLE);
- }
-
- mIsExpanded = false;
- }
-
- private void setupCollapsibleView(boolean isCollapsed) {
- // setup text
- final int numAttachments = mAttachments.size();
- final String attachmentText = mResources.getQuantityString(
- R.plurals.number_of_attachments, numAttachments, numAttachments);
- mCollapseText.setText(attachmentText);
-
- if (isCollapsed) {
- mCollapseCaret.setImageResource(R.drawable.ic_menu_expander_minimized_holo_light);
- } else {
- mCollapseCaret.setImageResource(R.drawable.ic_menu_expander_maximized_holo_light);
- }
- }
-
/**
* Set a listener for changes to the attachments.
* @param listener
*/
- public void setAttachmentChangesListener(AttachmentDeletedListener listener) {
+ public void setAttachmentChangesListener(AttachmentAddedOrDeletedListener listener) {
mChangeListener = listener;
}
@@ -203,57 +131,19 @@
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
}
+ if (mChangeListener != null) {
+ mChangeListener.onAttachmentAdded();
+ }
}
@VisibleForTesting
protected void deleteAttachment(final View attachmentView,
final Attachment attachment) {
- if (Utils.isRunningJellybeanOrLater()) {
- mComposeLayoutTransition.enableTransitionType(LayoutTransition.CHANGING);
- }
- mComposeLayoutTransition.setStartDelay(
- LayoutTransition.CHANGING, mChangingDelay);
-
- final LayoutTransition transition = getLayoutTransition();
- if (Utils.isRunningJellybeanOrLater()) {
- transition.enableTransitionType(LayoutTransition.CHANGING);
- }
- transition.setStartDelay(LayoutTransition.CHANGING, mChangingDelay);
- transition.addTransitionListener(this);
-
mAttachments.remove(attachment);
((ViewGroup) attachmentView.getParent()).removeView(attachmentView);
if (mChangeListener != null) {
mChangeListener.onAttachmentDeleted();
}
- if (mAttachments.size() == 0) {
- setVisibility(View.GONE);
- collapseView();
- } else {
- setupCollapsibleView(true);
- }
- }
-
- public void setComposeLayoutTransition(LayoutTransition transition) {
- mComposeLayoutTransition = transition;
- mComposeLayoutTransition.addTransitionListener(this);
- mChangingDelay =
- mComposeLayoutTransition.getDuration(LayoutTransition.DISAPPEARING);
- }
-
- @Override
- public void startTransition(LayoutTransition transition, ViewGroup container, View view,
- int transitionType) {
- /* Do nothing */
- }
-
- @Override
- public void endTransition(LayoutTransition transition, ViewGroup container, View view,
- int transitionType) {
- if (Utils.isRunningJellybeanOrLater()) {
- transition.disableTransitionType(LayoutTransition.CHANGING);
- }
- transition.setStartDelay(LayoutTransition.CHANGING, 0l);
}
/**
@@ -272,7 +162,6 @@
mTileGrid.removeAllViews();
mAttachmentLayout.removeAllViews();
setVisibility(GONE);
- collapseView();
}
/**
@@ -287,11 +176,13 @@
}
/**
- * Interface to implement to be notified about changes to the attachments.
- *
+ * Interface to implement to be notified about changes to the attachments
+ * explicitly made by the user.
*/
- public interface AttachmentDeletedListener {
+ public interface AttachmentAddedOrDeletedListener {
public void onAttachmentDeleted();
+
+ public void onAttachmentAdded();
}
/**
@@ -453,6 +344,10 @@
return result;
}
+ public void focusLastAttachment() {
+ mTileGrid.getChildAt(mTileGrid.getChildCount() - 1).requestFocus();
+ }
+
/**
* Class containing information about failures when adding attachments.
*/
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index 1031917..144fd5f 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -70,7 +70,7 @@
import com.android.common.Rfc822Validator;
import com.android.ex.chips.RecipientEditTextView;
import com.android.mail.R;
-import com.android.mail.compose.AttachmentsView.AttachmentDeletedListener;
+import com.android.mail.compose.AttachmentsView.AttachmentAddedOrDeletedListener;
import com.android.mail.compose.AttachmentsView.AttachmentFailureException;
import com.android.mail.compose.FromAddressSpinner.OnAccountChangedListener;
import com.android.mail.compose.QuotedTextView.RespondInlineListener;
@@ -113,7 +113,7 @@
public class ComposeActivity extends Activity implements OnClickListener, OnNavigationListener,
RespondInlineListener, DialogInterface.OnClickListener, TextWatcher,
- AttachmentDeletedListener, OnAccountChangedListener, LoaderManager.LoaderCallbacks<Cursor>,
+ AttachmentAddedOrDeletedListener, OnAccountChangedListener, LoaderManager.LoaderCallbacks<Cursor>,
TextView.OnEditorActionListener {
// Identifiers for which type of composition this is
static final int COMPOSE = -1;
@@ -490,6 +490,7 @@
private void updateHideOrShowQuotedText(boolean showQuotedText) {
mQuotedTextView.updateCheckedState(showQuotedText);
+ mQuotedTextView.setUpperDividerVisible(mAttachmentsView.getAttachments().size() > 0);
}
private void setFocus(int action) {
@@ -881,9 +882,6 @@
if (mVideoAttachmentsButton != null) {
mVideoAttachmentsButton.setOnClickListener(this);
}
- LayoutTransition transition =
- ((ViewGroup) findViewById(R.id.content)).getLayoutTransition();
- mAttachmentsView.setComposeLayoutTransition(transition);
mTo = (RecipientEditTextView) findViewById(R.id.to);
mCc = (RecipientEditTextView) findViewById(R.id.cc);
mBcc = (RecipientEditTextView) findViewById(R.id.bcc);
@@ -2512,6 +2510,8 @@
@Override
public void onRespondInline(String text) {
appendToBody(text, false);
+ mQuotedTextView.setUpperDividerVisible(false);
+ mTo.requestFocus();
}
/**
@@ -2676,9 +2676,17 @@
@Override
public void onAttachmentDeleted() {
mAttachmentsChanged = true;
+ // If we are showing any attachments, make sure we have an upper
+ // divider.
+ mQuotedTextView.setUpperDividerVisible(mAttachmentsView.getAttachments().size() > 0);
updateSaveUi();
}
+ @Override
+ public void onAttachmentAdded() {
+ mQuotedTextView.setUpperDividerVisible(mAttachmentsView.getAttachments().size() > 0);
+ mAttachmentsView.focusLastAttachment();
+ }
/**
* This is called any time one of our text fields changes.
diff --git a/src/com/android/mail/compose/QuotedTextView.java b/src/com/android/mail/compose/QuotedTextView.java
index d89263e..433cdb6 100644
--- a/src/com/android/mail/compose/QuotedTextView.java
+++ b/src/com/android/mail/compose/QuotedTextView.java
@@ -343,4 +343,9 @@
String textString = htmlText.toString();
return textString.indexOf(sQuoteBegin);
}
+
+ public void setUpperDividerVisible(boolean visible) {
+ findViewById(R.id.upper_quotedtext_divider_bar).setVisibility(
+ visible ? View.VISIBLE : View.GONE);
+ }
}
diff --git a/src/com/android/mail/ui/MailSpinner.java b/src/com/android/mail/ui/MailSpinner.java
index 789a34a..59d33ed 100644
--- a/src/com/android/mail/ui/MailSpinner.java
+++ b/src/com/android/mail/ui/MailSpinner.java
@@ -88,6 +88,12 @@
mFolderName.setText(mFolder.name);
mFolderCount.setText(Utils.getUnreadCountString(getContext(),
Utils.getFolderUnreadDisplayCount(mFolder)));
+
+ if (mSpinnerAdapter != null) {
+ // Update the spinner with this current folder, as it could change the recent items
+ // that are shown.
+ mSpinnerAdapter.setCurrentFolder(mFolder);
+ }
}
}
diff --git a/src/com/android/mail/ui/RecentFolderList.java b/src/com/android/mail/ui/RecentFolderList.java
index 2aa74e3..c49a0f3 100644
--- a/src/com/android/mail/ui/RecentFolderList.java
+++ b/src/com/android/mail/ui/RecentFolderList.java
@@ -29,11 +29,13 @@
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.LruCache;
import com.android.mail.utils.Utils;
+import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A self-updating list of folder canonical names for the N most recently touched folders, ordered
@@ -52,7 +54,7 @@
private Account mAccount = null;
/** The actual cache: map of folder URIs to folder objects. */
- private final LruCache<String, Folder> mFolderCache;
+ private final LruCache<String, RecentFolderListEntry> mFolderCache;
/**
* We want to show at most five recent folders
*/
@@ -124,7 +126,8 @@
* @param context
*/
public RecentFolderList(Context context) {
- mFolderCache = new LruCache<String, Folder>(MAX_RECENT_FOLDERS + MAX_EXCLUDED_FOLDERS);
+ mFolderCache = new LruCache<String, RecentFolderListEntry>(
+ MAX_RECENT_FOLDERS + MAX_EXCLUDED_FOLDERS);
mContext = context;
}
@@ -166,7 +169,8 @@
// there are duplicates in the cursor.
do {
final Folder folder = new Folder(c);
- mFolderCache.putElement(folder.uri.toString(), folder);
+ final RecentFolderListEntry entry = new RecentFolderListEntry(folder);
+ mFolderCache.putElement(folder.uri.toString(), entry);
LogUtils.v(TAG, "Account %s, Recent: %s", mAccount.name, folder.name);
} while (c.moveToPrevious());
}
@@ -188,7 +192,8 @@
}
}
assert (folder != null);
- mFolderCache.putElement(folder.uri.toString(), folder);
+ final RecentFolderListEntry entry = new RecentFolderListEntry(folder);
+ mFolderCache.putElement(folder.uri.toString(), entry);
new StoreRecent(mAccount, folder).execute();
}
@@ -209,18 +214,23 @@
if (!defaultInbox.equals(Uri.EMPTY)) {
excludedUris.add(defaultInbox);
}
- final List<Folder> recent = new ArrayList<Folder>(mFolderCache.values());
- final ArrayList<Folder> recentFolders = new ArrayList<Folder>();
- for (final Folder f : recent) {
- if (!excludedUris.contains(f.uri)) {
- recentFolders.add(f);
+ final List<RecentFolderListEntry> recent = Lists.newArrayList();
+ recent.addAll(mFolderCache.values());
+ Collections.sort(recent);
+
+ final ArrayList<Folder> recentFolders = Lists.newArrayList();
+ for (final RecentFolderListEntry entry : recent) {
+ if (!excludedUris.contains(entry.mFolder.uri)) {
+ recentFolders.add(entry.mFolder);
}
if (recentFolders.size() == MAX_RECENT_FOLDERS) {
break;
}
}
+
// Sort the values as the very last step.
Collections.sort(recentFolders, ALPHABET_IGNORECASE);
+
return recentFolders;
}
@@ -230,4 +240,25 @@
public void destroy() {
mAccountObserver.unregisterAndDestroy();
}
+
+ private static class RecentFolderListEntry implements Comparable<RecentFolderListEntry> {
+ private static final AtomicInteger SEQUENCE_GENERATOR = new AtomicInteger();
+
+ private final Folder mFolder;
+ private final int mSequence;
+
+ RecentFolderListEntry(Folder folder) {
+ mFolder = folder;
+ mSequence = SEQUENCE_GENERATOR.getAndIncrement();
+ }
+
+ /**
+ * Ensure that RecentFolderListEntry objects with greater sequence number will appear
+ * before objects with lower sequence numbers
+ */
+ @Override
+ public int compareTo(RecentFolderListEntry t) {
+ return t.mSequence - mSequence;
+ }
+ }
}