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.content.Context;
21 import android.database.Cursor;
22 import android.text.Spannable;
23 import android.text.SpannableStringBuilder;
24 import android.text.TextUtils;
25 import android.text.style.ForegroundColorSpan;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.CompoundButton;
29 import android.widget.TextView;
30 
31 import com.android.mail.R;
32 import com.android.mail.providers.Folder;
33 import com.google.common.annotations.VisibleForTesting;
34 
35 import java.util.Set;
36 
37 public class HierarchicalFolderSelectorAdapter extends FolderSelectorAdapter {
38 
39     private Context mContext;
40 
41     @VisibleForTesting
HierarchicalFolderSelectorAdapter(Context context, Cursor folders, Set<String> initiallySelected, int layout)42     public HierarchicalFolderSelectorAdapter(Context context, Cursor folders,
43             Set<String> initiallySelected, int layout) {
44         super(context, folders, initiallySelected, layout);
45         mContext = context;
46     }
47 
HierarchicalFolderSelectorAdapter(Context context, Cursor folders, int layout, Folder excludedFolder)48     public HierarchicalFolderSelectorAdapter(Context context, Cursor folders,
49             int layout, Folder excludedFolder) {
50         super(context, folders, layout, excludedFolder);
51         mContext = context;
52     }
53 
54     @Override
getView(int position, View convertView, ViewGroup parent)55     public View getView(int position, View convertView, ViewGroup parent) {
56         final View view = super.getView(position, convertView, parent);
57         final FolderRow row = (FolderRow) getItem(position);
58         final Folder folder = row.getFolder();
59         final CompoundButton checkBox = (CompoundButton) view.findViewById(R.id.checkbox);
60         final TextView display = (TextView) view.findViewById(R.id.folder_name);
61         final CharSequence displayText = TextUtils.isEmpty(row.mPathName) ? folder.name
62                 : truncateHierarchy(row.mPathName);
63         if (checkBox != null) {
64             checkBox.setText(TextUtils.isEmpty(row.mPathName) ? folder.name
65                 : truncateHierarchy(row.mPathName), TextView.BufferType.SPANNABLE);
66         } else {
67             display.setText(displayText, TextView.BufferType.SPANNABLE);
68         }
69         return view;
70     }
71 
72     /**
73      * Truncation of a hierarchy works as follows:
74      * 1) If there is just a folder name, return that.
75      * 2) If there is a single parent and a folder name, return parent/folder.
76      * 3) If there is > 1 but < 3 ancestors, return ancestor/ancestor2/folder
77      * 4) If there are > 3 ancestors, return the top most ancestor, and direct parent
78      * of the folder, and the folder: ancestor/.../directParent/folder
79      */
80     @VisibleForTesting
truncateHierarchy(String hierarchy)81     protected SpannableStringBuilder truncateHierarchy(String hierarchy) {
82         if (TextUtils.isEmpty(hierarchy)) {
83             return null;
84         }
85         final String[] splitHierarchy = hierarchy.split("/");
86         // We want to keep the last part of the hierachy, as that is the name of
87         // the folder.
88         final String folderName;
89         final String topParentName;
90         final String directParentName;
91         final SpannableStringBuilder display = new SpannableStringBuilder();
92         if (splitHierarchy != null && splitHierarchy.length > 0) {
93             final int length = splitHierarchy.length;
94             if (length > 2) {
95                 topParentName = splitHierarchy[0];
96                 directParentName = splitHierarchy[length - 2];
97                 folderName = splitHierarchy[length - 1];
98             } else if (length > 1) {
99                 topParentName = splitHierarchy[0];
100                 directParentName = null;
101                 folderName = splitHierarchy[length - 1];
102             } else {
103                 topParentName = null;
104                 directParentName = null;
105                 folderName = splitHierarchy[0];
106             }
107             if (!TextUtils.isEmpty(directParentName)) {
108                 final int formatString;
109                 if (length > 3) {
110                     formatString = R.string.hierarchical_folder_parent_top_ellip;
111                 } else {
112                     formatString = R.string.hierarchical_folder_parent_top;
113                 }
114                 display.append(mContext.getResources().getString(formatString, topParentName,
115                         directParentName));
116             } else if (!TextUtils.isEmpty(topParentName)) {
117                 display.append(mContext.getResources().getString(R.string.hierarchical_folder_top,
118                         topParentName));
119             }
120 
121             // If there is nothing appended to display, don't try to setSpan.
122             if (display.length() > 0) {
123                 display.setSpan(new ForegroundColorSpan(R.color.hierarchical_folder_parent_color),
124                         0, display.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
125             }
126             display.append(folderName);
127         }
128         return display;
129     }
130 }
131