Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2012 Google Inc.
      3  * Licensed to 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 
     18 package com.android.mail.ui;
     19 
     20 import android.net.Uri;
     21 import android.os.Bundle;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 
     25 import com.android.mail.providers.Conversation;
     26 import com.android.mail.providers.Message;
     27 import com.google.common.collect.Maps;
     28 import com.google.common.collect.Sets;
     29 
     30 import java.util.Map;
     31 import java.util.Set;
     32 
     33 /**
     34  * A small class to keep state for conversation view when restoring.
     35  *
     36  */
     37 public class ConversationViewState implements Parcelable {
     38 
     39     // N.B. don't serialize entire Messages because they contain body HTML/text
     40 
     41     private final Map<Uri, MessageViewState> mMessageViewStates = Maps.newHashMap();
     42 
     43     private byte[] mConversationInfo;
     44 
     45     public static final class ExpansionState {
     46         public static int NONE = 0;
     47         public static int EXPANDED = 1;
     48         public static int COLLAPSED = 2;
     49         public static int SUPER_COLLAPSED = 3;
     50 
     51         private ExpansionState() {}
     52 
     53         public static boolean isExpanded(int state) {
     54             return state == EXPANDED;
     55         }
     56         public static boolean isSuperCollapsed(int state) {
     57             return state == SUPER_COLLAPSED;
     58         }
     59     }
     60 
     61     public ConversationViewState() {}
     62 
     63     /**
     64      * Copy constructor that will copy overall conversation state, but NOT individual message state.
     65      */
     66     public ConversationViewState(ConversationViewState other) {
     67         mConversationInfo = other.mConversationInfo;
     68     }
     69 
     70     public boolean isUnread(Message m) {
     71         final MessageViewState mvs = mMessageViewStates.get(m.uri);
     72         return (mvs != null && !mvs.read);
     73     }
     74 
     75     public void setReadState(Message m, boolean read) {
     76         MessageViewState mvs = mMessageViewStates.get(m.uri);
     77         if (mvs == null) {
     78             mvs = new MessageViewState();
     79         }
     80         mvs.read = read;
     81         mMessageViewStates.put(m.uri, mvs);
     82     }
     83 
     84     public boolean getShouldShowImages(Message m) {
     85         final MessageViewState mvs = mMessageViewStates.get(m.uri);
     86         return (mvs != null && mvs.showImages);
     87     }
     88 
     89     public void setShouldShowImages(Message m, boolean showImages) {
     90         MessageViewState mvs = mMessageViewStates.get(m.uri);
     91         if (mvs == null) {
     92             mvs = new MessageViewState();
     93         }
     94         mvs.showImages = showImages;
     95         mMessageViewStates.put(m.uri, mvs);
     96     }
     97 
     98     /**
     99      * Returns the expansion state of a message in a conversation view.
    100      *
    101      * @param m a Message in the conversation
    102      * @return 1 = expanded, 2 = collapsed, 3 = super collapsed, or null otherwise
    103      * (see {@link ExpansionState}).
    104      */
    105     public Integer getExpansionState(Message m) {
    106         final MessageViewState mvs = mMessageViewStates.get(m.uri);
    107         return (mvs == null ? null : mvs.expansionState);
    108     }
    109 
    110     public void setExpansionState(Message m, int expansionState) {
    111         MessageViewState mvs = mMessageViewStates.get(m.uri);
    112         if (mvs == null) {
    113             mvs = new MessageViewState();
    114         }
    115         mvs.expansionState = expansionState;
    116         mMessageViewStates.put(m.uri, mvs);
    117     }
    118 
    119     public byte[] getConversationInfo() {
    120         return mConversationInfo;
    121     }
    122 
    123     public void setInfoForConversation(Conversation conv) {
    124         mConversationInfo = conv.conversationInfo.toBlob();
    125     }
    126 
    127     /**
    128      * Returns URIs of all unread messages in the conversation per
    129      * {@link #setReadState(Message, boolean)}. Returns an empty set for read conversations.
    130      *
    131      */
    132     public Set<Uri> getUnreadMessageUris() {
    133         final Set<Uri> result = Sets.newHashSet();
    134         for (Uri uri : mMessageViewStates.keySet()) {
    135             final MessageViewState mvs = mMessageViewStates.get(uri);
    136             if (mvs != null && !mvs.read) {
    137                 result.add(uri);
    138             }
    139         }
    140         return result;
    141     }
    142 
    143     public boolean contains(Message m) {
    144         return mMessageViewStates.containsKey(m.uri);
    145     }
    146 
    147     @Override
    148     public int describeContents() {
    149         return 0;
    150     }
    151 
    152     @Override
    153     public void writeToParcel(Parcel dest, int flags) {
    154         final Bundle states = new Bundle();
    155         for (Uri uri : mMessageViewStates.keySet()) {
    156             final MessageViewState mvs = mMessageViewStates.get(uri);
    157             states.putParcelable(uri.toString(), mvs);
    158         }
    159         dest.writeBundle(states);
    160         dest.writeByteArray(mConversationInfo);
    161     }
    162 
    163     private ConversationViewState(Parcel source, ClassLoader loader) {
    164         final Bundle states = source.readBundle(loader);
    165         for (String key : states.keySet()) {
    166             final MessageViewState state = states.getParcelable(key);
    167             mMessageViewStates.put(Uri.parse(key), state);
    168         }
    169         mConversationInfo = source.createByteArray();
    170     }
    171 
    172     public static final ClassLoaderCreator<ConversationViewState> CREATOR =
    173             new ClassLoaderCreator<ConversationViewState>() {
    174 
    175         @Override
    176         public ConversationViewState createFromParcel(Parcel source) {
    177             return new ConversationViewState(source, null);
    178         }
    179 
    180         @Override
    181         public ConversationViewState createFromParcel(Parcel source, ClassLoader loader) {
    182             return new ConversationViewState(source, loader);
    183         }
    184 
    185         @Override
    186         public ConversationViewState[] newArray(int size) {
    187             return new ConversationViewState[size];
    188         }
    189 
    190     };
    191 
    192     // Keep per-message state in an inner Parcelable.
    193     // This is a semi-private implementation detail.
    194     static class MessageViewState implements Parcelable {
    195 
    196         public boolean read;
    197         /**
    198          * See {@link ExpansionState} for values.
    199          *
    200          */
    201         public Integer expansionState;
    202         public boolean showImages;
    203 
    204         public MessageViewState() {}
    205 
    206         @Override
    207         public int describeContents() {
    208             return 0;
    209         }
    210 
    211         @Override
    212         public void writeToParcel(Parcel dest, int flags) {
    213             dest.writeInt(read ? 1 : 0);
    214             dest.writeInt(expansionState == null ? -1 : expansionState.intValue());
    215             dest.writeInt(showImages ? 1 : 0);
    216         }
    217 
    218         private MessageViewState(Parcel source) {
    219             read = (source.readInt() != 0);
    220             final int expandedVal = source.readInt();
    221             expansionState = (expandedVal == -1) ? null : expandedVal;
    222             showImages = (source.readInt() != 0);
    223         }
    224 
    225         @SuppressWarnings("hiding")
    226         public static final Parcelable.Creator<MessageViewState> CREATOR =
    227                 new Parcelable.Creator<MessageViewState>() {
    228 
    229             @Override
    230             public MessageViewState createFromParcel(Parcel source) {
    231                 return new MessageViewState(source);
    232             }
    233 
    234             @Override
    235             public MessageViewState[] newArray(int size) {
    236                 return new MessageViewState[size];
    237             }
    238 
    239         };
    240 
    241     }
    242 
    243 }
    244