OSDN Git Service

CMFileManager: Add mimetype to search result.
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / adapters / SearchResultAdapter.java
1 /*
2  * Copyright (C) 2012 The CyanogenMod 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.cyanogenmod.filemanager.adapters;
18
19 import android.content.Context;
20 import android.graphics.drawable.Drawable;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.ArrayAdapter;
25 import android.widget.ImageView;
26 import android.widget.TextView;
27
28 import com.cyanogenmod.filemanager.R;
29 import com.cyanogenmod.filemanager.model.FileSystemObject;
30 import com.cyanogenmod.filemanager.model.Query;
31 import com.cyanogenmod.filemanager.model.SearchResult;
32 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
33 import com.cyanogenmod.filemanager.preferences.Preferences;
34 import com.cyanogenmod.filemanager.ui.IconHolder;
35 import com.cyanogenmod.filemanager.ui.ThemeManager;
36 import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
37 import com.cyanogenmod.filemanager.ui.widgets.RelevanceView;
38 import com.cyanogenmod.filemanager.util.MimeTypeHelper;
39 import com.cyanogenmod.filemanager.util.SearchHelper;
40
41 import java.io.File;
42 import java.util.ArrayList;
43 import java.util.List;
44
45 /**
46  * An implementation of {@link ArrayAdapter} for display search results.
47  */
48 public class SearchResultAdapter extends ArrayAdapter<SearchResult> {
49
50     /**
51      * A class that conforms with the ViewHolder pattern to performance
52      * the list view rendering.
53      */
54     private static class ViewHolder {
55         /**
56          * @hide
57          */
58         public ViewHolder() {
59             super();
60         }
61         ImageView mIvIcon;
62         TextView mTvName;
63         TextView mTvParentDir;
64         RelevanceView mWgRelevance;
65         TextView mMimeType;
66     }
67
68     /**
69      * A class that holds the full data information.
70      */
71     private static class DataHolder {
72         /**
73          * @hide
74          */
75         public DataHolder() {
76             super();
77         }
78         Drawable mDwIcon;
79         CharSequence mName;
80         String mParentDir;
81         Float mRelevance;
82         MimeTypeHelper.MimeTypeCategory mimeTypeCategory;
83     }
84
85     private DataHolder[] mData;
86     private IconHolder mIconHolder;
87     private final int mItemViewResourceId;
88
89     private final boolean mHighlightTerms;
90     private final boolean mShowRelevanceWidget;
91
92     private final List<String> mQueries;
93
94     private boolean mDisposed;
95
96     //The resource of the item icon
97     private static final int RESOURCE_ITEM_ICON = R.id.search_item_icon;
98     //The resource of the item name
99     private static final int RESOURCE_ITEM_NAME = R.id.search_item_name;
100     //The resource of the item path
101     private static final int RESOURCE_ITEM_PARENT_DIR = R.id.search_item_parent_dir;
102     //The resource of the item relevance
103     private static final int RESOURCE_ITEM_RELEVANCE = R.id.search_item_relevance;
104     //The resource of the item mime type
105     private static final int RESOURCE_ITEM_MIME_TYPE = R.id.search_item_mime_type;
106
107     /**
108      * Constructor of <code>SearchResultAdapter</code>.
109      *
110      * @param context The current context
111      * @param files The list of file system objects
112      * @param itemViewResourceId The identifier of the layout that represents an item
113      * of the list adapter
114      * @param queries The query object used to make the result of this search
115      */
116     public SearchResultAdapter(
117             Context context, List<SearchResult> files, int itemViewResourceId, Query queries) {
118         super(context, RESOURCE_ITEM_NAME, files);
119         this.mDisposed = false;
120         final boolean displayThumbs = Preferences.getSharedPreferences().getBoolean(
121                 FileManagerSettings.SETTINGS_DISPLAY_THUMBS.getId(),
122                 ((Boolean)FileManagerSettings.SETTINGS_DISPLAY_THUMBS.getDefaultValue()).booleanValue());
123         this.mIconHolder = new IconHolder(context, displayThumbs);
124         this.mItemViewResourceId = itemViewResourceId;
125         this.mQueries = queries.getQueries();
126
127         // Load settings
128         this.mHighlightTerms = Preferences.getSharedPreferences().getBoolean(
129                 FileManagerSettings.SETTINGS_HIGHLIGHT_TERMS.getId(),
130                 ((Boolean)FileManagerSettings.SETTINGS_HIGHLIGHT_TERMS.
131                         getDefaultValue()).booleanValue());
132         this.mShowRelevanceWidget = Preferences.getSharedPreferences().getBoolean(
133                 FileManagerSettings.SETTINGS_SHOW_RELEVANCE_WIDGET.getId(),
134                 ((Boolean)FileManagerSettings.SETTINGS_SHOW_RELEVANCE_WIDGET.
135                         getDefaultValue()).booleanValue());
136
137         //Do cache of the data for better performance
138         loadDefaultIcons();
139         processData();
140     }
141
142     /**
143      * Method that loads the default icons (known icons and more common icons).
144      */
145     private void loadDefaultIcons() {
146         this.mIconHolder.getDrawable("ic_fso_folder_drawable"); //$NON-NLS-1$
147         this.mIconHolder.getDrawable("ic_fso_default_drawable"); //$NON-NLS-1$
148     }
149
150     /**
151      * {@inheritDoc}
152      */
153     @Override
154     public void notifyDataSetChanged() {
155         if (this.mDisposed) {
156             return;
157         }
158         processData();
159         super.notifyDataSetChanged();
160     }
161
162     /**
163      * Method that dispose the elements of the adapter.
164      */
165     public void dispose() {
166         if (this.mIconHolder != null) {
167             this.mIconHolder.cleanup();
168         }
169         this.mDisposed = true;
170         clear();
171         this.mData = null;
172         this.mIconHolder = null;
173     }
174
175     /**
176      * Method that process the data before use {@link #getView} method.
177      */
178     private void processData() {
179         Theme theme = ThemeManager.getCurrentTheme(getContext());
180         int highlightedColor =
181                 theme.getColor(getContext(), "search_highlight_color"); //$NON-NLS-1$
182
183         this.mData = new DataHolder[getCount()];
184         int cc = getCount();
185         for (int i = 0; i < cc; i++) {
186             //File system object info
187             SearchResult result = getItem(i);
188
189             //Build the data holder
190             final FileSystemObject fso = result.getFso();
191             this.mData[i] = new SearchResultAdapter.DataHolder();
192             this.mData[i].mDwIcon = this.mIconHolder.getDrawable(
193                     MimeTypeHelper.getIcon(getContext(), fso));
194             if (this.mHighlightTerms) {
195                 this.mData[i].mName =
196                         SearchHelper.getHighlightedName(result, this.mQueries, highlightedColor);
197             } else {
198                 this.mData[i].mName = SearchHelper.getNonHighlightedName(result);
199             }
200             this.mData[i].mParentDir = new File(result.getFso().getFullPath()).getParent();
201             if (this.mShowRelevanceWidget) {
202                 this.mData[i].mRelevance =
203                         Float.valueOf(
204                                 (float)(result.getRelevance() * 100) / SearchResult.MAX_RELEVANCE);
205             } else {
206                 this.mData[i].mRelevance = null;
207             }
208             this.mData[i].mimeTypeCategory = MimeTypeHelper.getCategory(getContext(), fso);
209         }
210     }
211
212     /**
213      * Method that returns the data of the adapter.
214      *
215      * @return List<SearchResult> The adapter data
216      */
217     public List<SearchResult> getData() {
218         int cc = getCount();
219         final List<SearchResult> data = new ArrayList<SearchResult>(cc);
220         for (int i = 0; i < cc; i++) {
221             data.add(getItem(i));
222         }
223         return data;
224     }
225
226     /**
227      * Returns the position of the specified item in the array.
228      *
229      * @param item The item to retrieve the position of.
230      * @return The position of the specified item.
231      */
232     public int getPosition(FileSystemObject item) {
233         int cc = getCount();
234         for (int i = 0; i < cc; i++) {
235             SearchResult sr = getItem(i);
236             if (sr.getFso().compareTo(item) == 0) {
237                 return i;
238             }
239         }
240         return -1;
241     }
242
243     /**
244      * {@inheritDoc}
245      */
246     @Override
247     public View getView(int position, View convertView, ViewGroup parent) {
248
249         //Check to reuse view
250         View v = convertView;
251
252         if (v == null) {
253             //Create the view holder
254             LayoutInflater li =
255                     (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
256             v = li.inflate(this.mItemViewResourceId, parent, false);
257             ViewHolder viewHolder = new SearchResultAdapter.ViewHolder();
258             viewHolder.mIvIcon = (ImageView) v.findViewById(RESOURCE_ITEM_ICON);
259             viewHolder.mTvName = (TextView) v.findViewById(RESOURCE_ITEM_NAME);
260             viewHolder.mTvParentDir = (TextView) v.findViewById(RESOURCE_ITEM_PARENT_DIR);
261             viewHolder.mWgRelevance = (RelevanceView) v.findViewById(RESOURCE_ITEM_RELEVANCE);
262             viewHolder.mMimeType = (TextView) v.findViewById(RESOURCE_ITEM_MIME_TYPE);
263
264             // Apply the current theme
265             Theme theme = ThemeManager.getCurrentTheme(getContext());
266             theme.setTextColor(
267                     getContext(), viewHolder.mTvName, "text_color"); //$NON-NLS-1$
268             if (viewHolder.mTvParentDir != null) {
269                 theme.setTextColor(
270                         getContext(), viewHolder.mTvParentDir, "text_color"); //$NON-NLS-1$
271             }
272             v.setTag(viewHolder);
273         }
274
275         //Retrieve data holder
276         final DataHolder dataHolder = this.mData[position];
277
278         //Retrieve the view holder
279         ViewHolder viewHolder = (ViewHolder) v.getTag();
280
281         //Set the data
282         if (convertView != null) {
283             mIconHolder.cancelLoad(viewHolder.mIvIcon);
284         }
285         mIconHolder.loadDrawable(viewHolder.mIvIcon,
286                 getItem(position).getFso(), dataHolder.mDwIcon);
287
288         viewHolder.mTvName.setText(dataHolder.mName, TextView.BufferType.SPANNABLE);
289         viewHolder.mTvParentDir.setText(dataHolder.mParentDir);
290         if (dataHolder.mRelevance != null) {
291             viewHolder.mWgRelevance.setRelevance(dataHolder.mRelevance.floatValue());
292         }
293         viewHolder.mWgRelevance.setVisibility(
294                 dataHolder.mRelevance != null ? View.VISIBLE : View.GONE);
295         if (dataHolder.mimeTypeCategory != MimeTypeHelper.MimeTypeCategory.NONE) {
296             viewHolder.mMimeType.setVisibility(View.VISIBLE);
297             viewHolder.mMimeType.setText(dataHolder.mimeTypeCategory.name());
298         } else {
299             viewHolder.mMimeType.setVisibility(View.GONE);
300         }
301         //Return the view
302         return v;
303     }
304 }