PreviewImagePagerAdapter.java 12 KB

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