From 4203939d628c81e8d271157771fc68ccabad7bae Mon Sep 17 00:00:00 2001 From: tibbi Date: Mon, 2 Oct 2017 18:27:42 +0200 Subject: [PATCH] fix #378, allow adding multiple items as email attachments --- app/build.gradle | 2 +- .../gallery/activities/MainActivity.kt | 78 ++++++++++++------- .../gallery/activities/MediaActivity.kt | 12 ++- .../gallery/adapters/MediaAdapter.kt | 18 ++++- .../gallery/dialogs/PickMediumDialog.kt | 2 +- .../gallery/helpers/Constants.kt | 1 + app/src/main/res/menu/cab_media.xml | 5 ++ 7 files changed, 84 insertions(+), 34 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 44cc83b52..41c499e1e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -37,7 +37,7 @@ android { } dependencies { - compile 'com.simplemobiletools:commons:2.29.0' + compile 'com.simplemobiletools:commons:2.29.1' compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.6.0' compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0' compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt index 76d0303a3..8a9da9d4a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt @@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.activities import android.Manifest import android.app.Activity +import android.content.ClipData import android.content.Intent import android.content.pm.PackageManager import android.net.Uri @@ -412,36 +413,22 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { if (resultCode == Activity.RESULT_OK) { - if (requestCode == PICK_MEDIA && resultData?.data != null) { - Intent().apply { + if (requestCode == PICK_MEDIA && resultData != null) { + val resultIntent = Intent() + if (mIsGetImageContentIntent || mIsGetVideoContentIntent || mIsGetAnyContentIntent) { + when { + intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true -> fillExtraOutput(resultData) + resultData.extras?.containsKey(PICKED_PATHS) == true -> fillPickedPaths(resultData, resultIntent) + else -> fillIntentPath(resultData, resultIntent) + } + } else if ((mIsPickImageIntent || mIsPickVideoIntent)) { val path = resultData.data.path val uri = Uri.fromFile(File(path)) - if (mIsGetImageContentIntent || mIsGetVideoContentIntent || mIsGetAnyContentIntent) { - if (intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true) { - var inputStream: InputStream? = null - var outputStream: OutputStream? = null - try { - val output = intent.extras.get(MediaStore.EXTRA_OUTPUT) as Uri - inputStream = FileInputStream(File(path)) - outputStream = contentResolver.openOutputStream(output) - inputStream.copyTo(outputStream) - } catch (ignored: FileNotFoundException) { - } finally { - inputStream?.close() - outputStream?.close() - } - } else { - val type = File(path).getMimeType("image/jpeg") - setDataAndTypeAndNormalize(uri, type) - flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION - } - } else if (mIsPickImageIntent || mIsPickVideoIntent) { - data = uri - flags = Intent.FLAG_GRANT_READ_URI_PERMISSION - } - - setResult(Activity.RESULT_OK, this) + resultIntent.data = uri + resultIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION } + + setResult(Activity.RESULT_OK, resultIntent) finish() } else if (requestCode == PICK_WALLPAPER) { setResult(Activity.RESULT_OK) @@ -451,6 +438,42 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { super.onActivityResult(requestCode, resultCode, resultData) } + private fun fillExtraOutput(resultData: Intent) { + val path = resultData.data.path + var inputStream: InputStream? = null + var outputStream: OutputStream? = null + try { + val output = intent.extras.get(MediaStore.EXTRA_OUTPUT) as Uri + inputStream = FileInputStream(File(path)) + outputStream = contentResolver.openOutputStream(output) + inputStream.copyTo(outputStream) + } catch (ignored: FileNotFoundException) { + } finally { + inputStream?.close() + outputStream?.close() + } + } + + private fun fillPickedPaths(resultData: Intent, resultIntent: Intent) { + val paths = resultData.extras.getStringArrayList(PICKED_PATHS) + val uris = paths.map { Uri.fromFile(File(it)) } as ArrayList + val clipData = ClipData("Attachment", arrayOf("image/*", "video/*"), ClipData.Item(uris.removeAt(0))) + + uris.forEach { + clipData.addItem(ClipData.Item(it)) + } + + resultIntent.clipData = clipData + } + + private fun fillIntentPath(resultData: Intent, resultIntent: Intent) { + val path = resultData.data.path + val uri = Uri.fromFile(File(path)) + val type = File(path).getMimeType("image/jpeg") + resultIntent.setDataAndTypeAndNormalize(uri, type) + resultIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION + } + private fun itemClicked(path: String) { Intent(this, MediaActivity::class.java).apply { putExtra(DIRECTORY, path) @@ -462,6 +485,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener { putExtra(GET_IMAGE_INTENT, mIsPickImageIntent || mIsGetImageContentIntent) putExtra(GET_VIDEO_INTENT, mIsPickVideoIntent || mIsGetVideoContentIntent) putExtra(GET_ANY_INTENT, mIsGetAnyContentIntent) + putExtra(Intent.EXTRA_ALLOW_MULTIPLE, intent.getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)) startActivityForResult(this, PICK_MEDIA) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt index f9816269f..4851c7305 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt @@ -46,6 +46,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { private var mIsGetVideoIntent = false private var mIsGetAnyIntent = false private var mIsGettingMedia = false + private var mAllowPickingMultiple = false private var mShowAll = false private var mLoadedInitialPhotos = false private var mStoredAnimateGifs = true @@ -68,6 +69,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { mIsGetImageIntent = getBooleanExtra(GET_IMAGE_INTENT, false) mIsGetVideoIntent = getBooleanExtra(GET_VIDEO_INTENT, false) mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false) + mAllowPickingMultiple = getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false) } media_refresh_layout.setOnRefreshListener({ getMedia() }) @@ -159,7 +161,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { val currAdapter = media_grid.adapter if (currAdapter == null) { - media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetAnyIntent) { + media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetAnyIntent, mAllowPickingMultiple) { itemClicked(it.path) } } else { @@ -561,4 +563,12 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener { override fun itemLongClicked(position: Int) { media_grid.setDragSelectActive(position) } + + override fun selectedPaths(paths: ArrayList) { + Intent().apply { + putExtra(PICKED_PATHS, paths) + setResult(Activity.RESULT_OK, this) + } + finish() + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt index 50a03e7ca..7296f51d7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt @@ -25,7 +25,7 @@ import java.io.File import java.util.* class MediaAdapter(val activity: SimpleActivity, var media: MutableList, val listener: MediaOperationsListener?, val isPickIntent: Boolean, - val itemClick: (Medium) -> Unit) : RecyclerView.Adapter() { + val allowMultiplePicks: Boolean, val itemClick: (Medium) -> Unit) : RecyclerView.Adapter() { val multiSelector = MultiSelector() val config = activity.config @@ -72,6 +72,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) { override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { when (item.itemId) { + R.id.cab_confirm_selection -> confirmSelection() R.id.cab_properties -> showProperties() R.id.cab_rename -> renameFile() R.id.cab_edit -> editFile() @@ -97,6 +98,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean { menu.findItem(R.id.cab_rename).isVisible = selectedPositions.size <= 1 menu.findItem(R.id.cab_edit).isVisible = selectedPositions.size == 1 && media.size > selectedPositions.first() && media[selectedPositions.first()].isImage() + menu.findItem(R.id.cab_confirm_selection).isVisible = isPickIntent && allowMultiplePicks && selectedPositions.size > 0 checkHideBtnVisibility(menu) @@ -127,6 +129,11 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, } } + private fun confirmSelection() { + val paths = getSelectedMedia().map { it.path } as ArrayList + listener?.selectedPaths(paths) + } + private fun showProperties() { if (selectedPositions.size <= 1) { PropertiesDialog(activity, media[selectedPositions.first()].path, config.shouldShowHidden) @@ -247,7 +254,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder { val layoutType = if (isListViewType) R.layout.photo_video_item_list else R.layout.photo_video_item_grid val view = LayoutInflater.from(parent?.context).inflate(layoutType, parent, false) - return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, isPickIntent, itemClick) + return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, allowMultiplePicks || !isPickIntent, itemClick) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { @@ -319,7 +326,8 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, } class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback, - val multiSelector: MultiSelector, val listener: MediaOperationsListener?, val isPickIntent: Boolean, val itemClick: (Medium) -> (Unit)) : + val multiSelector: MultiSelector, val listener: MediaOperationsListener?, val allowMultiplePicks: Boolean, + val itemClick: (Medium) -> (Unit)) : SwappingHolder(view, MultiSelector()) { fun bindView(medium: Medium, displayFilenames: Boolean, scrollVertically: Boolean, isListViewType: Boolean, textColor: Int): View { itemView.apply { @@ -334,7 +342,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, } setOnClickListener { viewClicked(medium) } - setOnLongClickListener { if (isPickIntent) viewClicked(medium) else viewLongClicked(); true } + setOnLongClickListener { if (allowMultiplePicks) viewLongClicked() else viewClicked(medium); true } } return itemView } @@ -377,5 +385,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList, fun deleteFiles(files: ArrayList) fun itemLongClicked(position: Int) + + fun selectedPaths(paths: ArrayList) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt index 4c57c68f1..fe0a86add 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt @@ -47,7 +47,7 @@ class PickMediumDialog(val activity: SimpleActivity, val path: String, val callb return shownMedia = media - val adapter = MediaAdapter(activity, media, null, true) { + val adapter = MediaAdapter(activity, media, null, true, false) { callback(it.path) dialog.dismiss() } diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt index 18bf6ac29..d875a0f18 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt @@ -63,6 +63,7 @@ val SET_WALLPAPER_INTENT = "set_wallpaper_intent" val DIRECTORIES = "directories2" val IS_VIEW_INTENT = "is_view_intent" val IS_FROM_GALLERY = "is_from_gallery" +val PICKED_PATHS = "picked_paths" val REQUEST_EDIT_IMAGE = 1 val REQUEST_SET_AS = 2 diff --git a/app/src/main/res/menu/cab_media.xml b/app/src/main/res/menu/cab_media.xml index 4b47e6025..fa787d520 100644 --- a/app/src/main/res/menu/cab_media.xml +++ b/app/src/main/res/menu/cab_media.xml @@ -1,6 +1,11 @@ +