From: tobiasKaminsky Date: Thu, 5 Nov 2015 21:04:57 +0000 (+0100) Subject: Merge remote-tracking branch 'remotes/upstream/master' into resizedImagesMaster X-Git-Tag: beta-20151122~1^2~1 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/ce841a3c4f7e32d5f54972dbc8d9b950174ed2ca?ds=inline;hp=-c Merge remote-tracking branch 'remotes/upstream/master' into resizedImagesMaster --- ce841a3c4f7e32d5f54972dbc8d9b950174ed2ca diff --combined AndroidManifest.xml index 1f06b3e3,805e9ce7..e1d21f3c --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@@ -1,5 -1,5 +1,5 @@@ - - + --> + + + @@@ -32,74 -37,60 +37,60 @@@ - - - - + + + - - + + + android:theme="@style/Theme.ownCloud" > + android:label="@string/app_name" > + - - + - - + - - + - - + - - + - - - - - + - + + - - - + - + android:label="@string/app_name" + android:theme="@style/Theme.ownCloud.Fullscreen" /> - + android:exported="true" > + @@@ -109,8 -100,7 +100,7 @@@ + android:exported="true" > @@@ -124,30 -114,33 +114,39 @@@ android:name=".providers.FileContentProvider" android:authorities="@string/authority" android:enabled="true" - android:exported="false" + android:exported="true" android:label="@string/sync_string_files" - android:syncable="true" > - + android:syncable="true" /> + + + + + + android:launchMode="singleTask" + android:theme="@style/Theme.ownCloud.noActionBar" > + + + @@@ -156,50 -149,62 +155,62 @@@ - + - - - - - - - + + + + + + + - + + + - + - + - + - - - - - - - - + + + + + + + + + + + + diff --combined src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index 9b31f3aa,f0ecf767..939bc9a4 --- a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@@ -29,23 -29,18 +29,25 @@@ import org.apache.commons.httpclient.Ht import org.apache.commons.httpclient.methods.GetMethod; import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; +import android.graphics.Point; + import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; + import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.ThumbnailUtils; import android.net.Uri; import android.os.AsyncTask; +import android.view.Display; +import android.view.View; +import android.view.WindowManager; import android.widget.ImageView; +import android.widget.ProgressBar; import com.owncloud.android.MainApp; import com.owncloud.android.R; @@@ -79,8 -74,8 +81,8 @@@ public class ThumbnailsCacheManager public static Bitmap mDefaultImg = BitmapFactory.decodeResource( - MainApp.getAppContext().getResources(), - DisplayUtils.getFileTypeIconId("image/png", "default.png") + MainApp.getAppContext().getResources(), + R.drawable.file_image ); @@@ -147,12 -142,11 +149,12 @@@ public static class ThumbnailGenerationTask extends AsyncTask { private final WeakReference mImageViewReference; + private WeakReference mProgressWheelRef; private static Account mAccount; private Object mFile; + private Boolean mIsThumbnail; private FileDataStorageManager mStorageManager; - public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) { // Use a WeakReference to ensure the ImageView can be garbage collected @@@ -163,12 -157,6 +165,12 @@@ mAccount = account; } + public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, + Account account, ProgressBar progressWheel) { + this(imageView, storageManager, account); + mProgressWheelRef = new WeakReference(progressWheel); + } + public ThumbnailGenerationTask(ImageView imageView) { // Use a WeakReference to ensure the ImageView can be garbage collected mImageViewReference = new WeakReference(imageView); @@@ -187,15 -175,12 +189,15 @@@ } mFile = params[0]; + mIsThumbnail = (Boolean) params[1]; + if (mFile instanceof OCFile) { - thumbnail = doOCFileInBackground(); + thumbnail = doOCFileInBackground(mIsThumbnail); } else if (mFile instanceof File) { - thumbnail = doFileInBackground(); - //} else { do nothing + thumbnail = doFileInBackground(mIsThumbnail); + } else { + // do nothing } }catch(Throwable t){ @@@ -210,10 -195,6 +212,6 @@@ } protected void onPostExecute(Bitmap bitmap){ - if (isCancelled()) { - bitmap = null; - } - if (bitmap != null) { final ImageView imageView = mImageViewReference.get(); final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView); @@@ -225,14 -206,7 +223,14 @@@ tagId = String.valueOf(mFile.hashCode()); } if (String.valueOf(imageView.getTag()).equals(tagId)) { + if (mProgressWheelRef != null) { + final ProgressBar progressWheel = mProgressWheelRef.get(); + if (progressWheel != null) { + progressWheel.setVisibility(View.GONE); + } + } imageView.setImageBitmap(bitmap); + imageView.setVisibility(View.VISIBLE); } } } @@@ -243,13 -217,12 +241,13 @@@ * @param imageKey: thumb key * @param bitmap: image for extracting thumbnail * @param path: image path - * @param px: thumbnail dp + * @param pxW: thumbnail width + * @param pxH: thumbnail height * @return Bitmap */ - private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){ + private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int pxW, int pxH){ - Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH); // Rotate image, obeying exif tag thumbnail = BitmapUtils.rotateImage(thumbnail,path); @@@ -270,49 -243,31 +268,54 @@@ return Math.round(r.getDimension(R.dimen.file_icon_size_grid)); } - private Bitmap doOCFileInBackground() { + private Point getScreenDimension(){ + WindowManager wm = (WindowManager) MainApp.getAppContext().getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + Point test = new Point(); + display.getSize(test); + return test; + } + + private Bitmap doOCFileInBackground(Boolean isThumbnail) { + Bitmap thumbnail = null; OCFile file = (OCFile)mFile; - final String imageKey = String.valueOf(file.getRemoteId()); + // distinguish between thumbnail and resized image + String temp = String.valueOf(file.getRemoteId()); + if (isThumbnail){ + temp = "t" + temp; + } else { + temp = "r" + temp; + } + + final String imageKey = temp; // Check disk cache in background thread - Bitmap thumbnail = getBitmapFromDiskCache(imageKey); + thumbnail = getBitmapFromDiskCache(imageKey); // Not found in disk cache if (thumbnail == null || file.needsUpdateThumbnail()) { - - int px = getThumbnailDimension(); + int pxW = 0; + int pxH = 0; + if (mIsThumbnail) { + pxW = pxH = getThumbnailDimension(); + } else { + Point p = getScreenDimension(); + pxW = p.x; + pxH = p.y; + } if (file.isDown()) { - Bitmap temp = BitmapUtils.decodeSampledBitmapFromFile( - file.getStoragePath(), px, px); - Bitmap bitmap = ThumbnailUtils.extractThumbnail(temp, px, px); + Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( + file.getStoragePath(), pxW, pxH); if (bitmap != null) { + // Handle PNG + if (file.getMimetype().equalsIgnoreCase("image/png")) { - bitmap = handlePNG(bitmap, px); ++ bitmap = handlePNG(bitmap, pxW); + } + - thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px); + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), pxW, pxH); file.setNeedsUpdateThumbnail(false); mStorageManager.saveFile(file); @@@ -326,25 -281,20 +329,27 @@@ try { String uri = mClient.getBaseUri() + "" + "/index.php/apps/files/api/v1/thumbnail/" + - px + "/" + px + Uri.encode(file.getRemotePath(), "/"); + pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/"); Log_OC.d("Thumbnail", "URI: " + uri); GetMethod get = new GetMethod(uri); int status = mClient.executeMethod(get); if (status == HttpStatus.SC_OK) { - // byte[] bytes = get.getResponseBody(); - // Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, - // bytes.length); InputStream inputStream = get.getResponseBodyAsStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); - thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px); + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH); + byte[] bytes = get.getResponseBody(); + + if (mIsThumbnail) { + thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH); + } else { + thumbnail = bitmap; + } + // Handle PNG + if (file.getMimetype().equalsIgnoreCase("image/png")) { - thumbnail = handlePNG(thumbnail, px); ++ thumbnail = handlePNG(thumbnail, pxW); + } + // Add thumbnail to cache if (thumbnail != null) { addBitmapToCache(imageKey, thumbnail); @@@ -364,39 -314,37 +369,52 @@@ } + private Bitmap handlePNG(Bitmap bitmap, int px){ + Bitmap resultBitmap = Bitmap.createBitmap(px, + px, + Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(resultBitmap); + + c.drawColor(MainApp.getAppContext().getResources(). + getColor(R.color.background_color)); + c.drawBitmap(bitmap, 0, 0, null); + + return resultBitmap; + } + - private Bitmap doFileInBackground() { + private Bitmap doFileInBackground(Boolean mIsThumbnail) { File file = (File)mFile; - final String imageKey = String.valueOf(file.hashCode()); + // distinguish between thumbnail and resized image + String temp = String.valueOf(file.hashCode()); + if (mIsThumbnail){ + temp = "t" + temp; + } else { + temp = "r" + temp; + } + + final String imageKey = temp; // Check disk cache in background thread Bitmap thumbnail = getBitmapFromDiskCache(imageKey); // Not found in disk cache if (thumbnail == null) { - - int px = getThumbnailDimension(); + int pxW = 0; + int pxH = 0; + if (mIsThumbnail) { + pxW = pxH = getThumbnailDimension(); + } else { + Point p = getScreenDimension(); + pxW = p.x; + pxH = p.y; + } Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile( - file.getAbsolutePath(), px, px); + file.getAbsolutePath(), pxW, pxH); if (bitmap != null) { - thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px); + thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), pxW, pxH); } } return thumbnail; @@@ -413,6 -361,7 +431,7 @@@ if (bitmapData == null || bitmapData != file) { // Cancel previous task bitmapWorkerTask.cancel(true); + Log_OC.v(TAG, "Cancelled generation of thumbnail for a reused imageView"); } else { // The same work is already in progress return false; diff --combined src/com/owncloud/android/files/FileOperationsHelper.java index abea72cc,a22de8ef..a0034da6 --- a/src/com/owncloud/android/files/FileOperationsHelper.java +++ b/src/com/owncloud/android/files/FileOperationsHelper.java @@@ -21,52 -21,50 +21,60 @@@ package com.owncloud.android.files; - import org.apache.http.protocol.HTTP; - import android.accounts.Account; + import android.content.ActivityNotFoundException; + import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; + import android.content.pm.PackageManager; + import android.content.pm.ResolveInfo; import android.net.Uri; import android.support.v4.app.DialogFragment; import android.webkit.MimeTypeMap; import android.widget.Toast; +import com.owncloud.android.MainApp; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.datamodel.ThumbnailsCacheManager; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; - import com.owncloud.android.lib.common.network.WebdavUtils; import com.owncloud.android.lib.common.utils.Log_OC; + import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import com.owncloud.android.services.OperationsService; + import com.owncloud.android.services.observer.FileObserverService; import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.ui.adapter.DiskLruImageCacheFileProvider; + import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.dialog.ShareLinkToDialog; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + + import org.apache.http.protocol.HTTP; + + import java.util.List; + /** * */ public class FileOperationsHelper { private static final String TAG = FileOperationsHelper.class.getName(); - - private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; + + private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; protected FileActivity mFileActivity = null; /// Identifier of operation in progress which result shouldn't be lost private long mWaitingForOpId = Long.MAX_VALUE; - + public FileOperationsHelper(FileActivity fileActivity) { mFileActivity = fileActivity; } @@@ -76,9 -74,10 +84,10 @@@ if (file != null) { String storagePath = file.getStoragePath(); String encodedStoragePath = WebdavUtils.encodePath(storagePath); - + Intent intentForSavedMimeType = new Intent(Intent.ACTION_VIEW); - intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), file.getMimetype()); + intentForSavedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), + file.getMimetype()); intentForSavedMimeType.setFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION ); @@@ -90,59 -89,90 +99,90 @@@ ); if (guessedMimeType != null && !guessedMimeType.equals(file.getMimetype())) { intentForGuessedMimeType = new Intent(Intent.ACTION_VIEW); - intentForGuessedMimeType.setDataAndType(Uri.parse("file://"+ encodedStoragePath), guessedMimeType); + intentForGuessedMimeType. + setDataAndType(Uri.parse("file://"+ encodedStoragePath), + guessedMimeType); intentForGuessedMimeType.setFlags( - Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION + Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION ); } } - - Intent chooserIntent; + + Intent openFileWithIntent; if (intentForGuessedMimeType != null) { - chooserIntent = Intent.createChooser(intentForGuessedMimeType, mFileActivity.getString(R.string.actionbar_open_with)); + openFileWithIntent = intentForGuessedMimeType; } else { - chooserIntent = Intent.createChooser(intentForSavedMimeType, mFileActivity.getString(R.string.actionbar_open_with)); + openFileWithIntent = intentForSavedMimeType; } - - mFileActivity.startActivity(chooserIntent); - + + List launchables = mFileActivity.getPackageManager(). + queryIntentActivities(openFileWithIntent, PackageManager.GET_INTENT_FILTERS); + + if(launchables != null && launchables.size() > 0) { + try { + mFileActivity.startActivity( + Intent.createChooser( + openFileWithIntent, mFileActivity.getString(R.string.actionbar_open_with) + ) + ); + } catch (ActivityNotFoundException anfe) { + showNoAppForFileTypeToast(mFileActivity.getApplicationContext()); + } + } else { + showNoAppForFileTypeToast(mFileActivity.getApplicationContext()); + } + } else { Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); } } - - + + /** + * Displays a toast stating that no application could be found to open the file. + * + * @param context the context to be able to show a toast. + */ + private void showNoAppForFileTypeToast(Context context) { + Toast.makeText(context, + R.string.file_list_no_app_for_file_type, Toast.LENGTH_SHORT) + .show(); + } + public void shareFileWithLink(OCFile file) { - + if (isSharedSupported()) { if (file != null) { String link = "https://fake.url"; Intent intent = createShareWithLinkIntent(link); - String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; - DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, packagesToExclude, file); + String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent, + packagesToExclude, file); chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); - + } else { Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); } - + } else { // Show a Message Toast t = Toast.makeText( - mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG + mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), + Toast.LENGTH_LONG ); t.show(); } } - - + + public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) { if (file != null) { - mFileActivity.showLoadingDialog(); - + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); + Intent service = new Intent(mFileActivity, OperationsService.class); - service.setAction(OperationsService.ACTION_CREATE_SHARE); + service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK); service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); service.putExtra(OperationsService.EXTRA_PASSWORD_SHARE, password); @@@ -153,18 -183,45 +193,45 @@@ Log_OC.wtf(TAG, "Trying to open a NULL OCFile"); } } - - + + private Intent createShareWithLinkIntent(String link) { Intent intentToShareLink = new Intent(Intent.ACTION_SEND); intentToShareLink.putExtra(Intent.EXTRA_TEXT, link); intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE); - return intentToShareLink; + return intentToShareLink; } - - + + /** - * @return 'True' if the server supports the Share API + * Helper method to share a file with a know sharee. Starts a request to do it in {@link OperationsService} + * + * @param file The file to share. + * @param shareeName Name (user name or group name) of the target sharee. + * @param shareType The share type determines the sharee type. + */ + public void shareFileWithSharee(OCFile file, String shareeName, ShareType shareType) { + if (file != null) { + // TODO check capability? + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); + + Intent service = new Intent(mFileActivity, OperationsService.class); + service.setAction(OperationsService.ACTION_CREATE_SHARE_WITH_SHAREE); + service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + service.putExtra(OperationsService.EXTRA_SHARE_WITH, shareeName); + service.putExtra(OperationsService.EXTRA_SHARE_TYPE, shareType); + mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); + + } else { + Log_OC.wtf(TAG, "Trying to share a NULL OCFile"); + } + } + + + /** + * @return 'True' if the server supports the Share API */ public boolean isSharedSupported() { if (mFileActivity.getAccount() != null) { @@@ -173,39 -230,93 +240,93 @@@ } return false; } - - + + public void unshareFileWithLink(OCFile file) { - + + // Unshare the file: Create the intent + Intent unshareService = new Intent(mFileActivity, OperationsService.class); + unshareService.setAction(OperationsService.ACTION_UNSHARE); + unshareService.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + unshareService.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, ShareType.PUBLIC_LINK); + unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, ""); + + unshareFile(unshareService); + } + + public void unshareFileWithUserOrGroup(OCFile file, ShareType shareType, String userOrGroup){ + + // Unshare the file: Create the intent + Intent unshareService = new Intent(mFileActivity, OperationsService.class); + unshareService.setAction(OperationsService.ACTION_UNSHARE); + unshareService.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + unshareService.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); + unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, shareType); + unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, userOrGroup); + + unshareFile(unshareService); + } + + + private void unshareFile(Intent unshareService){ if (isSharedSupported()) { // Unshare the file - Intent service = new Intent(mFileActivity, OperationsService.class); - service.setAction(OperationsService.ACTION_UNSHARE); - service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); - service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); - mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - - mFileActivity.showLoadingDialog(); - + mWaitingForOpId = mFileActivity.getOperationsServiceBinder(). + queueNewOperation(unshareService); + + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); + } else { // Show a Message - Toast t = Toast.makeText(mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api), Toast.LENGTH_LONG); + Toast t = Toast.makeText(mFileActivity, + mFileActivity.getString(R.string.share_link_no_support_share_api), + Toast.LENGTH_LONG); t.show(); - + } } - + + /** + * Show an instance of {@link ShareType} for sharing or unsharing the {@OCFile} received as parameter. + * + * @param file File to share or unshare. + */ + public void showShareFile(OCFile file){ + Intent intent = new Intent(mFileActivity, ShareActivity.class); + intent.putExtra(mFileActivity.EXTRA_FILE, file); + intent.putExtra(mFileActivity.EXTRA_ACCOUNT, mFileActivity.getAccount()); + mFileActivity.startActivity(intent); + + } + + + /** + * @return 'True' if the server supports the Search Users API + */ + public boolean isSearchUsersSupportedSupported() { + if (mFileActivity.getAccount() != null) { + OwnCloudVersion serverVersion = AccountUtils.getServerVersion(mFileActivity.getAccount()); + return (serverVersion != null && serverVersion.isSearchUsersSupported()); + } + return false; + } + public void sendDownloadedFile(OCFile file) { if (file != null) { + String storagePath = file.getStoragePath(); + String encodedStoragePath = WebdavUtils.encodePath(storagePath); Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND); // set MimeType sendIntent.setType(file.getMimetype()); - sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + file.getStoragePath())); + sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + encodedStoragePath)); sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action - + // Show dialog, without the own app - String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; - DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file); + String[] packagesToExclude = new String[]{mFileActivity.getPackageName()}; + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, + packagesToExclude, file); chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); } else { @@@ -213,27 -324,12 +334,32 @@@ } } + public void sendCachedImage(OCFile file) { + if (file != null) { + Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND); + // set MimeType + sendIntent.setType(file.getMimetype()); +// sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName())); + sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath())); + sendIntent.putExtra(Intent.ACTION_SEND, true); // Send Action + + // Show dialog, without the own app + String[] packagesToExclude = new String[] { mFileActivity.getPackageName() }; + DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file); + chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG); + } else { + Log_OC.wtf(TAG, "Trying to send a NULL OCFile"); + } + } + + ++ + /** + * Request the synchronization of a file or folder with the OC server, including its contents. + * + * @param file The file or folder to synchronize + */ public void syncFile(OCFile file) { - if (!file.isFolder()){ Intent intent = new Intent(mFileActivity, OperationsService.class); intent.setAction(OperationsService.ACTION_SYNC_FILE); @@@ -241,7 -337,8 +367,8 @@@ intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); intent.putExtra(OperationsService.EXTRA_SYNC_FILE_CONTENTS, true); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(intent); - // mFileActivity.showLoadingDialog(); + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); } else { Intent intent = new Intent(mFileActivity, OperationsService.class); @@@ -249,6 -346,25 +376,25 @@@ intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath()); mFileActivity.startService(intent); + + } + } + + public void toggleFavorite(OCFile file, boolean isFavorite) { + file.setFavorite(isFavorite); + mFileActivity.getStorageManager().saveFile(file); + + /// register the OCFile instance in the observer service to monitor local updates + Intent observedFileIntent = FileObserverService.makeObservedFileIntent( + mFileActivity, + file, + mFileActivity.getAccount(), + isFavorite); + mFileActivity.startService(observedFileIntent); + + /// immediate content synchronization + if (file.isFavorite()) { + syncFile(file); } } @@@ -261,7 -377,8 +407,8 @@@ service.putExtra(OperationsService.EXTRA_NEWNAME, newFilename); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - mFileActivity.showLoadingDialog(); + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); } @@@ -274,10 -391,11 +421,11 @@@ service.putExtra(OperationsService.EXTRA_REMOVE_ONLY_LOCAL, onlyLocalCopy); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - mFileActivity.showLoadingDialog(); + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); } - - + + public void createFolder(String remotePath, boolean createFullPath) { // Create Folder Intent service = new Intent(mFileActivity, OperationsService.class); @@@ -287,7 -405,8 +435,8 @@@ service.putExtra(OperationsService.EXTRA_CREATE_FULL_PATH, createFullPath); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - mFileActivity.showLoadingDialog(); + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); } /** @@@ -297,7 -416,8 +446,8 @@@ public void cancelTransference(OCFile file) { Account account = mFileActivity.getAccount(); if (file.isFolder()) { - OperationsService.OperationsServiceBinder opsBinder = mFileActivity.getOperationsServiceBinder(); + OperationsService.OperationsServiceBinder opsBinder = + mFileActivity.getOperationsServiceBinder(); if (opsBinder != null) { opsBinder.cancel(account, file); } @@@ -305,27 -425,20 +455,20 @@@ // for both files and folders FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder(); - FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder(); if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) { downloaderBinder.cancel(account, file); - - // TODO - review why is this here, and solve in a better way - // Remove etag for parent, if file is a keep_in_sync - if (file.keepInSync()) { - OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId()); - parent.setEtag(""); - mFileActivity.getStorageManager().saveFile(parent); - } - - } else if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) { + } + FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder(); + if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) { uploaderBinder.cancel(account, file); } } /** * Start move file operation - * @param newfile File where it is going to be moved - * @param currentFile File with the previous info + * + * @param newfile File where it is going to be moved + * @param currentFile File with the previous info */ public void moveFile(OCFile newfile, OCFile currentFile) { // Move files @@@ -336,9 -449,28 +479,28 @@@ service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); - mFileActivity.showLoadingDialog(); + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); } + /** + * Start copy file operation + * + * @param newfile File where it is going to be moved + * @param currentFile File with the previous info + */ + public void copyFile(OCFile newfile, OCFile currentFile) { + // Copy files + Intent service = new Intent(mFileActivity, OperationsService.class); + service.setAction(OperationsService.ACTION_COPY_FILE); + service.putExtra(OperationsService.EXTRA_NEW_PARENT_PATH, newfile.getRemotePath()); + service.putExtra(OperationsService.EXTRA_REMOTE_PATH, currentFile.getRemotePath()); + service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount()); + mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service); + + mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext(). + getString(R.string.wait_a_moment)); + } public long getOpIdWaitingFor() { return mWaitingForOpId; @@@ -348,13 -480,14 +510,14 @@@ public void setOpIdWaitingFor(long waitingForOpId) { mWaitingForOpId = waitingForOpId; } - + /** * @return 'True' if the server doesn't need to check forbidden characters */ public boolean isVersionWithForbiddenCharacters() { if (mFileActivity.getAccount() != null) { - OwnCloudVersion serverVersion = AccountUtils.getServerVersion(mFileActivity.getAccount()); + OwnCloudVersion serverVersion = + AccountUtils.getServerVersion(mFileActivity.getAccount()); return (serverVersion != null && serverVersion.isVersionWithForbiddenCharacters()); } return false; diff --combined src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 897f9804,07a3eed5..2aa25eaf --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@@ -4,6 -4,7 +4,7 @@@ * @author Bartek Przybylski * @author Tobias Kaminsky * @author David A. Velasco + * @author masensio * Copyright (C) 2011 Bartek Przybylski * Copyright (C) 2015 ownCloud Inc. * @@@ -54,6 -55,7 +55,7 @@@ import com.owncloud.android.services.Op import com.owncloud.android.ui.activity.ComponentsGetter; import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.FileStorageUtils; + import com.owncloud.android.utils.MimetypeIconUtil; /** @@@ -61,7 -63,6 +63,6 @@@ * instance. */ public class FileListListAdapter extends BaseAdapter implements ListAdapter { - private final static String PERMISSION_SHARED_WITH_ME = "S"; private Context mContext; private OCFile mFile = null; @@@ -233,13 -234,21 +234,21 @@@ case GRID_IMAGE: // sharedIcon ImageView sharedIconV = (ImageView) view.findViewById(R.id.sharedIcon); - if (file.isShareByLink()) { + if (file.isSharedViaLink()) { + sharedIconV.setImageResource(R.drawable.shared_via_link); + sharedIconV.setVisibility(View.VISIBLE); + sharedIconV.bringToFront(); + } else if (file.isSharedWithSharee() || file.isSharedWithMe() ) { + sharedIconV.setImageResource(R.drawable.shared_via_users); sharedIconV.setVisibility(View.VISIBLE); sharedIconV.bringToFront(); } else { sharedIconV.setVisibility(View.GONE); } + /*ImageView sharedWithMeIcon = (ImageView) view.findViewById(R.id.sharedWithMeIcon); + sharedWithMeIcon.bringToFront();*/ + // local state ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator); localStateView.bringToFront(); @@@ -247,36 -256,47 +256,47 @@@ mTransferServiceGetter.getFileDownloaderBinder(); FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder(); - boolean downloading = (downloaderBinder != null && - downloaderBinder.isDownloading(mAccount, file)); OperationsServiceBinder opsBinder = mTransferServiceGetter.getOperationsServiceBinder(); - downloading |= (opsBinder != null && - opsBinder.isSynchronizing(mAccount, file.getRemotePath())); - if (downloading) { - localStateView.setImageResource(R.drawable.downloading_file_indicator); + + localStateView.setVisibility(View.INVISIBLE); // default first + + if ( //synchronizing + opsBinder != null && + opsBinder.isSynchronizing(mAccount, file.getRemotePath()) + ) { + localStateView.setImageResource(R.drawable.synchronizing_file_indicator); localStateView.setVisibility(View.VISIBLE); - } else if (uploaderBinder != null && - uploaderBinder.isUploading(mAccount, file)) { - localStateView.setImageResource(R.drawable.uploading_file_indicator); + + } else if ( // downloading + downloaderBinder != null && + downloaderBinder.isDownloading(mAccount, file) + ) { + localStateView.setImageResource( + file.isFolder() ? + R.drawable.synchronizing_file_indicator : + R.drawable.downloading_file_indicator + ); localStateView.setVisibility(View.VISIBLE); + + } else if ( //uploading + uploaderBinder != null && + uploaderBinder.isUploading(mAccount, file) + ) { + localStateView.setImageResource( + file.isFolder() ? + R.drawable.synchronizing_file_indicator : + R.drawable.uploading_file_indicator + ); + localStateView.setVisibility(View.VISIBLE); + + } else if (file.getEtagInConflict() != null) { // conflict + localStateView.setImageResource(R.drawable.conflict_file_indicator); + localStateView.setVisibility(View.VISIBLE); + } else if (file.isDown()) { localStateView.setImageResource(R.drawable.local_file_indicator); localStateView.setVisibility(View.VISIBLE); - } else { - localStateView.setVisibility(View.INVISIBLE); - } - - // share with me icon - if (!file.isFolder()) { - ImageView sharedWithMeIconV = (ImageView) - view.findViewById(R.id.sharedWithMeIcon); - sharedWithMeIconV.bringToFront(); - if (checkIfFileIsSharedWithMe(file)) { - sharedWithMeIconV.setVisibility(View.VISIBLE); - } else { - sharedWithMeIconV.setVisibility(View.GONE); - } } break; @@@ -286,7 -306,7 +306,7 @@@ // this if-else is needed even though favorite icon is visible by default // because android reuses views in listview - if (!file.keepInSync()) { + if (!file.isFavorite()) { view.findViewById(R.id.favoriteIcon).setVisibility(View.GONE); } else { view.findViewById(R.id.favoriteIcon).setVisibility(View.VISIBLE); @@@ -297,7 -317,8 +317,7 @@@ if (file.isImage() && file.getRemoteId() != null){ // Thumbnail in Cache? Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache( - String.valueOf(file.getRemoteId()) - ); + "t" + String.valueOf(file.getRemoteId())); if (thumbnail != null && !file.needsUpdateThumbnail()){ fileIcon.setImageBitmap(thumbnail); } else { @@@ -317,73 -338,35 +337,35 @@@ task ); fileIcon.setImageDrawable(asyncDrawable); - task.execute(file); + task.execute(file, true); } } + + if (file.getMimetype().equalsIgnoreCase("image/png")) { + fileIcon.setBackgroundColor(mContext.getResources() + .getColor(R.color.background_color)); + } + + } else { - fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(), + fileIcon.setImageResource(MimetypeIconUtil.getFileTypeIconId(file.getMimetype(), file.getFileName())); } } else { // Folder - if (checkIfFileIsSharedWithMe(file)) { - fileIcon.setImageResource(R.drawable.shared_with_me_folder); - } else if (file.isShareByLink()) { - // If folder is sharedByLink, icon folder must be changed to - // folder-public one - fileIcon.setImageResource(R.drawable.folder_public); - } else { - fileIcon.setImageResource( - DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName()) - ); - } + fileIcon.setImageResource( + MimetypeIconUtil.getFolderTypeIconId( + file.isSharedWithMe() || file.isSharedWithSharee(), + file.isSharedViaLink() + ) + ); } } return view; } - /** - * Local Folder size in human readable format - * - * @param path - * String - * @return Size in human readable format - */ - private String getFolderSizeHuman(String path) { - - File dir = new File(path); - - if (dir.exists()) { - long bytes = FileStorageUtils.getFolderSize(dir); - return DisplayUtils.bytesToHumanReadable(bytes); - } - - return "0 B"; - } - - /** - * Local Folder size - * @param dir File - * @return Size in bytes - */ - private long getFolderSize(File dir) { - if (dir.exists()) { - long result = 0; - File[] fileList = dir.listFiles(); - for(int i = 0; i < fileList.length; i++) { - if(fileList[i].isDirectory()) { - result += getFolderSize(fileList[i]); - } else { - result += fileList[i].length(); - } - } - return result; - } - return 0; - } - @Override public int getViewTypeCount() { return 1; @@@ -449,20 -432,6 +431,6 @@@ } - /** - * Check if parent folder does not include 'S' permission and if file/folder - * is shared with me - * - * @param file: OCFile - * @return boolean: True if it is shared with me and false if it is not - */ - private boolean checkIfFileIsSharedWithMe(OCFile file) { - return (mFile.getPermissions() != null - && !mFile.getPermissions().contains(PERMISSION_SHARED_WITH_ME) - && file.getPermissions() != null - && file.getPermissions().contains(PERMISSION_SHARED_WITH_ME)); - } - public void setSortOrder(Integer order, boolean ascending) { SharedPreferences.Editor editor = mAppPreferences.edit(); editor.putInt("sortOrder", order); diff --combined src/com/owncloud/android/ui/fragment/OCFileListFragment.java index 8b37f893,066ff0a2..44776368 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@@ -22,18 -22,18 +22,18 @@@ */ package com.owncloud.android.ui.fragment; - import java.io.File; - import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.view.ContextMenu; + import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; + import android.widget.PopupMenu; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; @@@ -48,31 -48,36 +48,36 @@@ import com.owncloud.android.ui.activity import com.owncloud.android.ui.activity.OnEnforceableRefreshListener; import com.owncloud.android.ui.adapter.FileListListAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; + import com.owncloud.android.ui.dialog.FileActionsDialogFragment; import com.owncloud.android.ui.dialog.RemoveFileDialogFragment; import com.owncloud.android.ui.dialog.RenameFileDialogFragment; import com.owncloud.android.ui.preview.PreviewImageFragment; import com.owncloud.android.ui.preview.PreviewMediaFragment; + import com.owncloud.android.ui.preview.PreviewTextFragment; import com.owncloud.android.utils.FileStorageUtils; + import java.io.File; + /** * A Fragment that lists all files and folders in a given path. - * + * * TODO refactor to get rid of direct dependency on FileDisplayActivity */ - public class OCFileListFragment extends ExtendedListFragment { + public class OCFileListFragment extends ExtendedListFragment + implements FileActionsDialogFragment.FileActionsDialogFragmentListener { private static final String TAG = OCFileListFragment.class.getSimpleName(); private static final String MY_PACKAGE = OCFileListFragment.class.getPackage() != null ? OCFileListFragment.class.getPackage().getName() : "com.owncloud.android.ui.fragment"; - + public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS"; public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL"; - + private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE"; private FileFragment.ContainerActivity mContainerActivity; - + private OCFile mFile = null; private FileListListAdapter mAdapter; private boolean mJustFolders; @@@ -90,21 -95,21 +95,21 @@@ Log_OC.e(TAG, "onAttach"); try { mContainerActivity = (FileFragment.ContainerActivity) activity; - + } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement " + + throw new ClassCastException(activity.toString() + " must implement " + FileFragment.ContainerActivity.class.getSimpleName()); } try { setOnRefreshListener((OnEnforceableRefreshListener) activity); } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() + " must implement " + + throw new ClassCastException(activity.toString() + " must implement " + SwipeRefreshLayout.OnRefreshListener.class.getSimpleName()); } } - + @Override public void onDetach() { setOnRefreshListener(null); @@@ -136,41 -141,95 +141,95 @@@ mJustFolders, getActivity(), mContainerActivity - ); + ); setListAdapter(mAdapter); - registerForContextMenu(); + registerLongClickListener(); } + private void registerLongClickListener() { + getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { + public boolean onItemLongClick(AdapterView arg0, View v, + int index, long arg3) { + showFileAction(index); + return true; + } + }); + } + + + private void showFileAction(int fileIndex) { + Bundle args = getArguments(); + PopupMenu pm = new PopupMenu(getActivity(),null); + Menu menu = pm.getMenu(); + + boolean allowContextualActions = + (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); + + if (allowContextualActions) { + MenuInflater inflater = getActivity().getMenuInflater(); + + inflater.inflate(R.menu.file_actions_menu, menu); + OCFile targetFile = (OCFile) mAdapter.getItem(fileIndex); + + if (mContainerActivity.getStorageManager() != null) { + FileMenuFilter mf = new FileMenuFilter( + targetFile, + mContainerActivity.getStorageManager().getAccount(), + mContainerActivity, + getActivity() + ); + mf.filter(menu); + } + + /// TODO break this direct dependency on FileDisplayActivity... if possible + MenuItem item = menu.findItem(R.id.action_open_file_with); + FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment(); + if (frag != null && frag instanceof FileDetailFragment && + frag.getFile().getFileId() == targetFile.getFileId()) { + item = menu.findItem(R.id.action_see_details); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } + } + + FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, + fileIndex, targetFile.getFileName()); + dialog.setTargetFragment(this, 0); + dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS); + } + } + /** * Saves the current listed folder. */ @Override - public void onSaveInstanceState (Bundle outState) { + public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(KEY_FILE, mFile); } - + /** * Call this, when the user presses the up button. - * - * Tries to move up the current folder one level. If the parent folder was removed from the + * + * Tries to move up the current folder one level. If the parent folder was removed from the * database, it continues browsing up until finding an existing folders. - * + *

* return Count of folder levels browsed up. */ public int onBrowseUp() { OCFile parentDir = null; int moveCount = 0; - - if(mFile != null){ + + if (mFile != null) { FileDataStorageManager storageManager = mContainerActivity.getStorageManager(); - + String parentPath = null; if (mFile.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) { parentPath = new File(mFile.getRemotePath()).getParent(); - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : - parentPath + OCFile.PATH_SEPARATOR; + parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : + parentPath + OCFile.PATH_SEPARATOR; parentDir = storageManager.getFileByPath(parentPath); moveCount++; } else { @@@ -178,8 -237,8 +237,8 @@@ } while (parentDir == null) { parentPath = new File(parentPath).getParent(); - parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : - parentPath + OCFile.PATH_SEPARATOR; + parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : + parentPath + OCFile.PATH_SEPARATOR; parentDir = storageManager.getFileByPath(parentPath); moveCount++; } // exit is granted because storageManager.getFileByPath("/") never returns null @@@ -189,20 -248,20 +248,20 @@@ listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/); onRefresh(false); - + // restore index and top position restoreIndexAndTopPosition(); - + } // else - should never happen now - + return moveCount; } - + @Override public void onItemClick(AdapterView l, View v, int position, long id) { OCFile file = (OCFile) mAdapter.getItem(position); if (file != null) { - if (file.isFolder()) { + if (file.isFolder()) { // update state and view of this fragment // TODO Enable when "On Device" is recovered ? listDirectory(file/*, MainApp.getOnlyOnDevice()*/); @@@ -210,46 -269,49 +269,49 @@@ mContainerActivity.onBrowsedDownTo(file); // save index and top position saveIndexAndTopPosition(position); - + } else { /// Click on a file if (PreviewImageFragment.canBePreviewed(file)) { // preview image - it handles the download, if needed ((FileDisplayActivity)mContainerActivity).startImagePreview(file); - + } else if (PreviewTextFragment.canBePreviewed(file)){ + ((FileDisplayActivity)mContainerActivity).startTextPreview(file); } else if (file.isDown()) { if (PreviewMediaFragment.canBePreviewed(file)) { // media preview - ((FileDisplayActivity)mContainerActivity).startMediaPreview(file, 0, true); + ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true); } else { mContainerActivity.getFileOperationsHelper().openFile(file); } - ++ } else { // automatic download, preview on finish ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file); } - ++ } - ++ } else { Log_OC.d(TAG, "Null object in ListAdapter!!"); } - + } - + /** * {@inheritDoc} */ @Override - public void onCreateContextMenu ( + public void onCreateContextMenu( ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); Bundle args = getArguments(); - boolean allowContextualActions = - (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); + boolean allowContextualActions = + (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); if (allowContextualActions) { MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.file_actions_menu, menu); AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; OCFile targetFile = (OCFile) mAdapter.getItem(info.position); - + if (mContainerActivity.getStorageManager() != null) { FileMenuFilter mf = new FileMenuFilter( targetFile, @@@ -273,20 -335,22 +335,22 @@@ } } } - - + /** - * {@inhericDoc} + * {@inheritDoc} */ @Override - public boolean onContextItemSelected (MenuItem item) { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); - mTargetFile = (OCFile) mAdapter.getItem(info.position); - switch (item.getItemId()) { + public boolean onFileActionChosen(int menuId, int filePosition) { + mTargetFile = (OCFile) mAdapter.getItem(filePosition); + switch (menuId) { case R.id.action_share_file: { mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile); return true; } + case R.id.action_share_with_users: { + mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile); + return true; + } case R.id.action_open_file_with: { mContainerActivity.getFileOperationsHelper().openFile(mTargetFile); return true; @@@ -305,13 -369,12 +369,12 @@@ dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION); return true; } - case R.id.action_download_file: + case R.id.action_download_file: case R.id.action_sync_file: { mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile); return true; } - case R.id.action_cancel_download: - case R.id.action_cancel_upload: { + case R.id.action_cancel_sync: { ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile); return true; } @@@ -323,8 -386,8 +386,8 @@@ // Obtain the file if (!mTargetFile.isDown()) { // Download the file Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded"); - ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile); - + ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile); + } else { mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile); } @@@ -338,8 -401,38 +401,38 @@@ getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES); return true; } + case R.id.action_favorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true); + return true; + } + case R.id.action_unfavorite_file: { + mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false); + return true; + } + case R.id.action_copy: + Intent action = new Intent(getActivity(), FolderPickerActivity.class); + + // Pass mTargetFile that contains info of selected file/folder + action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile); + getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES); + return true; default: - return super.onContextItemSelected(item); + return false; + } + } + + /** + * {@inhericDoc} + */ + @Override + public boolean onContextItemSelected (MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); + boolean matched = onFileActionChosen(item.getItemId(), + ((AdapterContextMenuInfo) item.getMenuInfo()).position); + if(!matched) { + return super.onContextItemSelected(item); + } else { + return matched; } } @@@ -347,12 -440,13 +440,13 @@@ /** * Use this to query the {@link OCFile} that is currently * being displayed by this fragment + * * @return The currently viewed OCFile */ - public OCFile getCurrentFile(){ + public OCFile getCurrentFile() { return mFile; } - + /** * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter */ @@@ -366,12 -460,12 +460,12 @@@ // TODO Enable when "On Device" is recovered ? listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/); } - + /** * Lists the given directory on the view. When the input parameter is null, * it will either refresh the last known directory. list the root * if there never was a directory. - * + * * @param directory File to be listed */ public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) { @@@ -379,18 -473,18 +473,18 @@@ if (storageManager != null) { // Check input parameters for null - if(directory == null){ - if(mFile != null){ + if (directory == null) { + if (mFile != null) { directory = mFile; } else { directory = storageManager.getFileByPath("/"); if (directory == null) return; // no files, wait for sync } } - - + + // If that's not a directory -> List its parent - if(!directory.isFolder()){ + if (!directory.isFolder()) { Log_OC.w(TAG, "You see, that is not a directory -> " + directory.toString()); directory = storageManager.getFileById(directory.getParentId()); } @@@ -417,9 -511,12 +511,12 @@@ if (file.isFolder()) { foldersCount++; } else { - filesCount++; - if (file.isImage()){ - imagesCount++; + if (!file.isHidden()) { + filesCount++; + + if (file.isImage()) { + imagesCount++; + } } } } @@@ -432,6 -529,7 +529,7 @@@ if (version != null && version.supportsRemoteThumbnails() && imagesCount > 0 && imagesCount == filesCount) { switchToGridView(); + registerLongClickListener(); } else { switchToListView(); } @@@ -439,27 -537,45 +537,45 @@@ } private String generateFooterText(int filesCount, int foldersCount) { - String output = ""; - if (filesCount > 0){ - if (filesCount == 1) { - output = output + filesCount + " " + getResources().getString(R.string.file_list_file); - } else { - output = output + filesCount + " " + getResources().getString(R.string.file_list_files); + String output; + if (filesCount <= 0) { + if (foldersCount <= 0) { + output = ""; + + } else if (foldersCount == 1) { + output = getResources().getString(R.string.file_list__footer__folder); + + } else { // foldersCount > 1 + output = getResources().getString(R.string.file_list__footer__folders, foldersCount); } - } - if (foldersCount > 0 && filesCount > 0){ - output = output + ", "; - } - if (foldersCount == 1) { - output = output + foldersCount + " " + getResources().getString(R.string.file_list_folder); - } else if (foldersCount > 1) { - output = output + foldersCount + " " + getResources().getString(R.string.file_list_folders); - } + } else if (filesCount == 1) { + if (foldersCount <= 0) { + output = getResources().getString(R.string.file_list__footer__file); + + } else if (foldersCount == 1) { + output = getResources().getString(R.string.file_list__footer__file_and_folder); + + } else { // foldersCount > 1 + output = getResources().getString(R.string.file_list__footer__file_and_folders, foldersCount); + } + } else { // filesCount > 1 + if (foldersCount <= 0) { + output = getResources().getString(R.string.file_list__footer__files, filesCount); + + } else if (foldersCount == 1) { + output = getResources().getString(R.string.file_list__footer__files_and_folder, filesCount); + + } else { // foldersCount > 1 + output = getResources().getString( + R.string.file_list__footer__files_and_folders, filesCount, foldersCount + ); + + } + } return output; } - public void sortByName(boolean descending) { mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending); } @@@ -470,8 -586,5 +586,5 @@@ public void sortBySize(boolean descending) { mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending); - } - - - + } } diff --combined src/com/owncloud/android/ui/preview/PreviewImageActivity.java index bfb02d3b,20b8de1d..213fcd3a --- a/src/com/owncloud/android/ui/preview/PreviewImageActivity.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageActivity.java @@@ -53,13 -53,15 +53,15 @@@ import com.owncloud.android.lib.common. import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.lib.common.utils.Log_OC; - import com.owncloud.android.operations.CreateShareOperation; + import com.owncloud.android.operations.CreateShareViaLinkOperation; + import com.owncloud.android.operations.CreateShareWithShareeOperation; import com.owncloud.android.operations.RemoveFileOperation; - import com.owncloud.android.operations.UnshareLinkOperation; + import com.owncloud.android.operations.SynchronizeFileOperation; + import com.owncloud.android.operations.UnshareOperation; import com.owncloud.android.ui.activity.FileActivity; import com.owncloud.android.ui.activity.FileDisplayActivity; + import com.owncloud.android.ui.activity.ShareActivity; import com.owncloud.android.ui.fragment.FileFragment; - import com.owncloud.android.utils.DisplayUtils; /** @@@ -103,7 -105,6 +105,6 @@@ public class PreviewImageActivity exten // ActionBar ActionBar actionBar = getSupportActionBar(); - actionBar.setIcon(DisplayUtils.getSeasonalIconId()); updateActionBarTitleAndHomeButton(null); actionBar.hide(); @@@ -132,6 -133,9 +133,9 @@@ } }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + getWindow().setStatusBarColor(getResources().getColor(R.color.owncloud_blue_dark_transparent)); + } } if (savedInstanceState != null) { @@@ -226,19 -230,23 +230,23 @@@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) { super.onRemoteOperationFinish(operation, result); - if (operation instanceof CreateShareOperation) { - onCreateShareOperationFinish((CreateShareOperation) operation, result); - - } else if (operation instanceof UnshareLinkOperation) { - onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result); + if (operation instanceof CreateShareViaLinkOperation || + operation instanceof CreateShareWithShareeOperation) { + onCreateShareOperationFinish(result); + + } else if (operation instanceof UnshareOperation) { + onUnshareLinkOperationFinish((UnshareOperation) operation, result); } else if (operation instanceof RemoveFileOperation) { finish(); + } else if (operation instanceof SynchronizeFileOperation) { + onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result); + } } - private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, + private void onUnshareLinkOperationFinish(UnshareOperation operation, RemoteOperationResult result) { if (result.isSuccess()) { OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); @@@ -252,8 -260,7 +260,7 @@@ } - private void onCreateShareOperationFinish(CreateShareOperation operation, - RemoteOperationResult result) { + private void onCreateShareOperationFinish(RemoteOperationResult result) { if (result.isSuccess()) { OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath()); if (file != null) { @@@ -263,6 -270,14 +270,14 @@@ } } + private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, + RemoteOperationResult result) { + if (result.isSuccess()) { + invalidateOptionsMenu(); + } + + } + @Override protected ServiceConnection newTransferenceServiceConnection() { return new PreviewImageServiceConnection(); @@@ -385,7 -400,6 +400,6 @@@ } - private void requestForDownload(OCFile file) { if (mDownloaderBinder == null) { Log_OC.d(TAG, "requestForDownload called without binder to download service"); @@@ -415,7 -429,12 +429,7 @@@ OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); getSupportActionBar().setTitle(currentFile.getFileName()); mDrawerToggle.setDrawerIndicatorEnabled(false); - if (!currentFile.isDown()) { - if (!mPreviewImagePagerAdapter.pendingErrorAt(position)) { - requestForDownload(currentFile); - } - } - + // Call to reset image zoom to initial state ((PreviewImagePagerAdapter) mViewPager.getAdapter()).resetZoom(); } @@@ -593,7 -612,7 +607,7 @@@ /** * Checks if OS version is Honeycomb one or higher - * + * * @return boolean */ private boolean isHoneycombOrHigher() { diff --combined src/com/owncloud/android/ui/preview/PreviewImageFragment.java index 5ef10405,a114fabd..0166829b --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@@ -26,6 -26,7 +26,7 @@@ import android.annotation.SuppressLint import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Point; + import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentStatePagerAdapter; @@@ -40,10 -41,8 +41,10 @@@ import android.widget.ImageView import android.widget.ProgressBar; import android.widget.TextView; +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; @@@ -70,20 -69,17 +71,20 @@@ public class PreviewImageFragment exten private static final String ARG_FILE = "FILE"; private static final String ARG_IGNORE_FIRST = "IGNORE_FIRST"; + private static final String ARG_SHOW_RESIZED_IMAGE = "SHOW_RESIZED_IMAGE"; private TouchImageViewCustom mImageView; 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; @@@ -101,19 -97,16 +102,19 @@@ * {@link FragmentStatePagerAdapter} * ; TODO better solution */ - public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){ + public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState, + boolean showResizedImage){ PreviewImageFragment frag = new PreviewImageFragment(); + frag.mShowResizedImage = showResizedImage; Bundle args = new Bundle(); args.putParcelable(ARG_FILE, imageFile); args.putBoolean(ARG_IGNORE_FIRST, ignoreFirstSavedState); + args.putBoolean(ARG_SHOW_RESIZED_IMAGE, showResizedImage); frag.setArguments(args); return frag; } - + /** * Creates an empty fragment for image previews. @@@ -127,8 -120,8 +128,8 @@@ public PreviewImageFragment() { mIgnoreFirstSavedState = false; } - - + + /** * {@inheritDoc} */ @@@ -141,17 -134,16 +142,17 @@@ // not right now mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST); + mShowResizedImage = args.getBoolean(ARG_SHOW_RESIZED_IMAGE); setHasOptionsMenu(true); } - + /** * {@inheritDoc} */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.preview_image_fragment, container, false); mImageView = (TouchImageViewCustom) view.findViewById(R.id.image); @@@ -187,8 -179,11 +188,8 @@@ if (getFile() == null) { throw new IllegalStateException("Instanced with a NULL OCFile"); } - if (!getFile().isDown()) { - throw new IllegalStateException("There is no local file to preview"); - } } - + /** * {@inheritDoc} @@@ -198,54 -193,20 +199,54 @@@ super.onSaveInstanceState(outState); outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile()); } - + @Override public void onStart() { super.onStart(); if (getFile() != null) { - mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel); - //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()}); -// mLoadBitmapTask.execute(getFile().getStoragePath()); - mLoadBitmapTask.execute(getFile()); + 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.setVisibility(View.VISIBLE); + mBitmap = thumbnail; + } else { + // generate new Thumbnail + if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView) && + mContainerActivity.getStorageManager() != null) { + final ThumbnailsCacheManager.ThumbnailGenerationTask task = + new ThumbnailsCacheManager.ThumbnailGenerationTask( + mImageView, mContainerActivity.getStorageManager(), + mContainerActivity.getStorageManager().getAccount(), + 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(getFile().getStoragePath()); ++ mLoadBitmapTask.execute(getFile()); + } } } - - + + @Override public void onStop() { Log_OC.d(TAG, "onStop starts"); @@@ -255,7 -216,7 +256,7 @@@ } super.onStop(); } - + /** * {@inheritDoc} */ @@@ -271,11 -232,11 +272,11 @@@ @Override public void onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); - + if (mContainerActivity.getStorageManager() != null) { // Update the file setFile(mContainerActivity.getStorageManager().getFileById(getFile().getFileId())); - + FileMenuFilter mf = new FileMenuFilter( getFile(), mContainerActivity.getStorageManager().getAccount(), @@@ -284,7 -245,7 +285,7 @@@ ); mf.filter(menu); } - + // additional restriction for this fragment // TODO allow renaming in PreviewImageFragment MenuItem item = menu.findItem(R.id.action_rename_file); @@@ -292,7 -253,7 +293,7 @@@ item.setVisible(false); item.setEnabled(false); } - + // additional restriction for this fragment // TODO allow refresh file in PreviewImageFragment item = menu.findItem(R.id.action_sync_file); @@@ -307,11 -268,17 +308,17 @@@ item.setVisible(false); item.setEnabled(false); } - + + // additional restriction for this fragment + item = menu.findItem(R.id.action_copy); + if (item != null) { + item.setVisible(false); + item.setEnabled(false); + } + } - - + /** * {@inheritDoc} */ @@@ -322,6 -289,10 +329,10 @@@ mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile()); return true; } + case R.id.action_share_with_users: { + mContainerActivity.getFileOperationsHelper().showShareFile(getFile()); + return true; + } case R.id.action_unshare_file: { mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile()); return true; @@@ -340,31 -311,31 +351,37 @@@ 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_download_file: case R.id.action_sync_file: { mContainerActivity.getFileOperationsHelper().syncFile(getFile()); return true; } - + case R.id.action_favorite_file:{ + mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), true); + return true; + } + case R.id.action_unfavorite_file:{ + mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false); + return true; + } default: return false; } } - + private void seeDetails() { - mContainerActivity.showDetails(getFile()); + mContainerActivity.showDetails(getFile()); } - @Override public void onResume() { super.onResume(); @@@ -388,7 -359,7 +405,7 @@@ super.onDestroy(); } - + /** * Opens the previewed image with an external application. */ @@@ -396,9 -367,9 +413,9 @@@ mContainerActivity.getFileOperationsHelper().openFile(getFile()); finish(); } + - - private class LoadBitmapTask extends AsyncTask { + private class LoadBitmapTask extends AsyncTask { /** * Weak reference to the target {@link ImageView} where the bitmap will be loaded into. @@@ -416,7 -387,7 +433,7 @@@ */ private final WeakReference mMessageViewRef; - + /** * Weak reference to the target {@link ProgressBar} shown while the load is in progress. * @@@ -425,17 -396,17 +442,17 @@@ */ private final WeakReference mProgressWheelRef; - + /** - * Error message to show when a load fails + * Error message to show when a load fails */ private int mErrorMessageId; - - + + /** * Constructor. - * - * @param imageView Target {@link ImageView} where the bitmap will be loaded into. + * + * @param imageView Target {@link ImageView} where the bitmap will be loaded into. */ public LoadBitmapTask(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) { @@@ -443,13 -414,13 +460,13 @@@ mMessageViewRef = new WeakReference(messageView); mProgressWheelRef = new WeakReference(progressWheel); } - - + @Override - protected Bitmap doInBackground(String... params) { + protected LoadImage doInBackground(OCFile... params) { Bitmap result = null; if (params.length != 1) return null; - String storagePath = params[0]; + OCFile ocFile = params[0]; + String storagePath = ocFile.getStoragePath(); try { int maxDownScale = 3; // could be a parameter passed to doInBackground(...) @@@ -462,7 -433,7 +479,7 @@@ result = BitmapUtils.decodeSampledBitmapFromFile(storagePath, minWidth, minHeight); - if (isCancelled()) return result; + if (isCancelled()) return new LoadImage(result, ocFile); if (result == null) { mErrorMessageId = R.string.preview_image_error_unknown_format; @@@ -494,48 -465,56 +511,56 @@@ } 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; + + return new LoadImage(result, ocFile); } - + @Override - protected void onCancelled(Bitmap result) { - if (result != null) { - result.recycle(); + protected void onCancelled(LoadImage result) { + if (result != null && result.bitmap != null) { + result.bitmap.recycle(); } } @Override - protected void onPostExecute(Bitmap result) { + protected void onPostExecute(LoadImage result) { hideProgressWheel(); - if (result != null) { + if (result.bitmap != null) { showLoadedImage(result); - } else { + } + else { showErrorMessage(); } - if (result != null && mBitmap != result) { + if (result.bitmap != null && mBitmap != result.bitmap) { // unused bitmap, release it! (just in case) - result.recycle(); + result.bitmap.recycle(); } } - + @SuppressLint("InlinedApi") - private void showLoadedImage(Bitmap result) { + 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 " + result.getWidth() + "x" + - result.getHeight()); - imageView.setImageBitmap(result); + Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" + + bitmap.getHeight()); + + if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")){ + Drawable backrepeat = getResources().getDrawable(R.drawable.backrepeat); + imageView.setBackground(backrepeat); + } + + imageView.setImageBitmap(bitmap); imageView.setVisibility(View.VISIBLE); - mBitmap = result; // needs to be kept for recycling when not useful + mBitmap = bitmap; // needs to be kept for recycling when not useful } final TextView messageView = mMessageViewRef.get(); @@@ -543,7 -522,7 +568,7 @@@ messageView.setVisibility(View.GONE); } // else , silently finish, the fragment was destroyed } - + private void showErrorMessage() { final ImageView imageView = mImageViewRef.get(); if (imageView != null) { @@@ -557,14 -536,14 +582,14 @@@ messageView.setVisibility(View.VISIBLE); } // else , silently finish, the fragment was destroyed } - + private void hideProgressWheel() { final ProgressBar progressWheel = mProgressWheelRef.get(); if (progressWheel != null) { progressWheel.setVisibility(View.GONE); } } - + } /** @@@ -578,7 -557,7 +603,7 @@@ return (file != null && file.isImage()); } - + /** * Finishes the preview */ @@@ -586,9 -565,20 +611,20 @@@ Activity container = getActivity(); container.finish(); } - + public TouchImageViewCustom getImageView() { return mImageView; } + private class LoadImage { + private Bitmap bitmap; + private OCFile ocFile; + + public LoadImage(Bitmap bitmap, OCFile ocFile){ + this.bitmap = bitmap; + this.ocFile = ocFile; + } + + } + }