/* ownCloud Android client application
* Copyright (C) 2012-2013 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
package com.owncloud.android.ui.activity;
import java.util.Vector;
import android.accounts.Account;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.owncloud.android.datamodel.DataStorageManager;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileDownloader;
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.ui.fragment.FileDetailFragment;
import com.owncloud.android.ui.fragment.FileDownloadFragment;
import com.owncloud.android.ui.fragment.FileFragment;
import com.owncloud.android.ui.fragment.FilePreviewFragment;
import com.owncloud.android.ui.fragment.PreviewImageFragment;
import com.owncloud.android.AccountUtils;
import com.owncloud.android.R;
/**
* Used as an utility to preview image files contained in an ownCloud account.
*
* @author David A. Velasco
*/
public class PreviewImageActivity extends SherlockFragmentActivity implements FileFragment.ContainerActivity, ViewPager.OnPageChangeListener {
public static final int DIALOG_SHORT_WAIT = 0;
public static final String TAG = PreviewImageActivity.class.getSimpleName();
public static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
private OCFile mFile;
private OCFile mParentFolder;
private Account mAccount;
private DataStorageManager mStorageManager;
private ViewPager mViewPager;
private PreviewImagePagerAdapter mPreviewImagePagerAdapter;
private FileDownloaderBinder mDownloaderBinder = null;
private ServiceConnection mDownloadConnection, mUploadConnection = null;
private FileUploaderBinder mUploaderBinder = null;
private boolean mWaitingToPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFile = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
mAccount = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
if (mFile == null) {
throw new IllegalStateException("Instanced with a NULL OCFile");
}
if (mAccount == null) {
throw new IllegalStateException("Instanced with a NULL ownCloud Account");
}
if (!mFile.isImage()) {
throw new IllegalArgumentException("Non-image file passed as argument");
}
setContentView(R.layout.preview_image_activity);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle(mFile.getFileName());
mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
mParentFolder = mStorageManager.getFileById(mFile.getParentId());
if (mParentFolder == null) {
// should not be necessary
mParentFolder = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
}
createViewPager();
if (savedInstanceState == null) {
mWaitingToPreview = false;
} else {
mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
}
mDownloadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
mUploadConnection = new DetailsServiceConnection();
bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
}
private void createViewPager() {
mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(), mParentFolder);
mViewPager = (ViewPager) findViewById(R.id.fragmentPager);
mViewPager.setAdapter(mPreviewImagePagerAdapter);
mViewPager.setOnPageChangeListener(this);
}
/**
* Adapter class that provides Fragment instances
*
* @author David A. Velasco
*/
public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
Vector mImageFiles;
public PreviewImagePagerAdapter(FragmentManager fm, OCFile parentFolder) {
super(fm);
mImageFiles = mStorageManager.getDirectoryImages(parentFolder);
}
@Override
public Fragment getItem(int i) {
Log.e(TAG, "GETTING PAGE " + i);
OCFile file = mImageFiles.get(i);
Fragment fragment = null;
if (file.isDown()) {
fragment = new PreviewImageFragment(file, mAccount);
mWaitingToPreview = false;
} else {
fragment = new FileDownloadFragment(file, mAccount); // TODO
//mWaitingToPreview = true;
}
return fragment;
}
@Override
public int getCount() {
return mImageFiles.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mImageFiles.get(position).getFileName();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
}
/** Defines callbacks for service binding, passed to bindService() */
private class DetailsServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service connected");
mDownloaderBinder = (FileDownloaderBinder) service;
if (mWaitingToPreview) {
requestForDownload();
}
} else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service connected");
mUploaderBinder = (FileUploaderBinder) service;
} else {
return;
}
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
if (detailsFragment != null) {
detailsFragment.listenForTransferProgress();
detailsFragment.updateFileDetails(mWaitingToPreview); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
}
}
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(PreviewImageActivity.this, FileDownloader.class))) {
Log.d(TAG, "Download service disconnected");
mDownloaderBinder = null;
} else if (component.equals(new ComponentName(PreviewImageActivity.this, FileUploader.class))) {
Log.d(TAG, "Upload service disconnected");
mUploaderBinder = null;
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
if (mDownloadConnection != null) {
unbindService(mDownloadConnection);
mDownloadConnection = null;
}
if (mUploadConnection != null) {
unbindService(mUploadConnection);
mUploadConnection = null;
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean returnValue = false;
switch(item.getItemId()){
case android.R.id.home:
backToDisplayActivity();
returnValue = true;
break;
default:
returnValue = super.onOptionsItemSelected(item);
}
return returnValue;
}
@Override
protected void onResume() {
super.onResume();
Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
if (fragment != null && fragment instanceof FileDetailFragment) {
((FileDetailFragment) fragment).updateFileDetails(false);
}
}
private void backToDisplayActivity() {
/*
Intent intent = new Intent(this, FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(FileDetailFragment.EXTRA_FILE, mFile);
intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, mAccount);
startActivity(intent);
*/
finish();
}
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
switch (id) {
case DIALOG_SHORT_WAIT: {
ProgressDialog working_dialog = new ProgressDialog(this);
working_dialog.setMessage(getResources().getString(
R.string.wait_a_moment));
working_dialog.setIndeterminate(true);
working_dialog.setCancelable(false);
dialog = working_dialog;
break;
}
default:
dialog = null;
}
return dialog;
}
/**
* {@inheritDoc}
*/
@Override
public void onFileStateChanged() {
// nothing to do here!
}
/**
* {@inheritDoc}
*/
@Override
public FileDownloaderBinder getFileDownloaderBinder() {
return mDownloaderBinder;
}
@Override
public FileUploaderBinder getFileUploaderBinder() {
return mUploaderBinder;
}
@Override
public void showFragmentWithDetails(OCFile file) {
Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
showDetailsIntent.putExtra(FileDetailActivity.EXTRA_MODE, FileDetailActivity.MODE_DETAILS);
startActivity(showDetailsIntent);
}
private void requestForDownload() {
if (!mDownloaderBinder.isDownloading(mAccount, mFile)) {
Intent i = new Intent(this, FileDownloader.class);
i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
i.putExtra(FileDownloader.EXTRA_FILE, mFile);
startService(i);
}
}
@Override
public void notifySuccessfulDownload(OCFile file, Intent intent, boolean success) {
if (success) {
if (mWaitingToPreview) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, new FilePreviewFragment(file, mAccount), FileDetailFragment.FTAG);
transaction.commit();
mWaitingToPreview = false;
}
}
}
/**
* This method will be invoked when a new page becomes selected. Animation is not necessarily complete.
*
* @param Position Position index of the new selected page
*/
@Override
public void onPageSelected(int position) {
OCFile currentFile = ((FileFragment)mPreviewImagePagerAdapter.getItem(position)).getFile();
getSupportActionBar().setTitle(currentFile.getFileName());
}
/**
* Called when the scroll state changes. Useful for discovering when the user begins dragging,
* when the pager is automatically settling to the current page, or when it is fully stopped/idle.
*
* @param State The new scroll state (SCROLL_STATE_IDLE, _DRAGGING, _SETTLING
*/
@Override
public void onPageScrollStateChanged(int state) {
}
/**
* This method will be invoked when the current page is scrolled, either as part of a programmatically
* initiated smooth scroll or a user initiated touch scroll.
*
* @param position Position index of the first page currently being displayed.
* Page position+1 will be visible if positionOffset is nonzero.
*
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
}