MessageListItem.java revision b616c955e2f513efb5f78e37882bac5f15f0a768
1/*
2 * Copyright (C) 2008 Esmertec AG.
3 * Copyright (C) 2008 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.ui;
19
20import java.util.Map;
21import java.util.regex.Matcher;
22import java.util.regex.Pattern;
23
24import android.app.AlertDialog;
25import android.content.Context;
26import android.content.DialogInterface;
27import android.content.Intent;
28import android.content.res.Resources;
29import android.graphics.Bitmap;
30import android.graphics.BitmapFactory;
31import android.graphics.Typeface;
32import android.graphics.Paint.FontMetricsInt;
33import android.graphics.drawable.Drawable;
34import android.net.Uri;
35import android.os.Handler;
36import android.os.Message;
37import android.provider.Browser;
38import android.provider.Telephony.Mms;
39import android.provider.Telephony.Sms;
40import android.telephony.PhoneNumberUtils;
41import android.text.Html;
42import android.text.Spannable;
43import android.text.SpannableStringBuilder;
44import android.text.TextUtils;
45import android.text.method.HideReturnsTransformationMethod;
46import android.text.style.ForegroundColorSpan;
47import android.text.style.LineHeightSpan;
48import android.text.style.StyleSpan;
49import android.text.style.TextAppearanceSpan;
50import android.text.style.URLSpan;
51import android.util.AttributeSet;
52import android.util.DisplayMetrics;
53import android.util.Log;
54import android.view.Gravity;
55import android.view.View;
56import android.view.ViewGroup;
57import android.view.View.OnClickListener;
58import android.widget.ArrayAdapter;
59import android.widget.Button;
60import android.widget.ImageButton;
61import android.widget.ImageView;
62import android.widget.LinearLayout;
63import android.widget.QuickContactBadge;
64import android.widget.RelativeLayout;
65import android.widget.TextView;
66
67import com.android.mms.MmsApp;
68import com.android.mms.R;
69import com.android.mms.data.WorkingMessage;
70import com.android.mms.transaction.Transaction;
71import com.android.mms.transaction.TransactionBundle;
72import com.android.mms.transaction.TransactionService;
73import com.android.mms.util.DownloadManager;
74import com.android.mms.util.SmileyParser;
75import com.google.android.mms.ContentType;
76import com.google.android.mms.pdu.PduHeaders;
77
78/**
79 * This class provides view of a message in the messages list.
80 */
81public class MessageListItem extends LinearLayout implements
82        SlideViewInterface, OnClickListener {
83    public static final String EXTRA_URLS = "com.android.mms.ExtraUrls";
84
85    private static final String TAG = "MessageListItem";
86    private static final StyleSpan STYLE_BOLD = new StyleSpan(Typeface.BOLD);
87
88    static final int MSG_LIST_EDIT_MMS   = 1;
89    static final int MSG_LIST_EDIT_SMS   = 2;
90
91    private View mMsgListItem;
92    private View mMmsView;
93    private ImageView mImageView;
94    private ImageView mLockedIndicator;
95    private ImageView mDeliveredIndicator;
96    private ImageView mDetailsIndicator;
97    private ImageButton mSlideShowButton;
98    private TextView mBodyTextView;
99    private Button mDownloadButton;
100    private TextView mDownloadingLabel;
101    private QuickContactBadge mAvatar;
102    private Handler mHandler;
103    private MessageItem mMessageItem;
104    private String mDefaultCountryIso;
105    private TextView mDateView;
106    private LinearLayout mStatusIcons;
107    private ImageViewDivot mDivit;        // little triangle on the side of the avatar
108
109    public MessageListItem(Context context) {
110        super(context);
111        mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();
112    }
113
114    public MessageListItem(Context context, AttributeSet attrs) {
115        super(context, attrs);
116
117        int color = mContext.getResources().getColor(R.color.timestamp_color);
118        mColorSpan = new ForegroundColorSpan(color);
119        mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();
120    }
121
122    @Override
123    protected void onFinishInflate() {
124        super.onFinishInflate();
125
126        mMsgListItem = findViewById(R.id.msg_list_item);
127        mBodyTextView = (TextView) findViewById(R.id.text_view);
128        mDateView = (TextView) findViewById(R.id.date_view);
129        mLockedIndicator = (ImageView) findViewById(R.id.locked_indicator);
130        mDeliveredIndicator = (ImageView) findViewById(R.id.delivered_indicator);
131        mDetailsIndicator = (ImageView) findViewById(R.id.details_indicator);
132        mAvatar = (QuickContactBadge) findViewById(R.id.avatar);
133        mStatusIcons = (LinearLayout) findViewById(R.id.status_icons);
134        mDivit = (ImageViewDivot) findViewById(R.id.divit);
135    }
136
137    public void bind(MessageListAdapter.AvatarCache avatarCache, MessageItem msgItem) {
138        mMessageItem = msgItem;
139
140        setLongClickable(false);
141
142        switch (msgItem.mMessageType) {
143            case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
144                bindNotifInd(msgItem);
145                break;
146            default:
147                bindCommonMessage(avatarCache, msgItem);
148                break;
149        }
150    }
151
152    public MessageItem getMessageItem() {
153        return mMessageItem;
154    }
155
156    public void setMsgListItemHandler(Handler handler) {
157        mHandler = handler;
158    }
159
160    private void bindNotifInd(final MessageItem msgItem) {
161        hideMmsViewIfNeeded();
162
163        String msgSizeText = mContext.getString(R.string.message_size_label)
164                                + String.valueOf((msgItem.mMessageSize + 1023) / 1024)
165                                + mContext.getString(R.string.kilobyte);
166
167        mBodyTextView.setText(formatMessage(msgItem, msgItem.mContact, null, msgItem.mSubject,
168                                            msgItem.mHighlight, msgItem.mTextContentType));
169
170        mDateView.setText(msgSizeText + " " + msgItem.mTimestamp);
171
172        int state = DownloadManager.getInstance().getState(msgItem.mMessageUri);
173        switch (state) {
174            case DownloadManager.STATE_DOWNLOADING:
175                inflateDownloadControls();
176                mDownloadingLabel.setVisibility(View.VISIBLE);
177                mDownloadButton.setVisibility(View.GONE);
178                break;
179            case DownloadManager.STATE_UNSTARTED:
180            case DownloadManager.STATE_TRANSIENT_FAILURE:
181            case DownloadManager.STATE_PERMANENT_FAILURE:
182            default:
183                setLongClickable(true);
184                inflateDownloadControls();
185                mDownloadingLabel.setVisibility(View.GONE);
186                mDownloadButton.setVisibility(View.VISIBLE);
187                mDownloadButton.setOnClickListener(new OnClickListener() {
188                    public void onClick(View v) {
189                        mDownloadingLabel.setVisibility(View.VISIBLE);
190                        mDownloadButton.setVisibility(View.GONE);
191                        Intent intent = new Intent(mContext, TransactionService.class);
192                        intent.putExtra(TransactionBundle.URI, msgItem.mMessageUri.toString());
193                        intent.putExtra(TransactionBundle.TRANSACTION_TYPE,
194                                Transaction.RETRIEVE_TRANSACTION);
195                        mContext.startService(intent);
196                    }
197                });
198                break;
199        }
200
201        // Hide the indicators.
202        mLockedIndicator.setVisibility(View.GONE);
203        mDeliveredIndicator.setVisibility(View.GONE);
204        mDetailsIndicator.setVisibility(View.GONE);
205    }
206
207    private void bindCommonMessage(final MessageListAdapter.AvatarCache avatarCache,
208            final MessageItem msgItem) {
209        if (mDownloadButton != null) {
210            mDownloadButton.setVisibility(View.GONE);
211            mDownloadingLabel.setVisibility(View.GONE);
212        }
213        // Since the message text should be concatenated with the sender's
214        // address(or name), I have to display it here instead of
215        // displaying it by the Presenter.
216        mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
217
218        String addr = null;
219        if (!Sms.isOutgoingFolder(msgItem.mBoxId)) {
220            addr = msgItem.mAddress;
221        } else {
222            addr = MmsApp.getApplication().getTelephonyManager().getLine1Number();
223        }
224        if (!TextUtils.isEmpty(addr)) {
225            MessageListAdapter.AvatarCache.ContactData contactData = avatarCache.get(addr);
226            mAvatar.setImageDrawable(contactData.getAvatar());
227            Uri contactUri = contactData.getContactUri();
228            // Since we load the contact info in the background, on the first screenfull of
229            // messages, it's likely we haven't loaded the contact URI info yet. In that case,
230            // fall back and use the phone number.
231            if (contactUri != null) {
232                mAvatar.assignContactUri(contactUri);
233            } else {
234                mAvatar.assignContactFromPhone(addr, true);
235            }
236        } else {
237            mAvatar.setImageToDefault();
238            mAvatar.assignContactUri(null);
239        }
240
241        // Get and/or lazily set the formatted message from/on the
242        // MessageItem.  Because the MessageItem instances come from a
243        // cache (currently of size ~50), the hit rate on avoiding the
244        // expensive formatMessage() call is very high.
245        CharSequence formattedMessage = msgItem.getCachedFormattedMessage();
246        if (formattedMessage == null) {
247            formattedMessage = formatMessage(msgItem, msgItem.mContact, msgItem.mBody,
248                                             msgItem.mSubject,
249                                             msgItem.mHighlight, msgItem.mTextContentType);
250        }
251        mBodyTextView.setText(formattedMessage);
252
253        // If we're in the process of sending a message (i.e. pending), then we show a "SENDING..."
254        // string in place of the timestamp.
255        mDateView.setText(msgItem.isSending() ?
256                mContext.getResources().getString(R.string.sending_message) :
257                    msgItem.mTimestamp);
258
259        if (msgItem.isSms()) {
260            hideMmsViewIfNeeded();
261        } else {
262            Presenter presenter = PresenterFactory.getPresenter(
263                    "MmsThumbnailPresenter", mContext,
264                    this, msgItem.mSlideshow);
265            presenter.present();
266
267            if (msgItem.mAttachmentType != WorkingMessage.TEXT) {
268                inflateMmsView();
269                mMmsView.setVisibility(View.VISIBLE);
270                setOnClickListener(msgItem);
271                drawPlaybackButton(msgItem);
272            } else {
273                hideMmsViewIfNeeded();
274            }
275        }
276
277        adjustLayoutItems(msgItem);
278        drawRightStatusIndicator(msgItem);
279
280        requestLayout();
281    }
282
283    private void adjustLayoutItems(final MessageItem msgItem) {
284        // Put the avatar on the left or right
285        RelativeLayout.LayoutParams avatarLayout =
286            (RelativeLayout.LayoutParams)mAvatar.getLayoutParams();
287        RelativeLayout.LayoutParams textLayout =
288            (RelativeLayout.LayoutParams)mBodyTextView.getLayoutParams();
289        RelativeLayout.LayoutParams dateLayout =
290            (RelativeLayout.LayoutParams)mDateView.getLayoutParams();
291        RelativeLayout.LayoutParams statusIconsLayout =
292            (RelativeLayout.LayoutParams)mStatusIcons.getLayoutParams();
293        RelativeLayout.LayoutParams divitLayout =
294            (RelativeLayout.LayoutParams)mDivit.getLayoutParams();
295
296        Resources resources = mContext.getResources();
297        int textPaddingLeftRight = resources.getDimensionPixelOffset(
298                R.dimen.message_item_text_padding_left_right);
299        int textPaddingTop = resources.getDimensionPixelOffset(
300                R.dimen.message_item_text_padding_top);
301
302        if (msgItem.mBoxId == Mms.MESSAGE_BOX_INBOX) {
303            // Avatar on left, text adjusted left
304            // undo the old rules first
305            textLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
306            textLayout.addRule(RelativeLayout.LEFT_OF, 0);
307            avatarLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
308            statusIconsLayout.addRule(RelativeLayout.LEFT_OF, 0);
309            dateLayout.addRule(RelativeLayout.LEFT_OF, 0);
310            divitLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
311
312            // set the new rules
313            avatarLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
314            textLayout.addRule(RelativeLayout.RIGHT_OF, R.id.avatar);
315            textLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
316            dateLayout.addRule(RelativeLayout.RIGHT_OF, R.id.avatar);
317            statusIconsLayout.addRule(RelativeLayout.RIGHT_OF, R.id.date_view);
318
319            mBodyTextView.setPadding(textPaddingLeftRight,
320                    textPaddingTop,
321                    textPaddingLeftRight,
322                    0);
323            mBodyTextView.setGravity(Gravity.LEFT);
324            mDateView.setPadding(textPaddingLeftRight, 0, 0, 0);
325
326            mDivit.setPosition(ImageViewDivot.RIGHT_UPPER);
327            divitLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
328        } else {
329            // Avatar on right, text adjusted right
330            // undo the old rules first
331            avatarLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
332            textLayout.addRule(RelativeLayout.RIGHT_OF, 0);
333            textLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
334            dateLayout.addRule(RelativeLayout.RIGHT_OF, 0);
335            statusIconsLayout.addRule(RelativeLayout.RIGHT_OF, 0);
336            divitLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT, 0);
337
338            // set the new rules
339            textLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
340            textLayout.addRule(RelativeLayout.LEFT_OF, R.id.avatar);
341            avatarLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
342            statusIconsLayout.addRule(RelativeLayout.LEFT_OF, R.id.date_view);
343            dateLayout.addRule(RelativeLayout.LEFT_OF, R.id.avatar);
344
345            mBodyTextView.setPadding(resources
346                    .getDimensionPixelOffset(R.dimen.message_item_avatar_on_right_text_indent),
347                        textPaddingTop,
348                        textPaddingLeftRight,
349                        0);
350            mBodyTextView.setGravity(Gravity.LEFT);
351            mDateView.setPadding(0, 0, textPaddingLeftRight, 0);
352
353            mDivit.setPosition(ImageViewDivot.LEFT_UPPER);
354            divitLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
355        }
356    }
357
358    private void hideMmsViewIfNeeded() {
359        if (mMmsView != null) {
360            mMmsView.setVisibility(View.GONE);
361        }
362    }
363
364    public void startAudio() {
365        // TODO Auto-generated method stub
366    }
367
368    public void startVideo() {
369        // TODO Auto-generated method stub
370    }
371
372    public void setAudio(Uri audio, String name, Map<String, ?> extras) {
373        // TODO Auto-generated method stub
374    }
375
376    public void setImage(String name, Bitmap bitmap) {
377        inflateMmsView();
378
379        try {
380            if (null == bitmap) {
381                bitmap = BitmapFactory.decodeResource(getResources(),
382                        R.drawable.ic_missing_thumbnail_picture);
383            }
384            mImageView.setImageBitmap(bitmap);
385            mImageView.setVisibility(VISIBLE);
386        } catch (java.lang.OutOfMemoryError e) {
387            Log.e(TAG, "setImage: out of memory: ", e);
388        }
389    }
390
391    private void inflateMmsView() {
392        if (mMmsView == null) {
393            //inflate the surrounding view_stub
394            findViewById(R.id.mms_layout_view_stub).setVisibility(VISIBLE);
395
396            mMmsView = findViewById(R.id.mms_view);
397            mImageView = (ImageView) findViewById(R.id.image_view);
398            mSlideShowButton = (ImageButton) findViewById(R.id.play_slideshow_button);
399        }
400    }
401
402    private void inflateDownloadControls() {
403        if (mDownloadButton == null) {
404            //inflate the download controls
405            findViewById(R.id.mms_downloading_view_stub).setVisibility(VISIBLE);
406            mDownloadButton = (Button) findViewById(R.id.btn_download_msg);
407            mDownloadingLabel = (TextView) findViewById(R.id.label_downloading);
408        }
409    }
410
411
412    private LineHeightSpan mSpan = new LineHeightSpan() {
413        public void chooseHeight(CharSequence text, int start,
414                int end, int spanstartv, int v, FontMetricsInt fm) {
415            fm.ascent -= 10;
416        }
417    };
418
419    TextAppearanceSpan mTextSmallSpan =
420        new TextAppearanceSpan(mContext, android.R.style.TextAppearance_Small);
421
422    ForegroundColorSpan mColorSpan = null;  // set in ctor
423
424    private CharSequence formatMessage(MessageItem msgItem, String contact, String body,
425                                       String subject, Pattern highlight,
426                                       String contentType) {
427        SpannableStringBuilder buf = new SpannableStringBuilder();
428
429        boolean hasSubject = !TextUtils.isEmpty(subject);
430        if (hasSubject) {
431            buf.append(mContext.getResources().getString(R.string.inline_subject, subject));
432        }
433
434        if (!TextUtils.isEmpty(body)) {
435            // Converts html to spannable if ContentType is "text/html".
436            if (contentType != null && ContentType.TEXT_HTML.equals(contentType)) {
437                buf.append("\n");
438                buf.append(Html.fromHtml(body));
439            } else {
440                if (hasSubject) {
441                    buf.append(" - ");
442                }
443                SmileyParser parser = SmileyParser.getInstance();
444                buf.append(parser.addSmileySpans(body));
445            }
446        }
447
448        if (highlight != null) {
449            Matcher m = highlight.matcher(buf.toString());
450            while (m.find()) {
451                buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0);
452            }
453        }
454        return buf;
455    }
456
457    private void drawPlaybackButton(MessageItem msgItem) {
458        switch (msgItem.mAttachmentType) {
459            case WorkingMessage.SLIDESHOW:
460            case WorkingMessage.AUDIO:
461            case WorkingMessage.VIDEO:
462                // Show the 'Play' button and bind message info on it.
463                mSlideShowButton.setTag(msgItem);
464                // Set call-back for the 'Play' button.
465                mSlideShowButton.setOnClickListener(this);
466                mSlideShowButton.setVisibility(View.VISIBLE);
467                setLongClickable(true);
468
469                // When we show the mSlideShowButton, this list item's onItemClickListener doesn't
470                // get called. (It gets set in ComposeMessageActivity:
471                // mMsgListView.setOnItemClickListener) Here we explicitly set the item's
472                // onClickListener. It allows the item to respond to embedded html links and at the
473                // same time, allows the slide show play button to work.
474                setOnClickListener(new OnClickListener() {
475                    public void onClick(View v) {
476                        onMessageListItemClick();
477                    }
478                });
479                break;
480            default:
481                mSlideShowButton.setVisibility(View.GONE);
482                break;
483        }
484    }
485
486    // OnClick Listener for the playback button
487    public void onClick(View v) {
488        MessageItem mi = (MessageItem) v.getTag();
489        switch (mi.mAttachmentType) {
490            case WorkingMessage.VIDEO:
491            case WorkingMessage.AUDIO:
492            case WorkingMessage.SLIDESHOW:
493                MessageUtils.viewMmsMessageAttachment(mContext, mi.mMessageUri, mi.mSlideshow);
494                break;
495        }
496    }
497
498    public void onMessageListItemClick() {
499        URLSpan[] spans = mBodyTextView.getUrls();
500
501        if (spans.length == 0) {
502            // Do nothing.
503        } else if (spans.length == 1) {
504            Uri uri = Uri.parse(spans[0].getURL());
505            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
506            intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
507            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
508            mContext.startActivity(intent);
509        } else {
510            final java.util.ArrayList<String> urls = MessageUtils.extractUris(spans);
511
512            ArrayAdapter<String> adapter =
513                new ArrayAdapter<String>(mContext, android.R.layout.select_dialog_item, urls) {
514                public View getView(int position, View convertView, ViewGroup parent) {
515                    View v = super.getView(position, convertView, parent);
516                    try {
517                        String url = getItem(position).toString();
518                        TextView tv = (TextView) v;
519                        Drawable d = mContext.getPackageManager().getActivityIcon(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
520                        if (d != null) {
521                            d.setBounds(0, 0, d.getIntrinsicHeight(), d.getIntrinsicHeight());
522                            tv.setCompoundDrawablePadding(10);
523                            tv.setCompoundDrawables(d, null, null, null);
524                        }
525                        final String telPrefix = "tel:";
526                        if (url.startsWith(telPrefix)) {
527                            url = PhoneNumberUtils.formatNumber(
528                                            url.substring(telPrefix.length()), mDefaultCountryIso);
529                        }
530                        tv.setText(url);
531                    } catch (android.content.pm.PackageManager.NameNotFoundException ex) {
532                        ;
533                    }
534                    return v;
535                }
536            };
537
538            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
539
540            DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {
541                public final void onClick(DialogInterface dialog, int which) {
542                    if (which >= 0) {
543                        Uri uri = Uri.parse(urls.get(which));
544                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
545                        intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
546                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
547                        mContext.startActivity(intent);
548                    }
549                    dialog.dismiss();
550                }
551            };
552
553            b.setTitle(R.string.select_link_title);
554            b.setCancelable(true);
555            b.setAdapter(adapter, click);
556
557            b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
558                public final void onClick(DialogInterface dialog, int which) {
559                    dialog.dismiss();
560                }
561            });
562
563            b.show();
564        }
565    }
566
567
568    private void setOnClickListener(final MessageItem msgItem) {
569        switch(msgItem.mAttachmentType) {
570        case WorkingMessage.IMAGE:
571        case WorkingMessage.VIDEO:
572            mImageView.setOnClickListener(new OnClickListener() {
573                public void onClick(View v) {
574                    MessageUtils.viewMmsMessageAttachment(mContext, null, msgItem.mSlideshow);
575                }
576            });
577            mImageView.setOnLongClickListener(new OnLongClickListener() {
578                public boolean onLongClick(View v) {
579                    return v.showContextMenu();
580                }
581            });
582            break;
583
584        default:
585            mImageView.setOnClickListener(null);
586            break;
587        }
588    }
589
590    private void setErrorIndicatorClickListener(final MessageItem msgItem) {
591        String type = msgItem.mType;
592        final int what;
593        if (type.equals("sms")) {
594            what = MSG_LIST_EDIT_SMS;
595        } else {
596            what = MSG_LIST_EDIT_MMS;
597        }
598        mDeliveredIndicator.setOnClickListener(new OnClickListener() {
599            public void onClick(View v) {
600                if (null != mHandler) {
601                    Message msg = Message.obtain(mHandler, what);
602                    msg.obj = new Long(msgItem.mMsgId);
603                    msg.sendToTarget();
604                }
605            }
606        });
607    }
608
609    private void drawRightStatusIndicator(MessageItem msgItem) {
610        // Locked icon
611        if (msgItem.mLocked) {
612            mLockedIndicator.setImageResource(R.drawable.ic_lock_message_sms);
613            mLockedIndicator.setVisibility(View.VISIBLE);
614        } else {
615            mLockedIndicator.setVisibility(View.GONE);
616        }
617
618        // Delivery icon
619        if (msgItem.isOutgoingMessage() && msgItem.isFailedMessage()) {
620            mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed);
621            setErrorIndicatorClickListener(msgItem);
622            mDeliveredIndicator.setVisibility(View.VISIBLE);
623        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.FAILED) {
624            mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed);
625            mDeliveredIndicator.setVisibility(View.VISIBLE);
626        } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED) {
627            mDeliveredIndicator.setImageResource(R.drawable.ic_sms_mms_delivered);
628            mDeliveredIndicator.setVisibility(View.VISIBLE);
629        } else {
630            mDeliveredIndicator.setVisibility(View.GONE);
631        }
632
633        // Message details icon
634        if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.INFO || msgItem.mReadReport) {
635            mDetailsIndicator.setImageResource(R.drawable.ic_sms_mms_details);
636            mDetailsIndicator.setVisibility(View.VISIBLE);
637        } else {
638            mDetailsIndicator.setVisibility(View.GONE);
639        }
640    }
641
642    public void setImageRegionFit(String fit) {
643        // TODO Auto-generated method stub
644    }
645
646    public void setImageVisibility(boolean visible) {
647        // TODO Auto-generated method stub
648    }
649
650    public void setText(String name, String text) {
651        // TODO Auto-generated method stub
652    }
653
654    public void setTextVisibility(boolean visible) {
655        // TODO Auto-generated method stub
656    }
657
658    public void setVideo(String name, Uri video) {
659        inflateMmsView();
660
661        try {
662            Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
663            if (null == bitmap) {
664                bitmap = BitmapFactory.decodeResource(getResources(),
665                        R.drawable.ic_missing_thumbnail_video);
666            }
667            mImageView.setImageBitmap(bitmap);
668            mImageView.setVisibility(VISIBLE);
669        } catch (java.lang.OutOfMemoryError e) {
670            Log.e(TAG, "setVideo: out of memory: ", e);
671        }
672    }
673
674    public void setVideoVisibility(boolean visible) {
675        // TODO Auto-generated method stub
676    }
677
678    public void stopAudio() {
679        // TODO Auto-generated method stub
680    }
681
682    public void stopVideo() {
683        // TODO Auto-generated method stub
684    }
685
686    public void reset() {
687        if (mImageView != null) {
688            mImageView.setVisibility(GONE);
689        }
690    }
691
692    public void setVisibility(boolean visible) {
693        // TODO Auto-generated method stub
694    }
695
696    public void pauseAudio() {
697        // TODO Auto-generated method stub
698
699    }
700
701    public void pauseVideo() {
702        // TODO Auto-generated method stub
703
704    }
705
706    public void seekAudio(int seekTo) {
707        // TODO Auto-generated method stub
708
709    }
710
711    public void seekVideo(int seekTo) {
712        // TODO Auto-generated method stub
713
714    }
715}
716