-/* ownCloud Android client application
- * Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ * ownCloud Android client application
+ *
+ * @author David A. Velasco
+ * Copyright (C) 2015 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.files.FileMenuFilter;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
import com.owncloud.android.ui.fragment.FileFragment;
-import com.owncloud.android.utils.TouchImageViewCustom;
+import com.owncloud.android.utils.BitmapUtils;
+import third_parties.michaelOrtiz.TouchImageViewCustom;
/**
* Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will produce an {@link IllegalStateException}.
*
* If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
- *
- * @author David A. Velasco
*/
public class PreviewImageFragment extends FileFragment {
private TextView mMessageView;
private ProgressBar mProgressWheel;
+ private Boolean mShowResizedImage = false;
+
public Bitmap mBitmap = null;
private static final String TAG = PreviewImageFragment.class.getSimpleName();
private boolean mIgnoreFirstSavedState;
+
+ private LoadBitmapTask mLoadBitmapTask = null;
/**
*
* When 'imageFile' or 'ocAccount' are null
*
- * @param imageFile An {@link OCFile} to preview as an image in the fragment
+ * @param fileToDetail An {@link OCFile} to preview as an image in the fragment
* @param ocAccount An ownCloud account; needed to start downloads
* @param ignoreFirstSavedState Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter}; TODO better solution
*/
- public PreviewImageFragment(OCFile fileToDetail, Account ocAccount, boolean ignoreFirstSavedState) {
+ public PreviewImageFragment(OCFile fileToDetail, Account ocAccount, boolean ignoreFirstSavedState, boolean showResizedImage) {
super(fileToDetail);
mAccount = ocAccount;
+ mShowResizedImage = showResizedImage;
mIgnoreFirstSavedState = ignoreFirstSavedState;
}
if (mAccount == null) {
throw new IllegalStateException("Instanced with a NULL ownCloud Account");
}
- if (!getFile().isDown()) {
- throw new IllegalStateException("There is no local file to preview");
- }
}
public void onStart() {
super.onStart();
if (getFile() != null) {
- BitmapLoader bl = new BitmapLoader(mImageView, mMessageView, mProgressWheel);
- bl.execute(new String[]{getFile().getStoragePath()});
+ mImageView.setTag(getFile().getFileId());
+
+ if (mShowResizedImage){
+ Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+ String.valueOf("r" + getFile().getRemoteId())
+ );
+
+ if (thumbnail != null && !getFile().needsUpdateThumbnail()){
+ mProgressWheel.setVisibility(View.GONE);
+ mImageView.setImageBitmap(thumbnail);
+ mImageView.setBitmap(thumbnail);
+ mImageView.setVisibility(View.VISIBLE);
+ mBitmap = thumbnail;
+ } else {
+ // generate new Thumbnail
+ if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView)) {
+ final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+ new ThumbnailsCacheManager.ThumbnailGenerationTask(
+ mImageView, mContainerActivity.getStorageManager(), mAccount, mProgressWheel
+ );
+ if (thumbnail == null) {
+ thumbnail = ThumbnailsCacheManager.mDefaultImg;
+ }
+ final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+ new ThumbnailsCacheManager.AsyncDrawable(
+ MainApp.getAppContext().getResources(),
+ thumbnail,
+ task
+ );
+ mImageView.setImageDrawable(asyncDrawable);
+ task.execute(getFile(), false);
+ }
+ }
+ } else {
+ mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+ mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
+ }
}
}
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (mLoadBitmapTask != null) {
+ mLoadBitmapTask.cancel(true);
+ mLoadBitmapTask = null;
+ }
+
+ }
+
/**
* {@inheritDoc}
*/
return true;
}
case R.id.action_send_file: {
- mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
- return true;
+ if (getFile().isImage() && !getFile().isDown()){
+ mContainerActivity.getFileOperationsHelper().sendCachedImage(getFile());
+ return true;
+ } else {
+ mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
+ return true;
+ }
}
case R.id.action_sync_file: {
mContainerActivity.getFileOperationsHelper().syncFile(getFile());
}
- private class BitmapLoader extends AsyncTask<String, Void, Bitmap> {
+ private class LoadBitmapTask extends AsyncTask<String, Void, Bitmap> {
/**
* Weak reference to the target {@link ImageView} where the bitmap will be loaded into.
/**
- * Weak reference to the target {@link Progressbar} shown while the load is in progress.
+ * Weak reference to the target {@link ProgressBar} shown while the load is in progress.
*
* Using a weak reference will avoid memory leaks if the target ImageView is retired from memory before the load finishes.
*/
*
* @param imageView Target {@link ImageView} where the bitmap will be loaded into.
*/
- public BitmapLoader(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
+ public LoadBitmapTask(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
mImageViewRef = new WeakReference<ImageViewCustom>(imageView);
mMessageViewRef = new WeakReference<TextView>(messageView);
mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
String storagePath = params[0];
try {
+ if (isCancelled()) return result;
+
File picture = new File(storagePath);
if (picture != null) {
- //Decode file into a bitmap in real size for being able to make zoom on the image
+ // Decode file into a bitmap in real size for being able to make zoom on
+ // the image
result = BitmapFactory.decodeStream(new FlushedInputStream
(new BufferedInputStream(new FileInputStream(picture))));
}
+ if (isCancelled()) return result;
+
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+ } else {
+ // Rotate image, obeying exif tag.
+ result = BitmapUtils.rotateImage(result, storagePath);
}
} catch (OutOfMemoryError e) {
Log_OC.e(TAG, "Out of memory occured for file " + storagePath, e);
- // If out of memory error when loading image, try to load it scaled
+ if (isCancelled()) return result;
+
+ // If out of memory error when loading or rotating image, try to load it scaled
result = loadScaledImage(storagePath);
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+ } else {
+ // Rotate scaled image, obeying exif tag
+ result = BitmapUtils.rotateImage(result, storagePath);
}
} catch (NoSuchFieldError e) {
mErrorMessageId = R.string.common_error_unknown;
- Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " + storagePath, e);
+ Log_OC.e(TAG, "Error from access to unexisting field despite protection; file "
+ + storagePath, e);
} catch (Throwable t) {
mErrorMessageId = R.string.common_error_unknown;
Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t);
}
+
return result;
}
@Override
+ protected void onCancelled(Bitmap result) {
+ if (result != null) {
+ result.recycle();
+ }
+ }
+
+ @Override
protected void onPostExecute(Bitmap result) {
hideProgressWheel();
if (result != null) {
showErrorMessage();
}
}
-
+
@SuppressLint("InlinedApi")
private void showLoadedImage(Bitmap result) {
if (mImageViewRef != null) {