PreviewImagePagerAdapter.java 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. import android.accounts.Account;
  22. import android.graphics.Matrix;
  23. import android.util.SparseArray;
  24. import android.view.ViewGroup;
  25. import com.nextcloud.client.preferences.AppPreferences;
  26. import com.owncloud.android.datamodel.FileDataStorageManager;
  27. import com.owncloud.android.datamodel.OCFile;
  28. import com.owncloud.android.datamodel.VirtualFolderType;
  29. import com.owncloud.android.ui.fragment.FileFragment;
  30. import com.owncloud.android.utils.FileSortOrder;
  31. import com.owncloud.android.utils.FileStorageUtils;
  32. import java.util.HashSet;
  33. import java.util.List;
  34. import java.util.Set;
  35. import javax.annotation.Nullable;
  36. import androidx.annotation.NonNull;
  37. import androidx.fragment.app.Fragment;
  38. import androidx.fragment.app.FragmentManager;
  39. import androidx.fragment.app.FragmentStatePagerAdapter;
  40. /**
  41. * Adapter class that provides Fragment instances
  42. */
  43. public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
  44. private List<OCFile> mImageFiles;
  45. private Account mAccount;
  46. private Set<Object> mObsoleteFragments;
  47. private Set<Integer> mObsoletePositions;
  48. private Set<Integer> mDownloadErrors;
  49. private FileDataStorageManager mStorageManager;
  50. private SparseArray<FileFragment> mCachedFragments;
  51. /**
  52. * Constructor
  53. *
  54. * @param fragmentManager {@link FragmentManager} instance that will handle
  55. * the {@link Fragment}s provided by the adapter.
  56. * @param parentFolder Folder where images will be searched for.
  57. * @param storageManager Bridge to database.
  58. */
  59. public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder,
  60. Account account, FileDataStorageManager storageManager,
  61. boolean onlyOnDevice, AppPreferences preferences) {
  62. super(fragmentManager);
  63. if (fragmentManager == null) {
  64. throw new IllegalArgumentException("NULL FragmentManager instance");
  65. }
  66. if (parentFolder == null) {
  67. throw new IllegalArgumentException("NULL parent folder");
  68. }
  69. if (storageManager == null) {
  70. throw new IllegalArgumentException("NULL storage manager");
  71. }
  72. mAccount = account;
  73. mStorageManager = storageManager;
  74. mImageFiles = mStorageManager.getFolderImages(parentFolder, onlyOnDevice);
  75. FileSortOrder sortOrder = preferences.getSortOrderByFolder(parentFolder);
  76. mImageFiles = sortOrder.sortCloudFiles(mImageFiles);
  77. mObsoleteFragments = new HashSet<>();
  78. mObsoletePositions = new HashSet<>();
  79. mDownloadErrors = new HashSet<>();
  80. mCachedFragments = new SparseArray<>();
  81. }
  82. /**
  83. * Constructor
  84. *
  85. * @param fragmentManager {@link FragmentManager} instance that will handle
  86. * the {@link Fragment}s provided by the adapter.
  87. * @param type Type of virtual folder, e.g. favorite or photos
  88. * @param storageManager Bridge to database.
  89. */
  90. public PreviewImagePagerAdapter(FragmentManager fragmentManager, VirtualFolderType type,
  91. Account account, FileDataStorageManager storageManager) {
  92. super(fragmentManager);
  93. if (fragmentManager == null) {
  94. throw new IllegalArgumentException("NULL FragmentManager instance");
  95. }
  96. if (type == null) {
  97. throw new IllegalArgumentException("NULL parent folder");
  98. }
  99. if (storageManager == null) {
  100. throw new IllegalArgumentException("NULL storage manager");
  101. }
  102. mAccount = account;
  103. mStorageManager = storageManager;
  104. mImageFiles = mStorageManager.getVirtualFolderContent(type, true);
  105. if (type == VirtualFolderType.PHOTOS) {
  106. mImageFiles = FileStorageUtils.sortOcFolderDescDateModifiedWithoutFavoritesFirst(mImageFiles);
  107. }
  108. mObsoleteFragments = new HashSet<>();
  109. mObsoletePositions = new HashSet<>();
  110. mDownloadErrors = new HashSet<>();
  111. mCachedFragments = new SparseArray<>();
  112. }
  113. /**
  114. * Returns the image files handled by the adapter.
  115. *
  116. * @return OCFile desired image or null if position is not in adapter
  117. */
  118. @Nullable
  119. public OCFile getFileAt(int position) {
  120. try {
  121. return mImageFiles.get(position);
  122. } catch (IndexOutOfBoundsException exception) {
  123. return null;
  124. }
  125. }
  126. public Fragment getItem(int i) {
  127. OCFile file = getFileAt(i);
  128. Fragment fragment;
  129. if (file == null) {
  130. fragment = PreviewImageErrorFragment.newInstance();
  131. } else if (file.isDown()) {
  132. fragment = PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), false);
  133. } else {
  134. if (mDownloadErrors.remove(i)) {
  135. fragment = FileDownloadFragment.newInstance(file, mAccount, true);
  136. ((FileDownloadFragment) fragment).setError(true);
  137. } else {
  138. if (file.isEncrypted()) {
  139. fragment = FileDownloadFragment.newInstance(file, mAccount, mObsoletePositions.contains(i));
  140. } else {
  141. fragment = PreviewImageFragment.newInstance(file, mObsoletePositions.contains(i), true);
  142. }
  143. }
  144. }
  145. mObsoletePositions.remove(i);
  146. return fragment;
  147. }
  148. public int getFilePosition(OCFile file) {
  149. return mImageFiles.indexOf(file);
  150. }
  151. @Override
  152. public int getCount() {
  153. return mImageFiles.size();
  154. }
  155. @Override
  156. public CharSequence getPageTitle(int position) {
  157. OCFile file = getFileAt(position);
  158. if (file != null) {
  159. return file.getFileName();
  160. } else {
  161. return "";
  162. }
  163. }
  164. public void updateFile(int position, OCFile file) {
  165. FileFragment fragmentToUpdate = mCachedFragments.get(position);
  166. if (fragmentToUpdate != null) {
  167. mObsoleteFragments.add(fragmentToUpdate);
  168. }
  169. mObsoletePositions.add(position);
  170. mImageFiles.set(position, file);
  171. }
  172. public void updateWithDownloadError(int position) {
  173. FileFragment fragmentToUpdate = mCachedFragments.get(position);
  174. if (fragmentToUpdate != null) {
  175. mObsoleteFragments.add(fragmentToUpdate);
  176. }
  177. mDownloadErrors.add(position);
  178. }
  179. @Override
  180. public int getItemPosition(@NonNull Object object) {
  181. if (mObsoleteFragments.remove(object)) {
  182. return POSITION_NONE;
  183. }
  184. return super.getItemPosition(object);
  185. }
  186. @NonNull
  187. @Override
  188. public Object instantiateItem(@NonNull ViewGroup container, int position) {
  189. Object fragment = super.instantiateItem(container, position);
  190. mCachedFragments.put(position, (FileFragment) fragment);
  191. return fragment;
  192. }
  193. @Override
  194. public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
  195. mCachedFragments.remove(position);
  196. super.destroyItem(container, position, object);
  197. }
  198. public boolean pendingErrorAt(int position) {
  199. return mDownloadErrors.contains(position);
  200. }
  201. /**
  202. * Reset the image zoom to default value for each CachedFragments
  203. */
  204. public void resetZoom() {
  205. Matrix matrix = new Matrix();
  206. for (int i = 0; i < mCachedFragments.size(); i++) {
  207. FileFragment fileFragment = mCachedFragments.valueAt(i);
  208. if (fileFragment instanceof PreviewImageFragment) {
  209. ((PreviewImageFragment) fileFragment).getImageView().setDisplayMatrix(matrix);
  210. ((PreviewImageFragment) fileFragment).getImageView().setSuppMatrix(matrix);
  211. }
  212. }
  213. }
  214. }