60675f466d38fb73aea5f13671d6881c8a03f65e
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / adapter / LocalFileListAdapter.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author David A. Velasco
5 * Copyright (C) 2011 Bartek Przybylski
6 * Copyright (C) 2015 ownCloud Inc.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21 package com.owncloud.android.ui.adapter;
22
23 import java.io.File;
24 import java.util.Arrays;
25 import java.util.Comparator;
26
27 import android.content.Context;
28 import android.graphics.Bitmap;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.view.ViewGroup;
32 import android.widget.BaseAdapter;
33 import android.widget.ImageView;
34 import android.widget.ListAdapter;
35 import android.widget.ListView;
36 import android.widget.TextView;
37
38 import com.owncloud.android.R;
39 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
40 import com.owncloud.android.lib.common.utils.Log_OC;
41 import com.owncloud.android.utils.BitmapUtils;
42 import com.owncloud.android.utils.DisplayUtils;
43 import com.owncloud.android.utils.MimetypeIconUtil;
44
45 /**
46 * This Adapter populates a ListView with all files and directories contained
47 * in a local directory
48 */
49 public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
50
51 private static final String TAG = LocalFileListAdapter.class.getSimpleName();
52
53 private Context mContext;
54 private File mDirectory;
55 private File[] mFiles = null;
56
57 public LocalFileListAdapter(File directory, Context context) {
58 mContext = context;
59 swapDirectory(directory);
60 }
61
62 @Override
63 public boolean areAllItemsEnabled() {
64 return true;
65 }
66
67 @Override
68 public boolean isEnabled(int position) {
69 return true;
70 }
71
72 @Override
73 public int getCount() {
74 return mFiles != null ? mFiles.length : 0;
75 }
76
77 @Override
78 public Object getItem(int position) {
79 if (mFiles == null || mFiles.length <= position)
80 return null;
81 return mFiles[position];
82 }
83
84 @Override
85 public long getItemId(int position) {
86 return mFiles != null && mFiles.length <= position ? position : -1;
87 }
88
89 @Override
90 public int getItemViewType(int position) {
91 return 0;
92 }
93
94 @Override
95 public View getView(int position, View convertView, ViewGroup parent) {
96 View view = convertView;
97 if (view == null) {
98 LayoutInflater inflator = (LayoutInflater) mContext
99 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
100 view = inflator.inflate(R.layout.list_item, null);
101 }
102 if (mFiles != null && mFiles.length > position) {
103 File file = mFiles[position];
104
105 TextView fileName = (TextView) view.findViewById(R.id.Filename);
106 String name = file.getName();
107 fileName.setText(name);
108
109 ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);
110
111 /** Cancellation needs do be checked and done before changing the drawable in fileIcon, or
112 * {@link ThumbnailsCacheManager#cancelPotentialWork} will NEVER cancel any task.
113 **/
114 boolean allowedToCreateNewThumbnail = (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon));
115
116 if (!file.isDirectory()) {
117 fileIcon.setImageResource(R.drawable.file);
118 } else {
119 fileIcon.setImageResource(R.drawable.ic_menu_archive);
120 }
121 fileIcon.setTag(file.hashCode());
122
123 TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
124 TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
125 ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
126 if (!file.isDirectory()) {
127 fileSizeV.setVisibility(View.VISIBLE);
128 fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
129
130 lastModV.setVisibility(View.VISIBLE);
131 lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.lastModified()));
132 ListView parentList = (ListView) parent;
133 if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) {
134 checkBoxV.setVisibility(View.GONE);
135 } else {
136 if (parentList.isItemChecked(position)) {
137 checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
138 } else {
139 checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
140 }
141 checkBoxV.setVisibility(View.VISIBLE);
142 }
143
144 // get Thumbnail if file is image
145 if (BitmapUtils.isImage(file)){
146 // Thumbnail in Cache?
147 Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
148 String.valueOf(file.hashCode())
149 );
150 if (thumbnail != null){
151 fileIcon.setImageBitmap(thumbnail);
152 } else {
153
154 // generate new Thumbnail
155 if (allowedToCreateNewThumbnail) {
156 final ThumbnailsCacheManager.ThumbnailGenerationTask task =
157 new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon);
158 if (thumbnail == null) {
159 thumbnail = ThumbnailsCacheManager.mDefaultImg;
160 }
161 final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
162 new ThumbnailsCacheManager.AsyncDrawable(
163 mContext.getResources(),
164 thumbnail,
165 task
166 );
167 fileIcon.setImageDrawable(asyncDrawable);
168 task.execute(file);
169 Log_OC.v(TAG, "Executing task to generate a new thumbnail");
170
171 } // else, already being generated, don't restart it
172 }
173 } else {
174 fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(null, file.getName()));
175 }
176
177 } else {
178 fileSizeV.setVisibility(View.GONE);
179 lastModV.setVisibility(View.GONE);
180 checkBoxV.setVisibility(View.GONE);
181 }
182
183 // not GONE; the alignment changes; ugly way to keep it
184 view.findViewById(R.id.localFileIndicator).setVisibility(View.INVISIBLE);
185 view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);
186
187 view.findViewById(R.id.sharedIcon).setVisibility(View.GONE);
188 view.findViewById(R.id.sharedWithMeIcon).setVisibility(View.GONE);
189 }
190
191 return view;
192 }
193
194 @Override
195 public int getViewTypeCount() {
196 return 1;
197 }
198
199 @Override
200 public boolean hasStableIds() {
201 return false;
202 }
203
204 @Override
205 public boolean isEmpty() {
206 return (mFiles == null || mFiles.length == 0);
207 }
208
209 /**
210 * Change the adapted directory for a new one
211 * @param directory New file to adapt. Can be NULL, meaning "no content to adapt".
212 */
213 public void swapDirectory(File directory) {
214 mDirectory = directory;
215 mFiles = (mDirectory != null ? mDirectory.listFiles() : null);
216 if (mFiles != null) {
217 Arrays.sort(mFiles, new Comparator<File>() {
218 @Override
219 public int compare(File lhs, File rhs) {
220 if (lhs.isDirectory() && !rhs.isDirectory()) {
221 return -1;
222 } else if (!lhs.isDirectory() && rhs.isDirectory()) {
223 return 1;
224 }
225 return compareNames(lhs, rhs);
226 }
227
228 private int compareNames(File lhs, File rhs) {
229 return lhs.getName().toLowerCase().compareTo(rhs.getName().toLowerCase());
230 }
231
232 });
233 }
234 notifyDataSetChanged();
235 }
236 }