fixed icon (+naming) to use resolution depended icon and don't scale
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewImagePagerAdapter.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author David A. Velasco
5 * Copyright (C) 2015 ownCloud Inc.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20 package com.owncloud.android.ui.preview;
21
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.Vector;
28
29 import android.accounts.Account;
30 import android.support.v4.app.Fragment;
31 import android.support.v4.app.FragmentManager;
32 import android.support.v4.app.FragmentStatePagerAdapter;
33 import android.view.ViewGroup;
34
35 import com.owncloud.android.datamodel.FileDataStorageManager;
36 import com.owncloud.android.datamodel.OCFile;
37 import com.owncloud.android.ui.fragment.FileFragment;
38 import com.owncloud.android.utils.FileStorageUtils;
39
40 /**
41 * Adapter class that provides Fragment instances
42 */
43 //public class PreviewImagePagerAdapter extends PagerAdapter {
44 public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
45
46 private Vector<OCFile> mImageFiles;
47 private Account mAccount;
48 private Set<Object> mObsoleteFragments;
49 private Set<Integer> mObsoletePositions;
50 private Set<Integer> mDownloadErrors;
51 private FileDataStorageManager mStorageManager;
52
53 private Map<Integer, FileFragment> mCachedFragments;
54
55 /**
56 * Constructor.
57 *
58 * @param fragmentManager {@link FragmentManager} instance that will handle
59 * the {@link Fragment}s provided by the adapter.
60 * @param parentFolder Folder where images will be searched for.
61 * @param storageManager Bridge to database.
62 */
63 public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder,
64 Account account, FileDataStorageManager storageManager,
65 boolean onlyOnDevice) {
66 super(fragmentManager);
67
68 if (fragmentManager == null) {
69 throw new IllegalArgumentException("NULL FragmentManager instance");
70 }
71 if (parentFolder == null) {
72 throw new IllegalArgumentException("NULL parent folder");
73 }
74 if (storageManager == null) {
75 throw new IllegalArgumentException("NULL storage manager");
76 }
77
78 mAccount = account;
79 mStorageManager = storageManager;
80 mImageFiles = mStorageManager.getFolderImages(parentFolder, false);
81
82 mImageFiles = FileStorageUtils.sortFolder(mImageFiles);
83
84 mObsoleteFragments = new HashSet<Object>();
85 mObsoletePositions = new HashSet<Integer>();
86 mDownloadErrors = new HashSet<Integer>();
87 //mFragmentManager = fragmentManager;
88 mCachedFragments = new HashMap<Integer, FileFragment>();
89 }
90
91 /**
92 * Returns the image files handled by the adapter.
93 *
94 * @return A vector with the image files handled by the adapter.
95 */
96 protected OCFile getFileAt(int position) {
97 return mImageFiles.get(position);
98 }
99
100
101 public Fragment getItem(int i) {
102 OCFile file = mImageFiles.get(i);
103 Fragment fragment = null;
104 if (file.isDown()) {
105 fragment = PreviewImageFragment.newInstance(file,
106 mObsoletePositions.contains(Integer.valueOf(i)));
107
108 } else if (mDownloadErrors.contains(Integer.valueOf(i))) {
109 fragment = FileDownloadFragment.newInstance(file, mAccount, true);
110 ((FileDownloadFragment)fragment).setError(true);
111 mDownloadErrors.remove(Integer.valueOf(i));
112
113 } else {
114 fragment = FileDownloadFragment.newInstance(
115 file, mAccount, mObsoletePositions.contains(Integer.valueOf(i))
116 );
117 }
118 mObsoletePositions.remove(Integer.valueOf(i));
119 return fragment;
120 }
121
122 public int getFilePosition(OCFile file) {
123 return mImageFiles.indexOf(file);
124 }
125
126 @Override
127 public int getCount() {
128 return mImageFiles.size();
129 }
130
131 @Override
132 public CharSequence getPageTitle(int position) {
133 return mImageFiles.get(position).getFileName();
134 }
135
136
137 public void updateFile(int position, OCFile file) {
138 FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
139 if (fragmentToUpdate != null) {
140 mObsoleteFragments.add(fragmentToUpdate);
141 }
142 mObsoletePositions.add(Integer.valueOf(position));
143 mImageFiles.set(position, file);
144 }
145
146
147 public void updateWithDownloadError(int position) {
148 FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
149 if (fragmentToUpdate != null) {
150 mObsoleteFragments.add(fragmentToUpdate);
151 }
152 mDownloadErrors.add(Integer.valueOf(position));
153 }
154
155 public void clearErrorAt(int position) {
156 FileFragment fragmentToUpdate = mCachedFragments.get(Integer.valueOf(position));
157 if (fragmentToUpdate != null) {
158 mObsoleteFragments.add(fragmentToUpdate);
159 }
160 mDownloadErrors.remove(Integer.valueOf(position));
161 }
162
163
164 @Override
165 public int getItemPosition(Object object) {
166 if (mObsoleteFragments.contains(object)) {
167 mObsoleteFragments.remove(object);
168 return POSITION_NONE;
169 }
170 return super.getItemPosition(object);
171 }
172
173
174 @Override
175 public Object instantiateItem(ViewGroup container, int position) {
176 Object fragment = super.instantiateItem(container, position);
177 mCachedFragments.put(Integer.valueOf(position), (FileFragment)fragment);
178 return fragment;
179 }
180
181 @Override
182 public void destroyItem(ViewGroup container, int position, Object object) {
183 mCachedFragments.remove(Integer.valueOf(position));
184 super.destroyItem(container, position, object);
185 }
186
187
188 public boolean pendingErrorAt(int position) {
189 return mDownloadErrors.contains(Integer.valueOf(position));
190 }
191
192 /**
193 * Reset the image zoom to default value for each CachedFragments
194 */
195 public void resetZoom() {
196 Iterator<FileFragment> entries = mCachedFragments.values().iterator();
197 while (entries.hasNext()) {
198 FileFragment fileFragment = (FileFragment) entries.next();
199 if (fileFragment instanceof PreviewImageFragment) {
200 ((PreviewImageFragment) fileFragment).getImageView().resetZoom();
201 }
202 }
203 }
204
205 /* -*
206 * Called when a change in the shown pages is going to start being made.
207 *
208 * @param container The containing View which is displaying this adapter's page views.
209 *- /
210 @Override
211 public void startUpdate(ViewGroup container) {
212 Log_OC.e(TAG, "** startUpdate");
213 }
214
215 @Override
216 public Object instantiateItem(ViewGroup container, int position) {
217 Log_OC.e(TAG, "** instantiateItem " + position);
218
219 if (mFragments.size() > position) {
220 Fragment fragment = mFragments.get(position);
221 if (fragment != null) {
222 Log_OC.e(TAG, "** \t returning cached item");
223 return fragment;
224 }
225 }
226
227 if (mCurTransaction == null) {
228 mCurTransaction = mFragmentManager.beginTransaction();
229 }
230
231 Fragment fragment = getItem(position);
232 if (mSavedState.size() > position) {
233 Fragment.SavedState savedState = mSavedState.get(position);
234 if (savedState != null) {
235 // TODO WATCH OUT:
236 // * The Fragment must currently be attached to the FragmentManager.
237 // * A new Fragment created using this saved state must be the same class type as the Fragment it was created from.
238 // * The saved state can not contain dependencies on other fragments -- that is it can't use putFragment(Bundle, String, Fragment)
239 // to store a fragment reference
240 fragment.setInitialSavedState(savedState);
241 }
242 }
243 while (mFragments.size() <= position) {
244 mFragments.add(null);
245 }
246 fragment.setMenuVisibility(false);
247 mFragments.set(position, fragment);
248 //Log_OC.e(TAG, "** \t adding fragment at position " + position + ", containerId " + container.getId());
249 mCurTransaction.add(container.getId(), fragment);
250
251 return fragment;
252 }
253
254 @Override
255 public void destroyItem(ViewGroup container, int position, Object object) {
256 Log_OC.e(TAG, "** destroyItem " + position);
257 Fragment fragment = (Fragment)object;
258
259 if (mCurTransaction == null) {
260 mCurTransaction = mFragmentManager.beginTransaction();
261 }
262 Log_OC.e(TAG, "** \t removing fragment at position " + position);
263 while (mSavedState.size() <= position) {
264 mSavedState.add(null);
265 }
266 mSavedState.set(position, mFragmentManager.saveFragmentInstanceState(fragment));
267 mFragments.set(position, null);
268
269 mCurTransaction.remove(fragment);
270 }
271
272 @Override
273 public void setPrimaryItem(ViewGroup container, int position, Object object) {
274 Fragment fragment = (Fragment)object;
275 if (fragment != mCurrentPrimaryItem) {
276 if (mCurrentPrimaryItem != null) {
277 mCurrentPrimaryItem.setMenuVisibility(false);
278 }
279 if (fragment != null) {
280 fragment.setMenuVisibility(true);
281 }
282 mCurrentPrimaryItem = fragment;
283 }
284 }
285
286 @Override
287 public void finishUpdate(ViewGroup container) {
288 Log_OC.e(TAG, "** finishUpdate (start)");
289 if (mCurTransaction != null) {
290 mCurTransaction.commitAllowingStateLoss();
291 mCurTransaction = null;
292 mFragmentManager.executePendingTransactions();
293 }
294 Log_OC.e(TAG, "** finishUpdate (end)");
295 }
296
297 @Override
298 public boolean isViewFromObject(View view, Object object) {
299 return ((Fragment)object).getView() == view;
300 }
301
302 @Override
303 public Parcelable saveState() {
304 Bundle state = null;
305 if (mSavedState.size() > 0) {
306 state = new Bundle();
307 Fragment.SavedState[] savedStates = new Fragment.SavedState[mSavedState.size()];
308 mSavedState.toArray(savedStates);
309 state.putParcelableArray("states", savedStates);
310 }
311 for (int i=0; i<mFragments.size(); i++) {
312 Fragment fragment = mFragments.get(i);
313 if (fragment != null) {
314 if (state == null) {
315 state = new Bundle();
316 }
317 String key = "f" + i;
318 mFragmentManager.putFragment(state, key, fragment);
319 }
320 }
321 return state;
322 }
323
324 @Override
325 public void restoreState(Parcelable state, ClassLoader loader) {
326 if (state != null) {
327 Bundle bundle = (Bundle)state;
328 bundle.setClassLoader(loader);
329 Parcelable[] states = bundle.getParcelableArray("states");
330 mSavedState.clear();
331 mFragments.clear();
332 if (states != null) {
333 for (int i=0; i<states.length; i++) {
334 mSavedState.add((Fragment.SavedState)states[i]);
335 }
336 }
337 Iterable<String> keys = bundle.keySet();
338 for (String key: keys) {
339 if (key.startsWith("f")) {
340 int index = Integer.parseInt(key.substring(1));
341 Fragment f = mFragmentManager.getFragment(bundle, key);
342 if (f != null) {
343 while (mFragments.size() <= index) {
344 mFragments.add(null);
345 }
346 f.setMenuVisibility(false);
347 mFragments.set(index, f);
348 } else {
349 Log_OC.w(TAG, "Bad fragment at key " + key);
350 }
351 }
352 }
353 }
354 }
355 */
356 }