de22b19b3edf529828f2475b7fd96b300daf9b32
[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 if (savedInstanceState == null) {
114 mWaitingToPreview = false;
115 createViewPager();
116 } else {
117 mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
118 }
119
120 mDownloadConnection = new DetailsServiceConnection();
121 bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
122 mUploadConnection = new DetailsServiceConnection();
123 bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
124
125 }
126
127 private void createViewPager() {
128 mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), mParentFolder);
129 mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
130 mViewPager.setAdapter(mPreviewImagePagerAdapter);
131 mViewPager.setOnPageChangeListener(this);
132 }
133
134
135 /**
136 * Adapter class that provides Fragment instances
137 *
138 * @author David A. Velasco
139 */
140 public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
141
142 Vector<OCFile> mImageFiles;
143
144 public PreviewImagePagerAdapter(FragmentManager fm, OCFile parentFolder) {
145 super(fm);
146 mImageFiles = mStorageManager.getDirectoryImages(parentFolder);
147 }
148
149 @Override
150 public Fragment getItem(int i) {
151 Log.e(TAG, "GETTING PAGE " + i);
152 OCFile file = mImageFiles.get(i);
153 Fragment fragment = null;
154 if (file.isDown()) {
155 fragment = new PreviewImageFragment(file, mAccount);
156 mWaitingToPreview = false;
157 } else {
158 fragment = new FileDownloadFragment(file, mAccount); // TODO
159 //mWaitingToPreview = true;
160 }
161 return fragment;
162 }
163
164 @Override
165 public int getCount() {
166 return mImageFiles.size();
167 }
168
169 @Override
170 public CharSequence getPageTitle(int position) {
171 return mImageFiles.get(position).getFileName();
172 }
173 }
174
175
176 @Override
177 protected void onSaveInstanceState(Bundle outState) {
178 super.onSaveInstanceState(outState);
179 outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
180 }
181
182
183 /** Defines callbacks for service binding, passed to bindService() */
184 private class DetailsServiceConnection implements ServiceConnection {
185
186 @Override
187 public void onServiceConnected(ComponentName component, IBinder service) {
188
189 if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
190 Log.d(TAG, "Download service connected");
191 mDownloaderBinder = (FileDownloaderBinder) service;
192 if (mWaitingToPreview) {
193 requestForDownload();
194 }
195
196 } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
197 Log.d(TAG, "Upload service connected");
198 mUploaderBinder = (FileUploaderBinder) service;
199 } else {
200 return;
201 }
202
203 Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
204 FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
205 if (detailsFragment != null) {
206 detailsFragment.listenForTransferProgress();
207 detailsFragment.updateFileDetails(mWaitingToPreview); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
208 }
209 }
210
211 @Override
212 public void onServiceDisconnected(ComponentName component) {
213 if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
214 Log.d(TAG, "Download service disconnected");
215 mDownloaderBinder = null;
216 } else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
217 Log.d(TAG, "Upload service disconnected");
218 mUploaderBinder = null;
219 }
220 }
221 };
222
223
224 @Override
225 public void onDestroy() {
226 super.onDestroy();
227 if (mDownloadConnection != null) {
228 unbindService(mDownloadConnection);
229 mDownloadConnection = null;
230 }
231 if (mUploadConnection != null) {
232 unbindService(mUploadConnection);
233 mUploadConnection = null;
234 }
235 }
236
237
238 @Override
239 public boolean onOptionsItemSelected(MenuItem item) {
240 boolean returnValue = false;
241
242 switch(item.getItemId()){
243 case android.R.id.home:
244 backToDisplayActivity();
245 returnValue = true;
246 break;
247 default:
248 returnValue = super.onOptionsItemSelected(item);
249 }
250
251 return returnValue;
252 }
253
254
255 @Override
256 protected void onResume() {
257 super.onResume();
258 Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
259 if (fragment != null && fragment instanceof FileDetailFragment) {
260 ((FileDetailFragment) fragment).updateFileDetails(false);
261 }
262 }
263
264
265 private void backToDisplayActivity() {
266 /*
267 Intent intent = new Intent(this, FileDisplayActivity.class);
268 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
269 intent.putExtra(FileDetailFragment.EXTRA_FILE, mFile);
270 intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
271 startActivity(intent);
272 */
273 finish();
274 }
275
276
277 @Override
278 protected Dialog onCreateDialog(int id) {
279 Dialog dialog = null;
280 switch (id) {
281 case DIALOG_SHORT_WAIT: {
282 ProgressDialog working_dialog = new ProgressDialog(this);
283 working_dialog.setMessage(getResources().getString(
284 R.string.wait_a_moment));
285 working_dialog.setIndeterminate(true);
286 working_dialog.setCancelable(false);
287 dialog = working_dialog;
288 break;
289 }
290 default:
291 dialog = null;
292 }
293 return dialog;
294 }
295
296
297 /**
298 * {@inheritDoc}
299 */
300 @Override
301 public void onFileStateChanged() {
302 // nothing to do here!
303 }
304
305
306 /**
307 * {@inheritDoc}
308 */
309 @Override
310 public FileDownloaderBinder getFileDownloaderBinder() {
311 return mDownloaderBinder;
312 }
313
314
315 @Override
316 public FileUploaderBinder getFileUploaderBinder() {
317 return mUploaderBinder;
318 }
319
320
321 @Override
322 public void showFragmentWithDetails(OCFile file) {
323 Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
324 showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
325 showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
326 showDetailsIntent.putExtra(FileDetailActivity.EXTRA_MODE, FileDetailActivity.MODE_DETAILS);
327 startActivity(showDetailsIntent);
328 }
329
330
331 private void requestForDownload() {
332 if (!mDownloaderBinder.isDownloading(mAccount, mFile)) {
333 Intent i = new Intent(this, FileDownloader.class);
334 i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
335 i.putExtra(FileDownloader.EXTRA_FILE, mFile);
336 startService(i);
337 }
338 }
339
340 @Override
341 public void notifySuccessfulDownload(OCFile file, Intent intent, boolean success) {
342 if (success) {
343 if (mWaitingToPreview) {
344 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
345 transaction.replace(R.id.fragment, new FilePreviewFragment(file, mAccount), FileDetailFragment.FTAG);
346 transaction.commit();
347 mWaitingToPreview = false;
348 }
349 }
350 }
351
352
353 /**
354 * This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
355 *
356 * @param Position Position index of the new selected page
357 */
358 @Override
359 public void onPageSelected(int position) {
360 OCFile currentFile = ((FileFragment)mPreviewImagePagerAdapter.getItem(position)).getFile();
361 getSupportActionBar().setTitle(currentFile.getFileName());
362 }
363
364 /**
365 * Called when the scroll state changes. Useful for discovering when the user begins dragging,
366 * when the pager is automatically settling to the current page, or when it is fully stopped/idle.
367 *
368 * @param State The new scroll state (SCROLL_STATE_IDLE, _DRAGGING, _SETTLING
369 */
370 @Override
371 public void onPageScrollStateChanged(int state) {
372 }
373
374 /**
375 * This method will be invoked when the current page is scrolled, either as part of a programmatically
376 * initiated smooth scroll or a user initiated touch scroll.
377 *
378 * @param position Position index of the first page currently being displayed.
379 * Page position+1 will be visible if positionOffset is nonzero.
380 *
381 * @param positionOffset Value from [0, 1) indicating the offset from the page at position.
382 * @param positionOffsetPixels Value in pixels indicating the offset from position.
383 */
384 @Override
385 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
386 }
387
388 }