fix #378, allow adding multiple items as email attachments

This commit is contained in:
tibbi 2017-10-02 18:27:42 +02:00
parent 9b112d0827
commit 4203939d62
7 changed files with 84 additions and 34 deletions

View file

@ -37,7 +37,7 @@ android {
} }
dependencies { 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.davemorrissey.labs:subsampling-scale-image-view:3.6.0'
compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0' compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0'
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2' compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'

View file

@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.activities
import android.Manifest import android.Manifest
import android.app.Activity import android.app.Activity
import android.content.ClipData
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
@ -412,12 +413,33 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_MEDIA && resultData?.data != null) { if (requestCode == PICK_MEDIA && resultData != null) {
Intent().apply { 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 path = resultData.data.path
val uri = Uri.fromFile(File(path)) val uri = Uri.fromFile(File(path))
if (mIsGetImageContentIntent || mIsGetVideoContentIntent || mIsGetAnyContentIntent) { resultIntent.data = uri
if (intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true) { resultIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}
setResult(Activity.RESULT_OK, resultIntent)
finish()
} else if (requestCode == PICK_WALLPAPER) {
setResult(Activity.RESULT_OK)
finish()
}
}
super.onActivityResult(requestCode, resultCode, resultData)
}
private fun fillExtraOutput(resultData: Intent) {
val path = resultData.data.path
var inputStream: InputStream? = null var inputStream: InputStream? = null
var outputStream: OutputStream? = null var outputStream: OutputStream? = null
try { try {
@ -430,25 +452,26 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
inputStream?.close() inputStream?.close()
outputStream?.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) 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))
} }
finish()
} else if (requestCode == PICK_WALLPAPER) { resultIntent.clipData = clipData
setResult(Activity.RESULT_OK)
finish()
} }
}
super.onActivityResult(requestCode, resultCode, resultData) 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) { private fun itemClicked(path: String) {
@ -462,6 +485,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
putExtra(GET_IMAGE_INTENT, mIsPickImageIntent || mIsGetImageContentIntent) putExtra(GET_IMAGE_INTENT, mIsPickImageIntent || mIsGetImageContentIntent)
putExtra(GET_VIDEO_INTENT, mIsPickVideoIntent || mIsGetVideoContentIntent) putExtra(GET_VIDEO_INTENT, mIsPickVideoIntent || mIsGetVideoContentIntent)
putExtra(GET_ANY_INTENT, mIsGetAnyContentIntent) putExtra(GET_ANY_INTENT, mIsGetAnyContentIntent)
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, intent.getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false))
startActivityForResult(this, PICK_MEDIA) startActivityForResult(this, PICK_MEDIA)
} }
} }

View file

@ -46,6 +46,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
private var mIsGetVideoIntent = false private var mIsGetVideoIntent = false
private var mIsGetAnyIntent = false private var mIsGetAnyIntent = false
private var mIsGettingMedia = false private var mIsGettingMedia = false
private var mAllowPickingMultiple = false
private var mShowAll = false private var mShowAll = false
private var mLoadedInitialPhotos = false private var mLoadedInitialPhotos = false
private var mStoredAnimateGifs = true private var mStoredAnimateGifs = true
@ -68,6 +69,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
mIsGetImageIntent = getBooleanExtra(GET_IMAGE_INTENT, false) mIsGetImageIntent = getBooleanExtra(GET_IMAGE_INTENT, false)
mIsGetVideoIntent = getBooleanExtra(GET_VIDEO_INTENT, false) mIsGetVideoIntent = getBooleanExtra(GET_VIDEO_INTENT, false)
mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false) mIsGetAnyIntent = getBooleanExtra(GET_ANY_INTENT, false)
mAllowPickingMultiple = getBooleanExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)
} }
media_refresh_layout.setOnRefreshListener({ getMedia() }) media_refresh_layout.setOnRefreshListener({ getMedia() })
@ -159,7 +161,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
val currAdapter = media_grid.adapter val currAdapter = media_grid.adapter
if (currAdapter == null) { if (currAdapter == null) {
media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetAnyIntent) { media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetAnyIntent, mAllowPickingMultiple) {
itemClicked(it.path) itemClicked(it.path)
} }
} else { } else {
@ -561,4 +563,12 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
override fun itemLongClicked(position: Int) { override fun itemLongClicked(position: Int) {
media_grid.setDragSelectActive(position) media_grid.setDragSelectActive(position)
} }
override fun selectedPaths(paths: ArrayList<String>) {
Intent().apply {
putExtra(PICKED_PATHS, paths)
setResult(Activity.RESULT_OK, this)
}
finish()
}
} }

