1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mail.widget; 18 19 import com.android.mail.R; 20 import com.android.mail.providers.Conversation; 21 import com.android.mail.providers.Folder; 22 import com.android.mail.ui.FolderDisplayer; 23 import com.android.mail.utils.FolderUri; 24 25 import android.content.Context; 26 import android.content.res.Resources; 27 import android.graphics.Bitmap; 28 import android.graphics.BitmapFactory; 29 import android.graphics.Typeface; 30 import android.text.Spannable; 31 import android.text.SpannableStringBuilder; 32 import android.text.style.AbsoluteSizeSpan; 33 import android.text.style.ForegroundColorSpan; 34 import android.text.style.StyleSpan; 35 import android.view.View; 36 import android.widget.RemoteViews; 37 38 public class WidgetConversationListItemViewBuilder { 39 // Static font sizes 40 private static int DATE_FONT_SIZE; 41 private static int SUBJECT_FONT_SIZE; 42 43 // Static colors 44 private static int SUBJECT_TEXT_COLOR_READ; 45 private static int SUBJECT_TEXT_COLOR_UNREAD; 46 private static int DATE_TEXT_COLOR; 47 48 // Static bitmap 49 private static Bitmap ATTACHMENT; 50 51 private final Context mContext; 52 private WidgetFolderDisplayer mFolderDisplayer; 53 54 /** 55 * Label Displayer for Widget 56 */ 57 protected static class WidgetFolderDisplayer extends FolderDisplayer { 58 public WidgetFolderDisplayer(Context context) { 59 super(context); 60 } 61 62 // Maximum number of folders we want to display 63 private static final int MAX_DISPLAYED_FOLDERS_COUNT = 3; 64 65 /* 66 * Load Conversation Labels 67 */ 68 @Override 69 public void loadConversationFolders(Conversation conv, final FolderUri ignoreFolderUri, 70 final int ignoreFolderType) { 71 super.loadConversationFolders(conv, ignoreFolderUri, ignoreFolderType); 72 } 73 74 private static int getFolderViewId(int position) { 75 switch (position) { 76 case 0: 77 return R.id.widget_folder_0; 78 case 1: 79 return R.id.widget_folder_1; 80 case 2: 81 return R.id.widget_folder_2; 82 } 83 return 0; 84 } 85 86 /** 87 * Display folders 88 */ 89 public void displayFolders(RemoteViews remoteViews) { 90 int displayedFolder = 0; 91 for (Folder folderValues : mFoldersSortedSet) { 92 int viewId = getFolderViewId(displayedFolder); 93 if (viewId == 0) { 94 continue; 95 } 96 remoteViews.setViewVisibility(viewId, View.VISIBLE); 97 int color[] = new int[] {folderValues.getBackgroundColor(mDefaultBgColor)}; 98 Bitmap bitmap = Bitmap.createBitmap(color, 1, 1, Bitmap.Config.RGB_565); 99 remoteViews.setImageViewBitmap(viewId, bitmap); 100 101 if (++displayedFolder == MAX_DISPLAYED_FOLDERS_COUNT) { 102 break; 103 } 104 } 105 106 for (int i = displayedFolder; i < MAX_DISPLAYED_FOLDERS_COUNT; i++) { 107 remoteViews.setViewVisibility(getFolderViewId(i), View.GONE); 108 } 109 } 110 } 111 112 /* 113 * Get font sizes and bitmaps from Resources 114 */ 115 public WidgetConversationListItemViewBuilder(Context context) { 116 mContext = context; 117 Resources res = context.getResources(); 118 119 // Initialize font sizes 120 DATE_FONT_SIZE = res.getDimensionPixelSize(R.dimen.widget_date_font_size); 121 SUBJECT_FONT_SIZE = res.getDimensionPixelSize(R.dimen.widget_subject_font_size); 122 123 // Initialize colors 124 SUBJECT_TEXT_COLOR_READ = res.getColor(R.color.subject_text_color_read); 125 SUBJECT_TEXT_COLOR_UNREAD = res.getColor(R.color.subject_text_color_unread); 126 DATE_TEXT_COLOR = res.getColor(R.color.date_text_color); 127 128 // Initialize Bitmap 129 ATTACHMENT = BitmapFactory.decodeResource(res, R.drawable.ic_attachment_holo_light); 130 } 131 132 /* 133 * Add size, color and style to a given text 134 */ 135 private static CharSequence addStyle(CharSequence text, int size, int color) { 136 SpannableStringBuilder builder = new SpannableStringBuilder(text); 137 builder.setSpan( 138 new AbsoluteSizeSpan(size), 0, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 139 if (color != 0) { 140 builder.setSpan(new ForegroundColorSpan(color), 0, text.length(), 141 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 142 } 143 return builder; 144 } 145 146 /* 147 * Return the full View 148 */ 149 public RemoteViews getStyledView(final CharSequence date, final Conversation conversation, 150 final FolderUri folderUri, final int ignoreFolderType, 151 final SpannableStringBuilder senders, final String filteredSubject) { 152 153 final boolean isUnread = !conversation.read; 154 final String snippet = conversation.getSnippet(); 155 final boolean hasAttachments = conversation.hasAttachments; 156 157 // Add style to date 158 final CharSequence styledDate = addStyle(date, DATE_FONT_SIZE, DATE_TEXT_COLOR); 159 160 // Add style to subject 161 final int subjectColor = isUnread ? SUBJECT_TEXT_COLOR_UNREAD : SUBJECT_TEXT_COLOR_READ; 162 final SpannableStringBuilder subjectAndSnippet = new SpannableStringBuilder( 163 Conversation.getSubjectAndSnippetForDisplay(mContext, filteredSubject, snippet)); 164 if (isUnread) { 165 subjectAndSnippet.setSpan(new StyleSpan(Typeface.BOLD), 0, filteredSubject.length(), 166 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 167 } 168 subjectAndSnippet.setSpan(new ForegroundColorSpan(subjectColor), 0, subjectAndSnippet 169 .length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 170 final CharSequence styledSubject = addStyle(subjectAndSnippet, SUBJECT_FONT_SIZE, 0); 171 172 // Paper clip for attachment 173 Bitmap paperclipBitmap = null; 174 if (hasAttachments) { 175 paperclipBitmap = ATTACHMENT; 176 } 177 178 // Inflate and fill out the remote view 179 final RemoteViews remoteViews = new RemoteViews( 180 mContext.getPackageName(), R.layout.widget_conversation_list_item); 181 remoteViews.setTextViewText(R.id.widget_senders, senders); 182 remoteViews.setTextViewText(R.id.widget_date, styledDate); 183 remoteViews.setTextViewText(R.id.widget_subject, styledSubject); 184 if (paperclipBitmap != null) { 185 remoteViews.setViewVisibility(R.id.widget_attachment, View.VISIBLE); 186 remoteViews.setImageViewBitmap(R.id.widget_attachment, paperclipBitmap); 187 } else { 188 remoteViews.setViewVisibility(R.id.widget_attachment, View.GONE); 189 } 190 if (isUnread) { 191 remoteViews.setViewVisibility(R.id.widget_unread_background, View.VISIBLE); 192 remoteViews.setViewVisibility(R.id.widget_read_background, View.GONE); 193 } else { 194 remoteViews.setViewVisibility(R.id.widget_unread_background, View.GONE); 195 remoteViews.setViewVisibility(R.id.widget_read_background, View.VISIBLE); 196 } 197 if (mContext.getResources().getBoolean(R.bool.display_folder_colors_in_widget)) { 198 mFolderDisplayer = new WidgetFolderDisplayer(mContext); 199 mFolderDisplayer.loadConversationFolders(conversation, folderUri, ignoreFolderType); 200 mFolderDisplayer.displayFolders(remoteViews); 201 } 202 203 return remoteViews; 204 } 205 } 206