PreviewImageActivity.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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 as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. */
  18. package com.owncloud.android.ui.activity;
  19. import java.util.Vector;
  20. import android.accounts.Account;
  21. import android.app.Dialog;
  22. import android.app.ProgressDialog;
  23. import android.content.ComponentName;
  24. import android.content.Context;
  25. import android.content.Intent;
  26. import android.content.ServiceConnection;
  27. import android.os.Bundle;
  28. import android.os.IBinder;
  29. import android.support.v4.app.Fragment;
  30. import android.support.v4.app.FragmentManager;
  31. import android.support.v4.app.FragmentStatePagerAdapter;
  32. import android.support.v4.app.FragmentTransaction;
  33. import android.support.v4.view.ViewPager;
  34. import android.util.Log;
  35. import com.actionbarsherlock.app.ActionBar;
  36. import com.actionbarsherlock.app.SherlockFragmentActivity;
  37. import com.actionbarsherlock.view.MenuItem;
  38. import com.owncloud.android.datamodel.DataStorageManager;
  39. import com.owncloud.android.datamodel.FileDataStorageManager;
  40. import com.owncloud.android.datamodel.OCFile;
  41. import com.owncloud.android.files.services.FileDownloader;
  42. import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
  43. import com.owncloud.android.files.services.FileUploader;
  44. import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
  45. import com.owncloud.android.ui.fragment.FileDetailFragment;
  46. import com.owncloud.android.ui.fragment.FileDownloadFragment;
  47. import com.owncloud.android.ui.fragment.FileFragment;
  48. import com.owncloud.android.ui.fragment.FilePreviewFragment;
  49. import com.owncloud.android.ui.fragment.PreviewImageFragment;
  50. import com.owncloud.android.AccountUtils;
  51. import com.owncloud.android.R;
  52. /**
  53. * Used as an utility to preview image files contained in an ownCloud account.
  54. *
  55. * @author David A. Velasco
  56. */
  57. public class PreviewImageActivity extends SherlockFragmentActivity implements FileFragment.ContainerActivity, ViewPager.OnPageChangeListener {
  58. public static final int DIALOG_SHORT_WAIT = 0;
  59. public static final String TAG = PreviewImageActivity.class.getSimpleName();
  60. public static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
  61. private OCFile mFile;
  62. private OCFile mParentFolder;
  63. private Account mAccount;
  64. private DataStorageManager mStorageManager;
  65. private ViewPager mViewPager;
  66. private PreviewImagePagerAdapter mPreviewImagePagerAdapter;
  67. private FileDownloaderBinder mDownloaderBinder = null;
  68. private ServiceConnection mDownloadConnection, mUploadConnection = null;
  69. private FileUploaderBinder mUploaderBinder = null;
  70. private boolean mWaitingToPreview;
  71. @Override
  72. protected void onCreate(Bundle savedInstanceState) {
  73. super.onCreate(savedInstanceState);
  74. mFile = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
  75. mAccount = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
  76. if (mFile == null) {
  77. throw new IllegalStateException("Instanced with a NULL OCFile");
  78. }
  79. if (mAccount == null) {
  80. throw new IllegalStateException("Instanced with a NULL ownCloud Account");
  81. }
  82. if (!mFile.isImage()) {
  83. throw new IllegalArgumentException("Non-image file passed as argument");
  84. }
  85. setContentView(R.layout.preview_image_activity);
  86. ActionBar actionBar = getSupportActionBar();
  87. actionBar.setDisplayHomeAsUpEnabled(true);
  88. actionBar.setTitle(mFile.getFileName());
  89. mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
  90. mParentFolder = mStorageManager.getFileById(mFile.getParentId());
  91. if (mParentFolder == null) {
  92. // should not be necessary
  93. mParentFolder = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
  94. }
  95. createViewPager();
  96. if (savedInstanceState == null) {
  97. mWaitingToPreview = false;
  98. } else {
  99. mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
  100. }
  101. mDownloadConnection = new DetailsServiceConnection();
  102. bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
  103. mUploadConnection = new DetailsServiceConnection();
  104. bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
  105. }
  106. private void createViewPager() {
  107. mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), mParentFolder);
  108. mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
  109. mViewPager.setAdapter(mPreviewImagePagerAdapter);
  110. mViewPager.setOnPageChangeListener(this);
  111. }
  112. /**
  113. * Adapter class that provides Fragment instances
  114. *
  115. * @author David A. Velasco
  116. */
  117. public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
  118. Vector<OCFile> mImageFiles;
  119. public PreviewImagePagerAdapter(FragmentManager fm, OCFile parentFolder) {
  120. super(fm);
  121. mImageFiles = mStorageManager.getDirectoryImages(parentFolder);
  122. }
  123. @Override
  124. public Fragment getItem(int i) {
  125. Log.e(TAG, "GETTING PAGE " + i);
  126. OCFile file = mImageFiles.get(i);
  127. Fragment fragment = null;
  128. if (file.isDown()) {
  129. fragment = new PreviewImageFragment(file, mAccount);
  130. mWaitingToPreview = false;
  131. } else {
  132. fragment = new FileDownloadFragment(file, mAccount); // TODO
  133. //mWaitingToPreview = true;
  134. }
  135. return fragment;
  136. }
  137. @Override
  138. public int getCount() {
  139. return mImageFiles.size();
  140. }
  141. @Override
  142. public CharSequence getPageTitle(int position) {
  143. return mImageFiles.get(position).getFileName();
  144. }
  145. }
  146. @Override
  147. protected void onSaveInstanceState(Bundle outState) {
  148. super.onSaveInstanceState(outState);
  149. outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
  150. }
  151. /** Defines callbacks for service binding, passed to bindService() */
  152. private class DetailsServiceConnection implements ServiceConnection {
  153. @Override
  154. public void onServiceConnected(ComponentName component, IBinder service) {
  155. if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
  156. Log.d(TAG, "Download service connected");
  157. mDownloaderBinder = (FileDownloaderBinder) service;
  158. if (mWaitingToPreview) {
  159. requestForDownload();
  160. }
  161. } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
  162. Log.d(TAG, "Upload service connected");
  163. mUploaderBinder = (FileUploaderBinder) service;
  164. } else {
  165. return;
  166. }
  167. Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
  168. FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
  169. if (detailsFragment != null) {
  170. detailsFragment.listenForTransferProgress();
  171. detailsFragment.updateFileDetails(mWaitingToPreview); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
  172. }
  173. }
  174. @Override
  175. public void onServiceDisconnected(ComponentName component) {
  176. if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
  177. Log.d(TAG, "Download service disconnected");
  178. mDownloaderBinder = null;
  179. } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
  180. Log.d(TAG, "Upload service disconnected");
  181. mUploaderBinder = null;
  182. }
  183. }
  184. };
  185. @Override
  186. public void onDestroy() {
  187. super.onDestroy();
  188. if (mDownloadConnection != null) {
  189. unbindService(mDownloadConnection);
  190. mDownloadConnection = null;
  191. }
  192. if (mUploadConnection != null) {
  193. unbindService(mUploadConnection);
  194. mUploadConnection = null;
  195. }
  196. }
  197. @Override
  198. public boolean onOptionsItemSelected(MenuItem item) {
  199. boolean returnValue = false;
  200. switch(item.getItemId()){
  201. case android.R.id.home:
  202. backToDisplayActivity();
  203. returnValue = true;
  204. break;
  205. default:
  206. returnValue = super.onOptionsItemSelected(item);
  207. }
  208. return returnValue;
  209. }
  210. @Override
  211. protected void onResume() {
  212. super.onResume();
  213. Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
  214. if (fragment != null && fragment instanceof FileDetailFragment) {
  215. ((FileDetailFragment) fragment).updateFileDetails(false);
  216. }
  217. }
  218. private void backToDisplayActivity() {
  219. /*
  220. Intent intent = new Intent(this, FileDisplayActivity.class);
  221. intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  222. intent.putExtra(FileDetailFragment.EXTRA_FILE, mFile);
  223. intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
  224. startActivity(intent);
  225. */
  226. finish();
  227. }
  228. @Override
  229. protected Dialog onCreateDialog(int id) {
  230. Dialog dialog = null;
  231. switch (id) {
  232. case DIALOG_SHORT_WAIT: {
  233. ProgressDialog working_dialog = new ProgressDialog(this);
  234. working_dialog.setMessage(getResources().getString(
  235. R.string.wait_a_moment));
  236. working_dialog.setIndeterminate(true);
  237. working_dialog.setCancelable(false);
  238. dialog = working_dialog;
  239. break;
  240. }
  241. default:
  242. dialog = null;
  243. }
  244. return dialog;
  245. }
  246. /**
  247. * {@inheritDoc}
  248. */
  249. @Override
  250. public void onFileStateChanged() {
  251. // nothing to do here!
  252. }
  253. /**
  254. * {@inheritDoc}
  255. */
  256. @Override
  257. public FileDownloaderBinder getFileDownloaderBinder() {
  258. return mDownloaderBinder;
  259. }
  260. @Override
  261. public FileUploaderBinder getFileUploaderBinder() {
  262. return mUploaderBinder;
  263. }
  264. @Override
  265. public void showFragmentWithDetails(OCFile file) {
  266. Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
  267. showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
  268. showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
  269. showDetailsIntent.putExtra(FileDetailActivity.EXTRA_MODE, FileDetailActivity.MODE_DETAILS);
  270. startActivity(showDetailsIntent);
  271. }
  272. private void requestForDownload() {
  273. if (!mDownloaderBinder.isDownloading(mAccount, mFile)) {
  274. Intent i = new Intent(this, FileDownloader.class);
  275. i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
  276. i.putExtra(FileDownloader.EXTRA_FILE, mFile);
  277. startService(i);
  278. }
  279. }
  280. @Override
  281. public void notifySuccessfulDownload(OCFile file, Intent intent, boolean success) {
  282. if (success) {
  283. if (mWaitingToPreview) {
  284. FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
  285. transaction.replace(R.id.fragment, new FilePreviewFragment(file, mAccount), FileDetailFragment.FTAG);
  286. transaction.commit();
  287. mWaitingToPreview = false;
  288. }
  289. }
  290. }
  291. /**
  292. * This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
  293. *
  294. * @param Position Position index of the new selected page
  295. */
  296. @Override
  297. public void onPageSelected(int position) {
  298. OCFile currentFile = ((FileFragment)mPreviewImagePagerAdapter.getItem(position)).getFile();
  299. getSupportActionBar().setTitle(currentFile.getFileName());
  300. }
  301. /**
  302. * Called when the scroll state changes. Useful for discovering when the user begins dragging,
  303. * when the pager is automatically settling to the current page, or when it is fully stopped/idle.
  304. *
  305. * @param State The new scroll state (SCROLL_STATE_IDLE, _DRAGGING, _SETTLING
  306. */
  307. @Override
  308. public void onPageScrollStateChanged(int state) {
  309. }
  310. /**
  311. * This method will be invoked when the current page is scrolled, either as part of a programmatically
  312. * initiated smooth scroll or a user initiated touch scroll.
  313. *
  314. * @param position Position index of the first page currently being displayed.
  315. * Page position+1 will be visible if positionOffset is nonzero.
  316. *
  317. * @param positionOffset Value from [0, 1) indicating the offset from the page at position.
  318. * @param positionOffsetPixels Value in pixels indicating the offset from position.
  319. */
  320. @Override
  321. public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  322. }
  323. }