View file

@ -25,7 +25,7 @@ import java.io.File
import java.util.* import java.util.*
class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>, val listener: MediaOperationsListener?, val isPickIntent: Boolean, class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>, val listener: MediaOperationsListener?, val isPickIntent: Boolean,
val itemClick: (Medium) -> Unit) : RecyclerView.Adapter<MediaAdapter.ViewHolder>() { val allowMultiplePicks: Boolean, val itemClick: (Medium) -> Unit) : RecyclerView.Adapter<MediaAdapter.ViewHolder>() {
val multiSelector = MultiSelector() val multiSelector = MultiSelector()
val config = activity.config val config = activity.config
@ -72,6 +72,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) { private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.cab_confirm_selection -> confirmSelection()
R.id.cab_properties -> showProperties() R.id.cab_properties -> showProperties()
R.id.cab_rename -> renameFile() R.id.cab_rename -> renameFile()
R.id.cab_edit -> editFile() R.id.cab_edit -> editFile()
@ -97,6 +98,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean { override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
menu.findItem(R.id.cab_rename).isVisible = selectedPositions.size <= 1 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_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) checkHideBtnVisibility(menu)
@ -127,6 +129,11 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
} }
} }
private fun confirmSelection() {
val paths = getSelectedMedia().map { it.path } as ArrayList<String>
listener?.selectedPaths(paths)
}
private fun showProperties() { private fun showProperties() {
if (selectedPositions.size <= 1) { if (selectedPositions.size <= 1) {
PropertiesDialog(activity, media[selectedPositions.first()].path, config.shouldShowHidden) PropertiesDialog(activity, media[selectedPositions.first()].path, config.shouldShowHidden)
@ -247,7 +254,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder { 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 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) 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) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
@ -319,7 +326,8 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
} }
class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback, 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()) { SwappingHolder(view, MultiSelector()) {
fun bindView(medium: Medium, displayFilenames: Boolean, scrollVertically: Boolean, isListViewType: Boolean, textColor: Int): View { fun bindView(medium: Medium, displayFilenames: Boolean, scrollVertically: Boolean, isListViewType: Boolean, textColor: Int): View {
itemView.apply { itemView.apply {
@ -334,7 +342,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
} }
setOnClickListener { viewClicked(medium) } setOnClickListener { viewClicked(medium) }
setOnLongClickListener { if (isPickIntent) viewClicked(medium) else viewLongClicked(); true } setOnLongClickListener { if (allowMultiplePicks) viewLongClicked() else viewClicked(medium); true }
} }
return itemView return itemView
} }
@ -377,5 +385,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
fun deleteFiles(files: ArrayList<File>) fun deleteFiles(files: ArrayList<File>)
fun itemLongClicked(position: Int) fun itemLongClicked(position: Int)
fun selectedPaths(paths: ArrayList<String>)
} }
} }

View file

@ -47,7 +47,7 @@ class PickMediumDialog(val activity: SimpleActivity, val path: String, val callb
return return
shownMedia = media shownMedia = media
val adapter = MediaAdapter(activity, media, null, true) { val adapter = MediaAdapter(activity, media, null, true, false) {
callback(it.path) callback(it.path)
dialog.dismiss() dialog.dismiss()
} }

View file

@ -63,6 +63,7 @@ val SET_WALLPAPER_INTENT = "set_wallpaper_intent"
val DIRECTORIES = "directories2" val DIRECTORIES = "directories2"
val IS_VIEW_INTENT = "is_view_intent" val IS_VIEW_INTENT = "is_view_intent"
val IS_FROM_GALLERY = "is_from_gallery" val IS_FROM_GALLERY = "is_from_gallery"
val PICKED_PATHS = "picked_paths"
val REQUEST_EDIT_IMAGE = 1 val REQUEST_EDIT_IMAGE = 1
val REQUEST_SET_AS = 2 val REQUEST_SET_AS = 2

View file

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/cab_confirm_selection"
android:icon="@drawable/ic_check"
android:title="@string/confirm_selection"
app:showAsAction="ifRoom"/>
<item <item
android:id="@+id/cab_delete" android:id="@+id/cab_delete"
android:icon="@drawable/ic_delete" android:icon="@drawable/ic_delete"