a72a0ef341f2dcb3021bf61086a859a5af719e71
[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.content.SharedPreferences;
29 import android.graphics.Bitmap;
30 import android.preference.PreferenceManager;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.BaseAdapter;
35 import android.widget.ImageView;
36 import android.widget.ListAdapter;
37 import android.widget.ListView;
38 import android.widget.TextView;
39
40 import com.owncloud.android.R;
41 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
42 import com.owncloud.android.lib.common.utils.Log_OC;
43 import com.owncloud.android.utils.BitmapUtils;
44 import com.owncloud.android.utils.DisplayUtils;
45 import com.owncloud.android.utils.MimetypeIconUtil;
46 import com.owncloud.android.utils.FileStorageUtils;
47
48 /**
49 * This Adapter populates a ListView with all files and directories contained
50 * in a local directory
51 */
52 public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
53
54 private static final String TAG = LocalFileListAdapter.class.getSimpleName();
55
56 private Context mContext;
57 private File mDirectory;
58 private File[] mFiles = null;
59 private SharedPreferences mAppPreferences;
60
61 public LocalFileListAdapter(File directory, Context context) {
62 mContext = context;
63
64 mAppPreferences = PreferenceManager
65 .getDefaultSharedPreferences(mContext);
66
67 // Read sorting order, default to sort by name ascending
68 FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0);
69 FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true);
70
71 swapDirectory(directory);
72 }
73
74 @Override
75 public boolean areAllItemsEnabled() {
76 return true;
77 }
78
79 @Override
80 public boolean isEnabled(int position) {
81 return true;
82 }
83
84 @Override
85 public int getCount() {
86 return mFiles != null ? mFiles.length : 0;
87 }
88
89 @Override
90 public Object getItem(int position) {
91 if (mFiles == null || mFiles.length <= position)
92 return null;
93 return mFiles[position];
94 }
95
96 @Override
97 public long getItemId(int position) {
98 return mFiles != null && mFiles.length <= position ? position : -1;
99 }
100
101 @Override
102 public int getItemViewType(int position) {
103 return 0;
104 }
105
106 @Override
107 public View getView(int position, View convertView, ViewGroup parent) {
108 View view = convertView;
109 if (view == null) {
110 LayoutInflater inflator = (LayoutInflater) mContext
111 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
112 view = inflator.inflate(R.layout.list_item, null);
113 }
114 if (mFiles != null && mFiles.length > position) {
115 File file = mFiles[position];
116
117 TextView fileName = (TextView) view.findViewById(R.id.Filename);
118 String name = file.getName();
119 fileName.setText(name);
120
121 ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);
122
123 /** Cancellation needs do be checked and done before changing the drawable in fileIcon, or
124 * {@link ThumbnailsCacheManager#cancelPotentialWork} will NEVER cancel any task.
125 **/
126 boolean allowedToCreateNewThumbnail = (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon));
127
128 if (!file.isDirectory()) {
129 fileIcon.setImageResource(R.drawable.file);
130 } else {
131 fileIcon.setImageResource(R.drawable.ic_menu_archive);
132 }
133 fileIcon.setTag(file.hashCode());
134
135 TextView fileSizeV = (TextView) view.findViewById(R.id.last_size);
136 TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);
137 TextView lastModV = (TextView) view.findViewById(R.id.file_mod);
138 ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
139 if (!file.isDirectory()) {
140 fileSizeSeparatorV.setVisibility(View.VISIBLE);
141 fileSizeV.setVisibility(View.VISIBLE);
142 fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
143
144 lastModV.setVisibility(View.VISIBLE);
145 lastModV.setText(DisplayUtils.unixTimeToHumanReadable(file.lastModified()));
146 ListView parentList = (ListView) parent;
147 if (parentList.getChoiceMode() == ListView.CHOICE_MODE_NONE) {
148 checkBoxV.setVisibility(View.GONE);
149 } else {
150 if (parentList.isItemChecked(position)) {
151 checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
152 } else {
153 checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
154 }
155 checkBoxV.setVisibility(View.VISIBLE);
156 }
157
158 // get Thumbnail if file is image
159 if (BitmapUtils.isImage(file)){
160 // Thumbnail in Cache?
161 Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
162 String.valueOf(file.hashCode())
163 );
164 if (thumbnail != null){
165 fileIcon.setImageBitmap(thumbnail);
166 } else {
167
168 // generate new Thumbnail
169 if (allowedToCreateNewThumbnail) {
170 final ThumbnailsCacheManager.ThumbnailGenerationTask task =
171 new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon);
172 if (thumbnail == null) {
173 thumbnail = ThumbnailsCacheManager.mDefaultImg;
174 }
175 final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
176 new ThumbnailsCacheManager.AsyncDrawable(
177 mContext.getResources(),
178 thumbnail,
179 task
180 );
181 fileIcon.setImageDrawable(asyncDrawable);
182 task.execute(file);
183 Log_OC.v(TAG, "Executing task to generate a new thumbnail");
184
185 } // else, already being generated, don't restart it
186 }
187 } else {
188 fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(null, file.getName()));
189 }
190
191 } else {
192 fileSizeSeparatorV.setVisibility(View.GONE);
193 fileSizeV.setVisibility(View.GONE);
194 lastModV.setVisibility(View.GONE);
195 checkBoxV.setVisibility(View.GONE);
196 }
197
198 // not GONE; the alignment changes; ugly way to keep it
199 view.findViewById(R.id.localFileIndicator).setVisibility(View.INVISIBLE);
200 view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE);
201
202 view.findViewById(R.id.sharedIcon).setVisibility(View.GONE);
203 view.findViewById(R.id.sharedWithMeIcon).setVisibility(View.GONE);
204 }
205
206 return view;
207 }
208
209 @Override
210 public int getViewTypeCount() {
211 return 1;
212 }
213
214 @Override
215 public boolean hasStableIds() {
216 return false;
217 }
218
219 @Override
220 public boolean isEmpty() {
221 return (mFiles == null || mFiles.length == 0);
222 }
223
224 /**
225 * Change the adapted directory for a new one
226 * @param directory New file to adapt. Can be NULL, meaning "no content to adapt".
227 */
228 public void swapDirectory(File directory) {
229 mDirectory = directory;
230 mFiles = (mDirectory != null ? mDirectory.listFiles() : null);
231 if (mFiles != null) {
232 Arrays.sort(mFiles, new Comparator<File>() {
233 @Override
234 public int compare(File lhs, File rhs) {
235 if (lhs.isDirectory() && !rhs.isDirectory()) {
236 return -1;
237 } else if (!lhs.isDirectory() && rhs.isDirectory()) {
238 return 1;
239 }
240 return compareNames(lhs, rhs);
241 }
242
243 private int compareNames(File lhs, File rhs) {
244 return lhs.getName().toLowerCase().compareTo(rhs.getName().toLowerCase());
245 }
246
247 });
248
249 mFiles = FileStorageUtils.sortLocalFolder(mFiles);
250 }
251 notifyDataSetChanged();
252 }
253
254 public void setSortOrder(Integer order, boolean ascending) {
255 SharedPreferences.Editor editor = mAppPreferences.edit();
256 editor.putInt("sortOrder", order);
257 editor.putBoolean("sortAscending", ascending);
258 editor.commit();
259
260 FileStorageUtils.mSortOrder = order;
261 FileStorageUtils.mSortAscending = ascending;
262
263 mFiles = FileStorageUtils.sortLocalFolder(mFiles);
264 notifyDataSetChanged();
265
266 }
267 }