diff options
author | Andrew Sapperstein <asapperstein@google.com> | 2014-04-20 12:23:57 -0700 |
---|---|---|
committer | Andrew Sapperstein <asapperstein@google.com> | 2014-04-22 15:06:40 -0700 |
commit | 381c322eb30c39f63a2bb82812d63262eb3c1c1c (patch) | |
tree | 9525210ecd37f6b67f36cd0aa3d3e1b3133867da | |
parent | 8aed2ce1cf1d976f8f0e1bd8e1d3b176815987be (diff) | |
download | android_packages_apps_UnifiedEmail-381c322eb30c39f63a2bb82812d63262eb3c1c1c.tar.gz android_packages_apps_UnifiedEmail-381c322eb30c39f63a2bb82812d63262eb3c1c1c.tar.bz2 android_packages_apps_UnifiedEmail-381c322eb30c39f63a2bb82812d63262eb3c1c1c.zip |
Save to drive promo. b/7659807.
Provides a space above the attachment bars to show
some additional content. Default behavior does nothing.
Hooks have been added to allow resizing of the message
footer.
Change-Id: Ib950091d176311bdb06c7c7a466223beb997a7b5
-rw-r--r-- | assets/script.js | 9 | ||||
-rw-r--r-- | res/layout/above_attachment_bar_list_layout.xml | 18 | ||||
-rw-r--r-- | res/layout/conversation_message_footer.xml | 4 | ||||
-rw-r--r-- | src/com/android/mail/browse/AttachmentActionHandler.java | 53 | ||||
-rw-r--r-- | src/com/android/mail/browse/ConversationContainer.java | 1 | ||||
-rw-r--r-- | src/com/android/mail/browse/ConversationViewAdapter.java | 53 | ||||
-rw-r--r-- | src/com/android/mail/browse/EmlMessageViewFragment.java | 6 | ||||
-rw-r--r-- | src/com/android/mail/browse/MessageAttachmentBar.java | 2 | ||||
-rw-r--r-- | src/com/android/mail/browse/MessageFooterView.java | 88 | ||||
-rw-r--r-- | src/com/android/mail/browse/UrlSpan.java | 45 | ||||
-rw-r--r-- | src/com/android/mail/ui/ConversationViewFragment.java | 37 | ||||
-rw-r--r-- | src/com/android/mail/ui/SecureConversationViewController.java | 33 | ||||
-rw-r--r-- | src/com/android/mail/ui/SecureConversationViewFragment.java | 6 | ||||
-rw-r--r-- | src/com/android/mail/utils/StyleUtils.java | 48 |
14 files changed, 378 insertions, 25 deletions
diff --git a/assets/script.js b/assets/script.js index cd3045e03..b096c4b2c 100644 --- a/assets/script.js +++ b/assets/script.js @@ -662,6 +662,15 @@ function setConversationHeaderSpacerHeight(spacerHeight) { function setMessageHeaderSpacerHeight(messageDomId, spacerHeight) { var spacer = document.querySelector("#" + messageDomId + " > .mail-message-header"); + setSpacerHeight(spacer, spacerHeight); +} + +function setMessageFooterSpacerHeight(messageDomId, spacerHeight) { + var spacer = document.querySelector("#" + messageDomId + " > .mail-message-footer"); + setSpacerHeight(spacer, spacerHeight); +} + +function setSpacerHeight(spacer, spacerHeight) { if (!spacer) { console.log("can't set spacer for message with id: " + messageDomId); return; diff --git a/res/layout/above_attachment_bar_list_layout.xml b/res/layout/above_attachment_bar_list_layout.xml new file mode 100644 index 000000000..a0bd285b2 --- /dev/null +++ b/res/layout/above_attachment_bar_list_layout.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 Google Inc. + Licensed to 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. +--> +<merge />
\ No newline at end of file diff --git a/res/layout/conversation_message_footer.xml b/res/layout/conversation_message_footer.xml index a1eefb8bd..55f331069 100644 --- a/res/layout/conversation_message_footer.xml +++ b/res/layout/conversation_message_footer.xml @@ -53,6 +53,10 @@ android:visibility="gone" style="@style/AttachmentMarginStyle" /> + <include + layout="@layout/above_attachment_bar_list_layout" + android:id="@+id/above_attachment_bar_list_layout"/> + <LinearLayout android:id="@+id/attachment_bar_list" android:layout_width="match_parent" diff --git a/src/com/android/mail/browse/AttachmentActionHandler.java b/src/com/android/mail/browse/AttachmentActionHandler.java index 8a72533f5..33f612e09 100644 --- a/src/com/android/mail/browse/AttachmentActionHandler.java +++ b/src/com/android/mail/browse/AttachmentActionHandler.java @@ -29,6 +29,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Handler; import android.os.Parcelable; +import android.view.View; import com.android.mail.providers.Attachment; import com.android.mail.providers.Message; @@ -265,6 +266,37 @@ public class AttachmentActionHandler { sOptionHandler.handleOption1(mContext, mAccount, mMessage, mAttachment, mFragmentManager); } + public static boolean shouldShowAboveBarAttachmentLayout(Context context) { + return (sOptionHandler != null) && + sOptionHandler.shouldShowAboveBarAttachmentLayout(context); + } + + public static void setupAboveBarAttachmentLayout(View view) { + if (sOptionHandler != null) { + sOptionHandler.setupAboveBarAttachmentLayout(view); + } + } + + public static void onOverflowOpened(Context context) { + if(sOptionHandler != null) { + sOptionHandler.onOverflowOpened(context); + } + } + + public static void registerDismissListener(Uri conversationUri, + AboveAttachmentLayoutDismissedListener listener) { + if (sOptionHandler != null) { + sOptionHandler.registerDismissListener(conversationUri, listener); + } + } + + public static void unregisterDismissListeners(Uri conversationUri) { + if(sOptionHandler != null) { + sOptionHandler.unregisterDismissListeners(conversationUri); + } + } + + /** * A default, no-op option class. Override this and set it globally with * {@link AttachmentActionHandler#setOptionHandler(OptionHandler)}.<br> @@ -278,12 +310,31 @@ public class AttachmentActionHandler { return false; } - @SuppressWarnings("unused") public void handleOption1(Context context, String account, Message message, Attachment attachment, FragmentManager fm) { // no-op } + public boolean shouldShowAboveBarAttachmentLayout(Context context) { + return false; + } + + public void setupAboveBarAttachmentLayout(View view) { /* no-op */ } + + public void onOverflowOpened(Context context) { /* no-op */ } + + public void registerDismissListener(Uri conversationUri, + AboveAttachmentLayoutDismissedListener listener) { + // no-op + } + + public void unregisterDismissListeners(Uri conversationUri) { + // no-op + } + } + + public interface AboveAttachmentLayoutDismissedListener { + void onOtherLayoutDismissed(); } } diff --git a/src/com/android/mail/browse/ConversationContainer.java b/src/com/android/mail/browse/ConversationContainer.java index b75dd5ab3..19380eafb 100644 --- a/src/com/android/mail/browse/ConversationContainer.java +++ b/src/com/android/mail/browse/ConversationContainer.java @@ -206,7 +206,6 @@ public class ConversationContainer extends ViewGroup implements ScrollListener { /** * Child views of this container should implement this interface to be notified when they are * being detached. - * */ public interface DetachListener { /** diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java index 08f5cf5bb..1cc729bfb 100644 --- a/src/com/android/mail/browse/ConversationViewAdapter.java +++ b/src/com/android/mail/browse/ConversationViewAdapter.java @@ -32,6 +32,7 @@ import com.android.mail.ContactInfoSource; import com.android.mail.FormattedDateBuilder; import com.android.mail.R; import com.android.mail.browse.ConversationViewHeader.ConversationViewHeaderCallbacks; +import com.android.mail.browse.MessageFooterView.MessageFooterCallbacks; import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks; import com.android.mail.browse.SuperCollapsedBlock.OnClickListener; import com.android.mail.providers.Conversation; @@ -64,6 +65,7 @@ public class ConversationViewAdapter extends BaseAdapter { private final LoaderManager mLoaderManager; private final FragmentManager mFragmentManager; private final MessageHeaderViewCallbacks mMessageCallbacks; + private final MessageFooterCallbacks mFooterCallbacks; private final ContactInfoSource mContactInfoSource; private final ConversationViewHeaderCallbacks mConversationCallbacks; private final OnClickListener mSuperCollapsedListener; @@ -266,15 +268,19 @@ public class ConversationViewAdapter extends BaseAdapter { } } - public class MessageFooterItem extends ConversationOverlayItem { + public static class MessageFooterItem extends ConversationOverlayItem implements + AttachmentActionHandler.AboveAttachmentLayoutDismissedListener { + private final ConversationViewAdapter mAdapter; + /** * A footer can only exist if there is a matching header. Requiring a header allows a * footer to stay in sync with the expanded state of the header. */ - private final MessageHeaderItem mHeaderitem; + private final MessageHeaderItem mHeaderItem; - private MessageFooterItem(MessageHeaderItem item) { - mHeaderitem = item; + private MessageFooterItem(ConversationViewAdapter adapter, MessageHeaderItem item) { + mAdapter = adapter; + mHeaderItem = item; } @Override @@ -286,14 +292,15 @@ public class ConversationViewAdapter extends BaseAdapter { public View createView(Context context, LayoutInflater inflater, ViewGroup parent) { final MessageFooterView v = (MessageFooterView) inflater.inflate( R.layout.conversation_message_footer, parent, false); - v.initialize(mLoaderManager, mFragmentManager, mAccountController); + v.initialize(mAdapter.mLoaderManager, mAdapter.mFragmentManager, + mAdapter.mAccountController, mAdapter.mFooterCallbacks); return v; } @Override public void bindView(View v, boolean measureOnly) { final MessageFooterView attachmentsView = (MessageFooterView) v; - attachmentsView.bind(mHeaderitem, measureOnly); + attachmentsView.bind(mHeaderItem, this, measureOnly); } @Override @@ -303,7 +310,7 @@ public class ConversationViewAdapter extends BaseAdapter { @Override public boolean isExpanded() { - return mHeaderitem.isExpanded(); + return mHeaderItem.isExpanded(); } @Override @@ -317,11 +324,32 @@ public class ConversationViewAdapter extends BaseAdapter { public int getHeight() { // a footer may change height while its view does not exist because it is offscreen // (but the header is onscreen and thus collapsible) - if (!mHeaderitem.isExpanded()) { + if (!mHeaderItem.isExpanded()) { return 0; } return super.getHeight(); } + + public MessageHeaderItem getHeaderItem() { + return mHeaderItem; + } + + @Override + public void onOtherLayoutDismissed() { + final MessageFooterView view = mAdapter.mFooterCallbacks.getViewForItem(this); + + // the item has a view, use the normal path + if (view != null) { + view.collapseAboveBarAttachmentsView(); + return; + } + + // the item is offscreen or otherwise doesn't have a view + // just update the HTML + final int newHeight = mAdapter.mFooterCallbacks.getUpdatedHeight(this); + setHeight(newHeight); + mAdapter.mFooterCallbacks.setMessageSpacerHeight(this, newHeight); + } } public class SuperCollapsedBlockItem extends ConversationOverlayItem { @@ -453,6 +481,7 @@ public class ConversationViewAdapter extends BaseAdapter { ConversationAccountController accountController, LoaderManager loaderManager, MessageHeaderViewCallbacks messageCallbacks, + MessageFooterCallbacks footerCallbacks, ContactInfoSource contactInfoSource, ConversationViewHeaderCallbacks convCallbacks, SuperCollapsedBlock.OnClickListener scbListener, Map<String, Address> addressCache, @@ -463,6 +492,7 @@ public class ConversationViewAdapter extends BaseAdapter { mLoaderManager = loaderManager; mFragmentManager = controllableActivity.getFragmentManager(); mMessageCallbacks = messageCallbacks; + mFooterCallbacks = footerCallbacks; mContactInfoSource = contactInfoSource; mConversationCallbacks = convCallbacks; mSuperCollapsedListener = scbListener; @@ -548,7 +578,7 @@ public class ConversationViewAdapter extends BaseAdapter { } public int addMessageFooter(MessageHeaderItem headerItem) { - return addItem(new MessageFooterItem(headerItem)); + return addItem(new MessageFooterItem(this, headerItem)); } public static MessageHeaderItem newMessageHeaderItem(ConversationViewAdapter adapter, @@ -557,8 +587,9 @@ public class ConversationViewAdapter extends BaseAdapter { return new MessageHeaderItem(adapter, dateBuilder, message, expanded, showImages); } - public MessageFooterItem newMessageFooterItem(MessageHeaderItem headerItem) { - return new MessageFooterItem(headerItem); + public static MessageFooterItem newMessageFooterItem( + ConversationViewAdapter adapter, MessageHeaderItem headerItem) { + return new MessageFooterItem(adapter, headerItem); } public int addSuperCollapsedBlock(int start, int end) { diff --git a/src/com/android/mail/browse/EmlMessageViewFragment.java b/src/com/android/mail/browse/EmlMessageViewFragment.java index 8da260670..eb56bf930 100644 --- a/src/com/android/mail/browse/EmlMessageViewFragment.java +++ b/src/com/android/mail/browse/EmlMessageViewFragment.java @@ -174,6 +174,12 @@ public class EmlMessageViewFragment extends Fragment } @Override + public void onDestroyView() { + super.onDestroyView(); + mViewController.onDestroyView(); + } + + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (Utils.isRunningKitkatOrLater()) { inflater.inflate(R.menu.eml_fragment_menu, menu); diff --git a/src/com/android/mail/browse/MessageAttachmentBar.java b/src/com/android/mail/browse/MessageAttachmentBar.java index fffbb8d12..230e63431 100644 --- a/src/com/android/mail/browse/MessageAttachmentBar.java +++ b/src/com/android/mail/browse/MessageAttachmentBar.java @@ -225,6 +225,8 @@ public class MessageAttachmentBar extends FrameLayout implements OnClickListener menu.findItem(R.id.attachment_extra_option1).setVisible(shouldShowExtraOption1()); mPopup.show(); + + AttachmentActionHandler.onOverflowOpened(getContext()); } } else { // Handles clicking the attachment diff --git a/src/com/android/mail/browse/MessageFooterView.java b/src/com/android/mail/browse/MessageFooterView.java index 07212943c..cfec4e319 100644 --- a/src/com/android/mail/browse/MessageFooterView.java +++ b/src/com/android/mail/browse/MessageFooterView.java @@ -30,6 +30,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; @@ -37,15 +38,18 @@ import com.android.mail.R; import com.android.mail.analytics.Analytics; import com.android.mail.browse.AttachmentLoader.AttachmentCursor; import com.android.mail.browse.ConversationContainer.DetachListener; +import com.android.mail.browse.ConversationViewAdapter.MessageFooterItem; import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; import com.android.mail.providers.Account; import com.android.mail.providers.Attachment; +import com.android.mail.providers.Conversation; import com.android.mail.providers.Message; import com.android.mail.ui.AccountFeedbackActivity; 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.base.Objects; import com.google.common.collect.Lists; @@ -55,6 +59,7 @@ import java.util.List; public class MessageFooterView extends LinearLayout implements DetachListener, LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener { + private MessageFooterItem mMessageFooterItem; private MessageHeaderItem mMessageHeaderItem; private LoaderManager mLoaderManager; private FragmentManager mFragmentManager; @@ -63,6 +68,7 @@ public class MessageFooterView extends LinearLayout implements DetachListener, private TextView mTitleText; private AttachmentTileGrid mAttachmentGrid; private LinearLayout mAttachmentBarList; + private View mAboveAttachmentBarListLayout; private final LayoutInflater mInflater; @@ -72,6 +78,19 @@ public class MessageFooterView extends LinearLayout implements DetachListener, private BidiFormatter mBidiFormatter; + private MessageFooterCallbacks mCallbacks; + + /** + * Callbacks for the MessageFooterView to enable resizing the height. + */ + public interface MessageFooterCallbacks { + void setMessageSpacerHeight(MessageFooterItem item, int newSpacerHeight); + + MessageFooterView getViewForItem(MessageFooterItem item); + + int getUpdatedHeight(MessageFooterItem item); + } + public MessageFooterView(Context context) { this(context, null); } @@ -90,18 +109,21 @@ public class MessageFooterView extends LinearLayout implements DetachListener, mTitleText = (TextView) findViewById(R.id.attachments_header_text); mAttachmentGrid = (AttachmentTileGrid) findViewById(R.id.attachment_tile_grid); mAttachmentBarList = (LinearLayout) findViewById(R.id.attachment_bar_list); + mAboveAttachmentBarListLayout = findViewById(R.id.above_attachment_bar_list_layout); mViewEntireMessagePrompt.setOnClickListener(this); } public void initialize(LoaderManager loaderManager, FragmentManager fragmentManager, - ConversationAccountController accountController) { + ConversationAccountController accountController, MessageFooterCallbacks callbacks) { mLoaderManager = loaderManager; mFragmentManager = fragmentManager; mAccountController = accountController; + mCallbacks = callbacks; } - public void bind(MessageHeaderItem headerItem, boolean measureOnly) { + public void bind( + MessageHeaderItem headerItem, MessageFooterItem footerItem, boolean measureOnly) { // Resets the footer view. This step is only done if the // attachmentsListUri changes so that we don't // repeat the work of layout and measure when @@ -117,12 +139,14 @@ public class MessageFooterView extends LinearLayout implements DetachListener, mTitleText.setVisibility(View.GONE); mAttachmentGrid.setVisibility(View.GONE); mAttachmentBarList.setVisibility(View.GONE); + hideAboveAttachmentBarListLayout(); } // If this MessageFooterView is being bound to a new attachment, we need to unbind with the // old loader final Integer oldAttachmentLoaderId = getAttachmentLoaderId(); + mMessageFooterItem = footerItem; mMessageHeaderItem = headerItem; final Integer attachmentLoaderId = getAttachmentLoaderId(); @@ -152,6 +176,25 @@ public class MessageFooterView extends LinearLayout implements DetachListener, setVisibility(mMessageHeaderItem.isExpanded() ? VISIBLE : GONE); } + private void hideAboveAttachmentBarListLayout() { + if (mAboveAttachmentBarListLayout != null) { + mAboveAttachmentBarListLayout.setVisibility(GONE); + } + } + + private void showAboveAttachmentBarListLayout() { + if (mAboveAttachmentBarListLayout != null) { + final Conversation conversation = mMessageHeaderItem.getMessage().getConversation(); + if (conversation == null) { + hideAboveAttachmentBarListLayout(); + return; + } + AttachmentActionHandler.registerDismissListener(conversation.uri, mMessageFooterItem); + mAboveAttachmentBarListLayout.setVisibility(VISIBLE); + AttachmentActionHandler.setupAboveBarAttachmentLayout(mAboveAttachmentBarListLayout); + } + } + private void renderAttachments(boolean loaderResult) { final List<Attachment> attachments; if (mAttachmentsCursor != null && !mAttachmentsCursor.isClosed()) { @@ -198,8 +241,12 @@ public class MessageFooterView extends LinearLayout implements DetachListener, mTitleText.setVisibility(View.VISIBLE); - renderTiledAttachments(tiledAttachments, loaderResult); - renderBarAttachments(barAttachments, loaderResult); + if (!tiledAttachments.isEmpty()) { + renderTiledAttachments(tiledAttachments, loaderResult); + } + if (!barAttachments.isEmpty()) { + renderBarAttachments(barAttachments, loaderResult); + } } private void renderTiledAttachments(List<Attachment> tiledAttachments, boolean loaderResult) { @@ -213,6 +260,13 @@ public class MessageFooterView extends LinearLayout implements DetachListener, private void renderBarAttachments(List<Attachment> barAttachments, boolean loaderResult) { mAttachmentBarList.setVisibility(View.VISIBLE); + if (!barAttachments.isEmpty() && + AttachmentActionHandler.shouldShowAboveBarAttachmentLayout(getContext())) { + showAboveAttachmentBarListLayout(); + } else { + hideAboveAttachmentBarListLayout(); + } + final Account account = getAccount(); for (Attachment attachment : barAttachments) { final Uri id = attachment.getIdentifierUri(); @@ -242,7 +296,7 @@ public class MessageFooterView extends LinearLayout implements DetachListener, @Override public void onDetachedFromParent() { - // Do nothing + // Do nothing. } @Override @@ -311,4 +365,28 @@ public class MessageFooterView extends LinearLayout implements DetachListener, private Account getAccount() { return mAccountController != null ? mAccountController.getAccount() : null; } + + public void collapseAboveBarAttachmentsView() { + int heightBefore = measureHeight(); + mAboveAttachmentBarListLayout.setVisibility(View.GONE); + updateSpacerHeight(); + } + + private int measureHeight() { + ViewGroup parent = (ViewGroup) getParent(); + if (parent == null) { + LogUtils.e(LOG_TAG, new Error(), "Unable to measure height of detached header"); + return getHeight(); + } + return Utils.measureViewHeight(this, parent); + } + + private void updateSpacerHeight() { + final int h = measureHeight(); + + mMessageFooterItem.setHeight(h); + if (mCallbacks != null) { + mCallbacks.setMessageSpacerHeight(mMessageFooterItem, h); + } + } } diff --git a/src/com/android/mail/browse/UrlSpan.java b/src/com/android/mail/browse/UrlSpan.java new file mode 100644 index 000000000..9e3d17208 --- /dev/null +++ b/src/com/android/mail/browse/UrlSpan.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 Google Inc. + * Licensed to 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.mail.browse; + +import android.text.TextPaint; +import android.text.style.URLSpan; + +/** + * Extension to URLSpan that does not have underlines. + * Stupid URLSpan.<p/> + * + * WARNING: this span will not work if the TextView it uses + * saves and restores its text since TextView can only save + * and restore {@link android.text.ParcelableSpan}s which + * can only be implemented by framework Spans. + */ +public class UrlSpan extends URLSpan { + public UrlSpan(String url) { + super(url); + } + + /** + * Makes the text in the link color and not underlined. + */ + @Override + public void updateDrawState(TextPaint ds) { + ds.setColor(ds.linkColor); + ds.setUnderlineText(false); + } +} diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java index 5d54b94bc..74805d5cf 100644 --- a/src/com/android/mail/ui/ConversationViewFragment.java +++ b/src/com/android/mail/ui/ConversationViewFragment.java @@ -48,6 +48,7 @@ import com.android.mail.FormattedDateBuilder; import com.android.mail.R; import com.android.mail.analytics.Analytics; import com.android.mail.analytics.AnalyticsTimer; +import com.android.mail.browse.AttachmentActionHandler; import com.android.mail.browse.ConversationContainer; import com.android.mail.browse.ConversationContainer.OverlayPosition; import com.android.mail.browse.ConversationMessage; @@ -63,6 +64,7 @@ import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreator; import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreatorHolder; import com.android.mail.browse.MailWebView.ContentSizeChangeListener; import com.android.mail.browse.MessageCursor; +import com.android.mail.browse.MessageFooterView; import com.android.mail.browse.MessageHeaderView; import com.android.mail.browse.ScrollIndicatorsView; import com.android.mail.browse.SuperCollapsedBlock; @@ -94,7 +96,8 @@ import java.util.Set; */ public class ConversationViewFragment extends AbstractConversationViewFragment implements SuperCollapsedBlock.OnClickListener, OnLayoutChangeListener, - MessageHeaderView.MessageHeaderViewCallbacks, WebViewContextMenu.Callbacks { + MessageHeaderView.MessageHeaderViewCallbacks, + MessageFooterView.MessageFooterCallbacks, WebViewContextMenu.Callbacks { private static final String LOG_TAG = LogTag.getLogTag(); public static final String LAYOUT_TAG = "ConvLayout"; @@ -272,7 +275,7 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i final FormattedDateBuilder dateBuilder = new FormattedDateBuilder(context); mAdapter = new ConversationViewAdapter(mActivity, this, - getLoaderManager(), this, getContactInfoSource(), this, + getLoaderManager(), this, this, getContactInfoSource(), this, this, mAddressCache, dateBuilder, mBidiFormatter); mConversationContainer.setOverlayAdapter(mAdapter); @@ -448,6 +451,7 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i public void onDestroyView() { super.onDestroyView(); mConversationContainer.setOverlayAdapter(null); + AttachmentActionHandler.unregisterDismissListeners(mConversation.uri); mAdapter = null; resetLoadWaiting(); // be sure to unregister any active load observer mViewsCreated = false; @@ -886,7 +890,7 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i final MessageHeaderItem header = ConversationViewAdapter.newMessageHeaderItem( mAdapter, mAdapter.getDateBuilder(), msg, false /* expanded */, alwaysShowImages || mViewState.getShouldShowImages(msg)); - final MessageFooterItem footer = mAdapter.newMessageFooterItem(header); + final MessageFooterItem footer = mAdapter.newMessageFooterItem(mAdapter, header); final int headerPx = measureOverlayHeight(header); final int footerPx = measureOverlayHeight(footer); @@ -933,7 +937,7 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i * @param convItem adapter item with data to render and measure * @return height of the rendered view in screen px */ - private int measureOverlayHeight(ConversationOverlayItem convItem) { + public int measureOverlayHeight(ConversationOverlayItem convItem) { final int type = convItem.getType(); final View convertView = mConversationContainer.getScrapView(type); @@ -1633,6 +1637,31 @@ public class ConversationViewFragment extends AbstractConversationViewFragment i mDiff = (expanded ? 1 : -1) * Math.abs(i.getHeight() - heightBefore); } + // START MessageFooterCallbacks + + @Override + public void setMessageSpacerHeight(MessageFooterItem item, int newSpacerHeight) { + mConversationContainer.invalidateSpacerGeometry(); + + // update message HTML spacer height + final int h = mWebView.screenPxToWebPx(newSpacerHeight); + LogUtils.i(LAYOUT_TAG, "setting HTML spacer h=%dwebPx (%dscreenPx)", h, newSpacerHeight); + mWebView.loadUrl(String.format("javascript:setMessageFooterSpacerHeight('%s', %s);", + mTemplates.getMessageDomId(item.getHeaderItem().getMessage()), h)); + } + + @Override + public MessageFooterView getViewForItem(MessageFooterItem item) { + return (MessageFooterView) mConversationContainer.getViewForItem(item); + } + + @Override + public int getUpdatedHeight(MessageFooterItem item) { + return measureOverlayHeight(item); + } + + // END MessageFooterCallbacks + /** * @return {@code true} because either the Print or Print All menu item is shown in GMail */ diff --git a/src/com/android/mail/ui/SecureConversationViewController.java b/src/com/android/mail/ui/SecureConversationViewController.java index 5e10794b6..a0e190e6e 100644 --- a/src/com/android/mail/ui/SecureConversationViewController.java +++ b/src/com/android/mail/ui/SecureConversationViewController.java @@ -29,9 +29,11 @@ import android.webkit.WebSettings; import com.android.mail.FormattedDateBuilder; import com.android.mail.R; +import com.android.mail.browse.AttachmentActionHandler; import com.android.mail.browse.BorderView; import com.android.mail.browse.ConversationMessage; import com.android.mail.browse.ConversationViewAdapter; +import com.android.mail.browse.ConversationViewAdapter.MessageFooterItem; import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem; import com.android.mail.browse.ConversationViewHeader; import com.android.mail.browse.InlineAttachmentViewIntentBuilderCreator; @@ -54,7 +56,8 @@ import com.android.mail.utils.ConversationViewUtils; * is pretty much the rendering logic. */ public class SecureConversationViewController implements - MessageHeaderView.MessageHeaderViewCallbacks, ScrollListener { + MessageHeaderView.MessageHeaderViewCallbacks, ScrollListener, + MessageFooterView.MessageFooterCallbacks { private static final String BEGIN_HTML = "<body style=\"margin: 0 %spx;\"><div style=\"margin: 16px 0; font-size: 80%%\">"; private static final String END_HTML = "</div></body>"; @@ -156,7 +159,7 @@ public class SecureConversationViewController implements mCallbacks.setupMessageHeaderVeiledMatcher(mSnapHeaderView); mMessageFooterView.initialize(fragment.getLoaderManager(), fragment.getFragmentManager(), - mCallbacks.getConversationAccountController()); + mCallbacks.getConversationAccountController(), this); mCallbacks.startMessageLoader(); @@ -167,6 +170,10 @@ public class SecureConversationViewController implements R.dimen.conversation_message_content_margin_side) / r.getDisplayMetrics().density); } + public void onDestroyView() { + AttachmentActionHandler.unregisterDismissListeners(mMessage.conversationUri); + } + @Override public void onNotifierScroll(final int x, final int y) { // We need to decide whether or not to display the snap header. @@ -216,7 +223,8 @@ public class SecureConversationViewController implements if (mMessage.hasAttachments) { mMessageFooterView.setVisibility(View.VISIBLE); - mMessageFooterView.bind(item, false); + mMessageFooterView.bind( + item, ConversationViewAdapter.newMessageFooterItem(null, item), false); } } @@ -288,4 +296,23 @@ public class SecureConversationViewController implements } // End MessageHeaderViewCallbacks implementations + + // START MessageFooterCallbacks + + @Override + public void setMessageSpacerHeight(MessageFooterItem item, int newSpacerHeight) { + // Do nothing. + } + + @Override + public MessageFooterView getViewForItem(MessageFooterItem item) { + return mMessageFooterView; + } + + @Override + public int getUpdatedHeight(MessageFooterItem item) { + return 0; // should never get called since we'll always have a footer view + } + + // END MessageFooterCallbacks } diff --git a/src/com/android/mail/ui/SecureConversationViewFragment.java b/src/com/android/mail/ui/SecureConversationViewFragment.java index f13bb0dbf..d96ff67bc 100644 --- a/src/com/android/mail/ui/SecureConversationViewFragment.java +++ b/src/com/android/mail/ui/SecureConversationViewFragment.java @@ -127,6 +127,12 @@ public class SecureConversationViewFragment extends AbstractConversationViewFrag mViewController.onActivityCreated(savedInstanceState); } + @Override + public void onDestroyView() { + super.onDestroyView(); + mViewController.onDestroyView(); + } + // Start implementations of SecureConversationViewControllerCallbacks @Override diff --git a/src/com/android/mail/utils/StyleUtils.java b/src/com/android/mail/utils/StyleUtils.java new file mode 100644 index 000000000..5a0a38e0c --- /dev/null +++ b/src/com/android/mail/utils/StyleUtils.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 Google Inc. + * Licensed to 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.mail.utils; + +import android.text.Spannable; +import android.text.Spanned; +import android.text.style.URLSpan; +import android.widget.TextView; + +import com.android.mail.browse.UrlSpan; + +/** + * Utility class for styling UI. + */ +public class StyleUtils { + + /** + * Removes any {@link android.text.style.URLSpan}s from the text view + * and replaces them with their non-underline version {@link com.android.mail.browse.UrlSpan}. + */ + public static void stripUnderlines(TextView textView) { + final Spannable spannable = (Spannable) textView.getText(); + final URLSpan[] urls = textView.getUrls(); + + for (URLSpan span : urls) { + final int start = spannable.getSpanStart(span); + final int end = spannable.getSpanEnd(span); + spannable.removeSpan(span); + span = new UrlSpan(span.getURL()); + spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } +} |