|
@@ -29,6 +29,7 @@ import android.graphics.Point;
|
|
|
import android.graphics.drawable.BitmapDrawable;
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
import android.graphics.drawable.LayerDrawable;
|
|
|
+import android.graphics.drawable.PictureDrawable;
|
|
|
import android.os.AsyncTask;
|
|
|
import android.os.Bundle;
|
|
|
import android.support.annotation.DrawableRes;
|
|
@@ -48,6 +49,8 @@ import android.widget.ProgressBar;
|
|
|
import android.widget.RelativeLayout;
|
|
|
import android.widget.TextView;
|
|
|
|
|
|
+import com.caverock.androidsvg.SVG;
|
|
|
+import com.caverock.androidsvg.SVGParseException;
|
|
|
import com.owncloud.android.R;
|
|
|
import com.owncloud.android.datamodel.OCFile;
|
|
|
import com.owncloud.android.files.FileMenuFilter;
|
|
@@ -59,6 +62,8 @@ import com.owncloud.android.utils.BitmapUtils;
|
|
|
import com.owncloud.android.utils.DisplayUtils;
|
|
|
import com.owncloud.android.utils.MimeTypeUtil;
|
|
|
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileNotFoundException;
|
|
|
import java.lang.ref.WeakReference;
|
|
|
|
|
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
|
@@ -109,10 +114,10 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
*
|
|
|
* This method hides to client objects the need of doing the construction in two steps.
|
|
|
*
|
|
|
- * @param imageFile An {@link OCFile} to preview as an image in the fragment
|
|
|
- * @param ignoreFirstSavedState Flag to work around an unexpected behaviour of
|
|
|
- * {@link FragmentStatePagerAdapter}
|
|
|
- * ; TODO better solution
|
|
|
+ * @param imageFile An {@link OCFile} to preview as an image in the fragment
|
|
|
+ * @param ignoreFirstSavedState Flag to work around an unexpected behaviour of
|
|
|
+ * {@link FragmentStatePagerAdapter}
|
|
|
+ * ; TODO better solution
|
|
|
*/
|
|
|
public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState) {
|
|
|
PreviewImageFragment frag = new PreviewImageFragment();
|
|
@@ -125,13 +130,13 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * Creates an empty fragment for image previews.
|
|
|
+ * Creates an empty fragment for image previews.
|
|
|
*
|
|
|
- * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
|
|
|
- * (for instance, when the device is turned a aside).
|
|
|
+ * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
|
|
|
+ * (for instance, when the device is turned a aside).
|
|
|
*
|
|
|
- * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
|
|
|
- * construction
|
|
|
+ * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
|
|
|
+ * construction
|
|
|
*/
|
|
|
public PreviewImageFragment() {
|
|
|
mIgnoreFirstSavedState = false;
|
|
@@ -180,7 +185,7 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
toggleImageBackground();
|
|
|
}
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
mMultiView = (RelativeLayout) view.findViewById(R.id.multi_view);
|
|
|
|
|
|
setupMultiView(view);
|
|
@@ -337,7 +342,7 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
case R.id.action_share_file:
|
|
|
mContainerActivity.getFileOperationsHelper().showShareFile(getFile());
|
|
|
return true;
|
|
|
-
|
|
|
+
|
|
|
case R.id.action_open_file_with:
|
|
|
openFile();
|
|
|
return true;
|
|
@@ -419,12 +424,14 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
* @param imageView Target {@link ImageView} where the bitmap will be loaded into.
|
|
|
*/
|
|
|
public LoadBitmapTask(ImageViewCustom imageView) {
|
|
|
- mImageViewRef = new WeakReference<ImageViewCustom>(imageView);
|
|
|
+ mImageViewRef = new WeakReference<>(imageView);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
protected LoadImage doInBackground(OCFile... params) {
|
|
|
- Bitmap result = null;
|
|
|
+ Bitmap bitmapResult = null;
|
|
|
+ Drawable drawableResult = null;
|
|
|
+
|
|
|
if (params.length != 1) {
|
|
|
return null;
|
|
|
}
|
|
@@ -436,51 +443,72 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
Point screenSize = DisplayUtils.getScreenSize(getActivity());
|
|
|
int minWidth = screenSize.x;
|
|
|
int minHeight = screenSize.y;
|
|
|
- for (int i = 0; i < maxDownScale && result == null; i++) {
|
|
|
- if (isCancelled()) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- try {
|
|
|
- result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth,
|
|
|
- minHeight);
|
|
|
+ for (int i = 0; i < maxDownScale && bitmapResult == null && drawableResult == null; i++) {
|
|
|
|
|
|
+ if (ocFile.getMimetype().equalsIgnoreCase("image/svg+xml")) {
|
|
|
if (isCancelled()) {
|
|
|
- return new LoadImage(result, ocFile);
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- if (result == null) {
|
|
|
- mErrorMessageId = R.string.preview_image_error_unknown_format;
|
|
|
- Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
|
|
|
- break;
|
|
|
- } else {
|
|
|
- if (ocFile.getMimetype().equalsIgnoreCase("image/jpeg")) {
|
|
|
- // Rotate image, obeying exif tag.
|
|
|
- result = BitmapUtils.rotateImage(result, storagePath);
|
|
|
+ try {
|
|
|
+ SVG svg = SVG.getFromInputStream(new FileInputStream(storagePath));
|
|
|
+ drawableResult = new PictureDrawable(svg.renderToPicture());
|
|
|
+
|
|
|
+ if (isCancelled()) {
|
|
|
+ return new LoadImage(null, drawableResult, ocFile);
|
|
|
}
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ mErrorMessageId = R.string.common_error_unknown;
|
|
|
+ Log_OC.e(TAG, "File not found trying to load " + getFile().getStoragePath(), e);
|
|
|
+ } catch (SVGParseException e) {
|
|
|
+ mErrorMessageId = R.string.common_error_unknown;
|
|
|
+ Log_OC.e(TAG, "Couldn't parse SVG " + getFile().getStoragePath(), e);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (isCancelled()) {
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- } catch (OutOfMemoryError e) {
|
|
|
- mErrorMessageId = R.string.common_error_out_memory;
|
|
|
- if (i < maxDownScale - 1) {
|
|
|
- Log_OC.w(TAG, "Out of memory rendering file " + storagePath +
|
|
|
- " ; scaling down");
|
|
|
- minWidth = minWidth / 2;
|
|
|
- minHeight = minHeight / 2;
|
|
|
+ try {
|
|
|
+ bitmapResult = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth,
|
|
|
+ minHeight);
|
|
|
|
|
|
- } else {
|
|
|
- Log_OC.w(TAG, "Out of memory rendering file " + storagePath +
|
|
|
- " ; failing");
|
|
|
- }
|
|
|
- if (result != null) {
|
|
|
- result.recycle();
|
|
|
+ if (isCancelled()) {
|
|
|
+ return new LoadImage(bitmapResult, null, ocFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (bitmapResult == null) {
|
|
|
+ mErrorMessageId = R.string.preview_image_error_unknown_format;
|
|
|
+ Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
|
|
|
+ break;
|
|
|
+ } else {
|
|
|
+ if (ocFile.getMimetype().equalsIgnoreCase("image/jpeg")) {
|
|
|
+ // Rotate image, obeying exif tag.
|
|
|
+ bitmapResult = BitmapUtils.rotateImage(bitmapResult, storagePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (OutOfMemoryError e) {
|
|
|
+ mErrorMessageId = R.string.common_error_out_memory;
|
|
|
+ if (i < maxDownScale - 1) {
|
|
|
+ Log_OC.w(TAG, "Out of memory rendering file " + storagePath + " ; scaling down");
|
|
|
+ minWidth = minWidth / 2;
|
|
|
+ minHeight = minHeight / 2;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ Log_OC.w(TAG, "Out of memory rendering file " + storagePath + " ; failing");
|
|
|
+ }
|
|
|
+ if (bitmapResult != null) {
|
|
|
+ bitmapResult.recycle();
|
|
|
+ }
|
|
|
+ bitmapResult = null;
|
|
|
}
|
|
|
- result = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
} catch (NoSuchFieldError e) {
|
|
|
mErrorMessageId = R.string.common_error_unknown;
|
|
|
- Log_OC.e(TAG, "Error from access to unexisting field despite protection; file "
|
|
|
+ Log_OC.e(TAG, "Error from access to non-existing field despite protection; file "
|
|
|
+ storagePath, e);
|
|
|
|
|
|
} catch (Throwable t) {
|
|
@@ -489,7 +517,7 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
|
|
|
}
|
|
|
|
|
|
- return new LoadImage(result, ocFile);
|
|
|
+ return new LoadImage(bitmapResult, drawableResult, ocFile);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -501,7 +529,7 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
|
|
|
@Override
|
|
|
protected void onPostExecute(LoadImage result) {
|
|
|
- if (result.bitmap != null) {
|
|
|
+ if (result.bitmap != null || result.drawable != null) {
|
|
|
showLoadedImage(result);
|
|
|
} else {
|
|
|
showErrorMessage();
|
|
@@ -516,23 +544,43 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
private void showLoadedImage(LoadImage result) {
|
|
|
final ImageViewCustom imageView = mImageViewRef.get();
|
|
|
Bitmap bitmap = result.bitmap;
|
|
|
- if (imageView != null) {
|
|
|
- Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" +
|
|
|
- bitmap.getHeight());
|
|
|
|
|
|
|
|
|
- if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")) {
|
|
|
+ if (imageView != null) {
|
|
|
+ if (bitmap != null) {
|
|
|
+ Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" +
|
|
|
+ bitmap.getHeight());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.ocFile.getMimetype().equalsIgnoreCase("image/png") ||
|
|
|
+ result.ocFile.getMimetype().equals("image/svg+xml")) {
|
|
|
if (getResources() != null) {
|
|
|
Resources r = getResources();
|
|
|
Drawable[] layers = new Drawable[2];
|
|
|
layers[0] = r.getDrawable(R.color.white);
|
|
|
- Drawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
|
|
|
+ Drawable bitmapDrawable;
|
|
|
+ if (result.ocFile.getMimetype().equalsIgnoreCase("image/png") ) {
|
|
|
+ bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
|
|
|
+ } else {
|
|
|
+ bitmapDrawable = result.drawable;
|
|
|
+ }
|
|
|
layers[1] = bitmapDrawable;
|
|
|
LayerDrawable layerDrawable = new LayerDrawable(layers);
|
|
|
- layerDrawable.setLayerHeight(0, convertDpToPixel(bitmap.getHeight(), getActivity()));
|
|
|
- layerDrawable.setLayerHeight(1, convertDpToPixel(bitmap.getHeight(), getActivity()));
|
|
|
- layerDrawable.setLayerWidth(0, convertDpToPixel(bitmap.getWidth(), getActivity()));
|
|
|
- layerDrawable.setLayerWidth(1, convertDpToPixel(bitmap.getWidth(), getActivity()));
|
|
|
+ if (result.ocFile.getMimetype().equalsIgnoreCase("image/png") ) {
|
|
|
+ layerDrawable.setLayerHeight(0, convertDpToPixel(bitmap.getHeight(), getActivity()));
|
|
|
+ layerDrawable.setLayerHeight(1, convertDpToPixel(bitmap.getHeight(), getActivity()));
|
|
|
+ layerDrawable.setLayerWidth(0, convertDpToPixel(bitmap.getWidth(), getActivity()));
|
|
|
+ layerDrawable.setLayerWidth(1, convertDpToPixel(bitmap.getWidth(), getActivity()));
|
|
|
+ } else {
|
|
|
+ layerDrawable.setLayerHeight(0, convertDpToPixel(bitmapDrawable.getIntrinsicHeight(),
|
|
|
+ getActivity()));
|
|
|
+ layerDrawable.setLayerHeight(1, convertDpToPixel(bitmapDrawable.getIntrinsicHeight(),
|
|
|
+ getActivity()));
|
|
|
+ layerDrawable.setLayerWidth(0, convertDpToPixel(bitmapDrawable.getIntrinsicWidth(),
|
|
|
+ getActivity()));
|
|
|
+ layerDrawable.setLayerWidth(1, convertDpToPixel(bitmapDrawable.getIntrinsicWidth(),
|
|
|
+ getActivity()));
|
|
|
+ }
|
|
|
imageView.setImageDrawable(layerDrawable);
|
|
|
} else {
|
|
|
imageView.setImageBitmap(bitmap);
|
|
@@ -541,7 +589,8 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
|
|
|
if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")) {
|
|
|
imageView.setGIFImageFromStoragePath(result.ocFile.getStoragePath());
|
|
|
- } else if (!result.ocFile.getMimetype().equalsIgnoreCase("image/png")) {
|
|
|
+ } else if (!result.ocFile.getMimetype().equalsIgnoreCase("image/png") &&
|
|
|
+ !result.ocFile.getMimetype().equals("image/svg+xml")) {
|
|
|
imageView.setImageBitmap(bitmap);
|
|
|
}
|
|
|
|
|
@@ -589,8 +638,8 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
* Helper method to test if an {@link OCFile} can be passed to a {@link PreviewImageFragment}
|
|
|
* to be previewed.
|
|
|
*
|
|
|
- * @param file File to test if can be previewed.
|
|
|
- * @return 'True' if the file can be handled by the fragment.
|
|
|
+ * @param file File to test if can be previewed.
|
|
|
+ * @return 'True' if the file can be handled by the fragment.
|
|
|
*/
|
|
|
public static boolean canBePreviewed(OCFile file) {
|
|
|
return (file != null && MimeTypeUtil.isImage(file));
|
|
@@ -606,7 +655,8 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
}
|
|
|
|
|
|
private void toggleImageBackground() {
|
|
|
- if (getFile() != null && getFile().getMimetype().equalsIgnoreCase("image/png") && getActivity() != null
|
|
|
+ if (getFile() != null && (getFile().getMimetype().equalsIgnoreCase("image/png") ||
|
|
|
+ getFile().getMimetype().equalsIgnoreCase("image/svg+xml")) && getActivity() != null
|
|
|
&& getActivity() instanceof PreviewImageActivity && getResources() != null) {
|
|
|
PreviewImageActivity previewImageActivity = (PreviewImageActivity) getActivity();
|
|
|
LayerDrawable layerDrawable = (LayerDrawable) mImageView.getDrawable();
|
|
@@ -640,10 +690,12 @@ public class PreviewImageFragment extends FileFragment {
|
|
|
|
|
|
private class LoadImage {
|
|
|
private Bitmap bitmap;
|
|
|
+ private Drawable drawable;
|
|
|
private OCFile ocFile;
|
|
|
|
|
|
- public LoadImage(Bitmap bitmap, OCFile ocFile) {
|
|
|
+ public LoadImage(Bitmap bitmap, Drawable drawable, OCFile ocFile) {
|
|
|
this.bitmap = bitmap;
|
|
|
+ this.drawable = drawable;
|
|
|
this.ocFile = ocFile;
|
|
|
}
|
|
|
|