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