mirror of
https://github.com/FossifyOrg/Gallery.git
synced 2024-11-26 22:47:59 +01:00
fix #378, allow adding multiple items as email attachments
This commit is contained in:
parent
9b112d0827
commit
4203939d62
7 changed files with 84 additions and 34 deletions
|
@ -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'
|
||||||
|
|
|
@ -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,36 +413,22 @@ 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
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setResult(Activity.RESULT_OK, resultIntent)
|
||||||
finish()
|
finish()
|
||||||
} else if (requestCode == PICK_WALLPAPER) {
|
} else if (requestCode == PICK_WALLPAPER) {
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK)
|
||||||
|
@ -451,6 +438,42 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
|
||||||
super.onActivityResult(requestCode, resultCode, resultData)
|
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) {
|
private fun itemClicked(path: String) {
|
||||||
Intent(this, MediaActivity::class.java).apply {
|
Intent(this, MediaActivity::class.java).apply {
|
||||||
putExtra(DIRECTORY, path)
|
putExtra(DIRECTORY, path)
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue