diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11500d8ac..856703a75 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,29 @@
Changelog
==========
+Version 2.17.2 *(2017-10-29)*
+----------------------------
+
+ * Couple more minor fixes
+
+Version 2.17.1 *(2017-10-29)*
+----------------------------
+
+ * Show "Set As" and "Edit" menu buttons at videos and gifs too
+ * Couple other smaller issues fixed
+
+Version 2.17.0 *(2017-10-28)*
+----------------------------
+
+ * Added a toggle for keeping last-modified field at file copy/move/rename
+ * Improved GIF animation speed
+ * Implemented fileprovider support to third party intents
+ * Make rotation by "Device rotation" less sensitive
+ * Automatically append "_1" to filename after saving through the Editor
+ * Added support for Adaptive icons for Android 8 (by fiepi)
+ * Added Dutch translation (by ltGuillaume)
+ * Many other smaller improvements
+
Version 2.16.1 *(2017-10-24)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index f63fcf375..79f122486 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -3,15 +3,15 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
- compileSdkVersion 25
- buildToolsVersion "25.0.3"
+ compileSdkVersion 26
+ buildToolsVersion "26.0.2"
defaultConfig {
applicationId "com.simplemobiletools.gallery"
minSdkVersion 16
- targetSdkVersion 23
- versionCode 137
- versionName "2.16.1"
+ targetSdkVersion 26
+ versionCode 140
+ versionName "2.17.2"
}
signingConfigs {
@@ -37,13 +37,13 @@ android {
}
dependencies {
- compile 'com.simplemobiletools:commons:2.31.11'
+ compile 'com.simplemobiletools:commons:2.34.2'
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'
compile 'com.google.code.gson:gson:2.8.0'
- compile 'com.github.chrisbanes:PhotoView:2.1.2'
compile 'it.sephiroth.android.exif:library:1.0.1'
+ compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.8'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fb8ba91aa..ff7ff3399 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -83,16 +83,16 @@
android:label="@string/third_party_licences"
android:parentActivityName="com.simplemobiletools.commons.activities.AboutActivity"/>
-
-
+
+
@@ -118,7 +108,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
Intent(this, ViewPagerActivity::class.java).apply {
putExtra(IS_VIEW_INTENT, true)
putExtra(IS_FROM_GALLERY, mIsFromGallery)
- putExtra(MEDIUM, path)
+ putExtra(PATH, path)
startActivity(this)
}
}
@@ -127,7 +117,8 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
menuInflater.inflate(R.menu.photo_video_menu, menu)
menu.findItem(R.id.menu_set_as).isVisible = mMedium?.isImage() == true
- menu.findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true
+ menu.findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true && mUri?.scheme == "file"
+ menu.findItem(R.id.menu_properties).isVisible = mUri?.scheme == "file"
return true
}
@@ -137,15 +128,20 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
return true
when (item.itemId) {
- R.id.menu_set_as -> trySetAs(File(mMedium!!.path))
- R.id.menu_open_with -> openWith(File(mMedium!!.path))
- R.id.menu_share -> shareUri(mMedium!!, mUri)
- R.id.menu_edit -> openFileEditor(File(mMedium!!.path))
+ R.id.menu_set_as -> setAs(mUri!!)
+ R.id.menu_open_with -> openFile(mUri!!, true)
+ R.id.menu_share -> shareUri(mUri!!)
+ R.id.menu_edit -> openEditor(mUri!!)
+ R.id.menu_properties -> showProperties()
else -> return super.onOptionsItemSelected(item)
}
return true
}
+ private fun showProperties() {
+ PropertiesDialog(this, mUri!!.path)
+ }
+
override fun fragmentClicked() {
mIsFullScreen = !mIsFullScreen
if (mIsFullScreen) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt
index 7c0b7b60b..6e988b0e3 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt
@@ -50,6 +50,7 @@ class SettingsActivity : SimpleActivity() {
setupDeleteEmptyFolders()
setupAllowVideoGestures()
setupShowMediaCount()
+ setupKeepLastModified()
setupShowExtendedDetails()
setupManageExtendedDetails()
updateTextColors(settings_holder)
@@ -207,6 +208,14 @@ class SettingsActivity : SimpleActivity() {
}
}
+ private fun setupKeepLastModified() {
+ settings_keep_last_modified.isChecked = config.keepLastModified
+ settings_keep_last_modified_holder.setOnClickListener {
+ settings_keep_last_modified.toggle()
+ config.keepLastModified = settings_keep_last_modified.isChecked
+ }
+ }
+
private fun setupScreenRotation() {
settings_screen_rotation.text = getScreenRotationText()
settings_screen_rotation_holder.setOnClickListener {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt
index fa38734e3..7ca92e902 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/VideoActivity.kt
@@ -5,7 +5,7 @@ import android.os.Bundle
class VideoActivity : PhotoVideoActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
- PhotoVideoActivity.mIsVideo = true
+ mIsVideo = true
super.onCreate(savedInstanceState)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt
index e9af326b0..ae02f2a66 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt
@@ -26,7 +26,10 @@ import android.view.animation.DecelerateInterpolator
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.IS_FROM_GALLERY
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
+import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE
+import com.simplemobiletools.commons.helpers.REQUEST_SET_AS
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.MediaActivity.Companion.mMedia
import com.simplemobiletools.gallery.adapters.MyPagerAdapter
@@ -85,6 +88,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
private fun initViewPager() {
+ setupOrientationEventListener()
measureScreen()
val uri = intent.data
if (uri != null) {
@@ -100,7 +104,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
} else {
try {
- mPath = intent.getStringExtra(MEDIUM)
+ mPath = intent.getStringExtra(PATH)
mShowAll = config.showAll
} catch (e: Exception) {
showErrorToast(e)
@@ -140,7 +144,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
reloadViewPager()
scanPath(mPath) {}
- setupOrientationEventListener()
if (config.darkBackground)
view_pager.background = ColorDrawable(Color.BLACK)
@@ -176,8 +179,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
mOrientationEventListener = object : OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) {
override fun onOrientationChanged(orientation: Int) {
val currOrient = when (orientation) {
- in 45..134 -> ORIENT_LANDSCAPE_RIGHT
- in 225..314 -> ORIENT_LANDSCAPE_LEFT
+ in 75..134 -> ORIENT_LANDSCAPE_RIGHT
+ in 225..289 -> ORIENT_LANDSCAPE_LEFT
else -> ORIENT_PORTRAIT
}
@@ -230,8 +233,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
menu.apply {
findItem(R.id.menu_share_1).isVisible = !config.replaceShare
findItem(R.id.menu_share_2).isVisible = config.replaceShare
- findItem(R.id.menu_set_as).isVisible = currentMedium.isImage()
- findItem(R.id.menu_edit).isVisible = currentMedium.isImage()
findItem(R.id.menu_rotate).isVisible = currentMedium.isImage()
findItem(R.id.menu_save_as).isVisible = mRotationDegrees != 0f
findItem(R.id.menu_hide).isVisible = !currentMedium.name.startsWith('.')
@@ -246,18 +247,18 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
return true
when (item.itemId) {
- R.id.menu_set_as -> trySetAs(getCurrentFile())
+ R.id.menu_set_as -> setAs(Uri.fromFile(getCurrentFile()))
R.id.slideshow -> initSlideshow()
R.id.menu_copy_to -> copyMoveTo(true)
R.id.menu_move_to -> copyMoveTo(false)
- R.id.menu_open_with -> openWith(getCurrentFile())
+ R.id.menu_open_with -> openFile(Uri.fromFile(getCurrentFile()), true)
R.id.menu_hide -> toggleFileVisibility(true)
R.id.menu_unhide -> toggleFileVisibility(false)
R.id.menu_share_1 -> shareMedium(getCurrentMedium()!!)
R.id.menu_share_2 -> shareMedium(getCurrentMedium()!!)
R.id.menu_delete -> checkDeleteConfirmation()
R.id.menu_rename -> renameFile()
- R.id.menu_edit -> openFileEditor(getCurrentFile())
+ R.id.menu_edit -> openEditor(Uri.fromFile(getCurrentFile()))
R.id.menu_properties -> showProperties()
R.id.show_on_map -> showOnMap()
R.id.menu_rotate -> rotateImage()
@@ -327,10 +328,12 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
animator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener {
var oldDragPosition = 0
override fun onAnimationUpdate(animation: ValueAnimator) {
- val dragPosition = animation.animatedValue as Int
- val dragOffset = dragPosition - oldDragPosition
- oldDragPosition = dragPosition
- view_pager?.fakeDragBy(dragOffset * (if (forward) 1f else -1f))
+ if (view_pager?.isFakeDragging == true) {
+ val dragPosition = animation.animatedValue as Int
+ val dragOffset = dragPosition - oldDragPosition
+ oldDragPosition = dragPosition
+ view_pager.fakeDragBy(dragOffset * (if (forward) 1f else -1f))
+ }
}
})
@@ -446,7 +449,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun saveImageAs() {
val currPath = getCurrentPath()
- SaveAsDialog(this, currPath) {
+ SaveAsDialog(this, currPath, false) {
Thread({
toast(R.string.saving)
val selectedFile = File(it)
@@ -515,8 +518,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem)
private fun showProperties() {
- if (getCurrentMedium() != null)
+ if (getCurrentMedium() != null) {
PropertiesDialog(this, getCurrentPath(), false)
+ }
}
private fun showOnMap() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt
index 7f36dfd26..b2f585e07 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt
@@ -30,11 +30,9 @@ import java.util.*
class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList, val listener: DirOperationsListener?, val isPickIntent: Boolean,
val itemClick: (Directory) -> Unit) : RecyclerView.Adapter() {
- val config = activity.config
+ private val config = activity.config
var actMode: ActionMode? = null
var primaryColor = config.primaryColor
- var scrollVertically = !config.scrollHorizontally
- var showMediaCount = config.showMediaCount
private val multiSelector = MultiSelector()
private val isListViewType = config.viewTypeFolders == VIEW_TYPE_LIST
@@ -42,6 +40,10 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList()
private var textColor = config.textColor
private var pinnedFolders = config.pinnedFolders
+ private var scrollHorizontally = config.scrollHorizontally
+ private var showMediaCount = config.showMediaCount
+ private var animateGifs = config.animateGifs
+ private var cropThumbnails = config.cropThumbnails
fun toggleItemSelection(select: Boolean, pos: Int) {
if (select) {
@@ -353,7 +355,7 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList (Unit)) :
SwappingHolder(view, MultiSelector()) {
- fun bindView(directory: Directory, isPinned: Boolean, scrollVertically: Boolean, isListView: Boolean, textColor: Int, showMediaCount: Boolean): View {
+ fun bindView(directory: Directory, isPinned: Boolean, scrollHorizontally: Boolean, isListView: Boolean, textColor: Int, showMediaCount: Boolean,
+ animateGifs: Boolean, cropThumbnails: Boolean): View {
itemView.apply {
dir_name.text = directory.name
dir_path?.text = "${directory.path.substringBeforeLast("/")}/"
photo_cnt.text = directory.mediaCnt.toString()
- activity.loadImage(directory.tmb, dir_thumbnail, scrollVertically)
+ activity.loadImage(directory.tmb, dir_thumbnail, scrollHorizontally, animateGifs, cropThumbnails)
dir_pin.beVisibleIf(isPinned)
dir_sd_card.beVisibleIf(activity.isPathOnSD(directory.path))
photo_cnt.beVisibleIf(showMediaCount)
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 d1918aaad..46ff5a7cb 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt
@@ -1,6 +1,7 @@
package com.simplemobiletools.gallery.adapters
import android.graphics.PorterDuff
+import android.net.Uri
import android.os.Build
import android.support.v7.view.ActionMode
import android.support.v7.widget.RecyclerView
@@ -27,18 +28,21 @@ import java.util.*
class MediaAdapter(val activity: SimpleActivity, var media: MutableList, val listener: MediaOperationsListener?, val isPickIntent: Boolean,
val allowMultiplePicks: Boolean, val itemClick: (Medium) -> Unit) : RecyclerView.Adapter() {
- val multiSelector = MultiSelector()
- val config = activity.config
- val isListViewType = config.viewTypeFiles == VIEW_TYPE_LIST
- var skipConfirmationDialog = false
-
+ private val config = activity.config
var actMode: ActionMode? = null
- var itemViews = SparseArray()
- val selectedPositions = HashSet()
var primaryColor = config.primaryColor
- var textColor = config.textColor
- var displayFilenames = config.displayFileNames
- var scrollVertically = !config.scrollHorizontally
+
+ private val multiSelector = MultiSelector()
+ private val isListViewType = config.viewTypeFiles == VIEW_TYPE_LIST
+ private var skipConfirmationDialog = false
+
+ private var itemViews = SparseArray()
+ private val selectedPositions = HashSet()
+ private var scrollHorizontally = config.scrollHorizontally
+ private var animateGifs = config.animateGifs
+ private var cropThumbnails = config.cropThumbnails
+ private var textColor = config.textColor
+ private var displayFilenames = config.displayFileNames
fun toggleItemSelection(select: Boolean, pos: Int) {
if (select) {
@@ -86,6 +90,8 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
R.id.cab_copy_to -> copyMoveTo(true)
R.id.cab_move_to -> copyMoveTo(false)
R.id.cab_select_all -> selectAll()
+ R.id.cab_open_with -> activity.openFile(Uri.fromFile(getCurrentFile()), true)
+ R.id.cab_set_as -> activity.setAs(Uri.fromFile(getCurrentFile()))
R.id.cab_delete -> checkDeleteConfirmation()
else -> return false
}
@@ -100,8 +106,8 @@ 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_rename).isVisible = selectedPositions.size == 1
+ menu.findItem(R.id.cab_open_with).isVisible = selectedPositions.size == 1
menu.findItem(R.id.cab_confirm_selection).isVisible = isPickIntent && allowMultiplePicks && selectedPositions.size > 0
checkHideBtnVisibility(menu)
@@ -159,7 +165,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
}
private fun editFile() {
- activity.openFileEditor(getCurrentFile())
+ activity.openEditor(Uri.fromFile(getCurrentFile()))
actMode?.finish()
}
@@ -277,7 +283,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- itemViews.put(position, holder.bindView(media[position], displayFilenames, scrollVertically, isListViewType, textColor))
+ itemViews.put(position, holder.bindView(media[position], displayFilenames, scrollHorizontally, isListViewType, textColor, animateGifs, cropThumbnails))
toggleItemSelection(selectedPositions.contains(position), position)
holder.itemView.tag = holder
}
@@ -300,6 +306,21 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
notifyDataSetChanged()
}
+ fun updateAnimateGifs(animateGifs: Boolean) {
+ this.animateGifs = animateGifs
+ notifyDataSetChanged()
+ }
+
+ fun updateCropThumbnails(cropThumbnails: Boolean) {
+ this.cropThumbnails = cropThumbnails
+ notifyDataSetChanged()
+ }
+
+ fun updateScrollHorizontally(scrollHorizontally: Boolean) {
+ this.scrollHorizontally = scrollHorizontally
+ notifyDataSetChanged()
+ }
+
fun updateTextColor(textColor: Int) {
this.textColor = textColor
notifyDataSetChanged()
@@ -348,12 +369,13 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
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 {
+ fun bindView(medium: Medium, displayFilenames: Boolean, scrollHorizontally: Boolean, isListViewType: Boolean, textColor: Int,
+ animateGifs: Boolean, cropThumbnails: Boolean): View {
itemView.apply {
play_outline.visibility = if (medium.video) View.VISIBLE else View.GONE
photo_name.beVisibleIf(displayFilenames || isListViewType)
photo_name.text = medium.name
- activity.loadImage(medium.path, medium_thumbnail, scrollVertically)
+ activity.loadImage(medium.path, medium_thumbnail, scrollHorizontally, animateGifs, cropThumbnails)
if (isListViewType) {
photo_name.setTextColor(textColor)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MyPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MyPagerAdapter.kt
index b7e5640ad..b4be25e37 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MyPagerAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MyPagerAdapter.kt
@@ -23,10 +23,10 @@ class MyPagerAdapter(val activity: ViewPagerActivity, fm: FragmentManager, val m
bundle.putSerializable(MEDIUM, medium)
val fragment: ViewPagerFragment
- if (medium.video) {
- fragment = VideoFragment()
+ fragment = if (medium.video) {
+ VideoFragment()
} else {
- fragment = PhotoFragment()
+ PhotoFragment()
}
fragment.arguments = bundle
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt
index 503e0f741..f97e2fb99 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt
@@ -11,7 +11,7 @@ import com.simplemobiletools.gallery.activities.SimpleActivity
import kotlinx.android.synthetic.main.dialog_save_as.view.*
import java.io.File
-class SaveAsDialog(val activity: SimpleActivity, val path: String, val callback: (savePath: String) -> Unit) {
+class SaveAsDialog(val activity: SimpleActivity, val path: String, val appendFilename: Boolean, val callback: (savePath: String) -> Unit) {
init {
var realPath = File(path).parent.trimEnd('/')
@@ -28,6 +28,10 @@ class SaveAsDialog(val activity: SimpleActivity, val path: String, val callback:
save_as_extension.setText(extension)
}
+ if (appendFilename) {
+ name += "_1"
+ }
+
save_as_name.setText(name)
save_as_path.setOnClickListener {
FilePickerDialog(activity, realPath, false, false, true) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt
index 4fe4d6180..5bf08e18d 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt
@@ -2,16 +2,11 @@ package com.simplemobiletools.gallery.extensions
import android.app.Activity
import android.content.Intent
-import android.database.Cursor
import android.net.Uri
-import android.os.Build
import android.provider.MediaStore
import android.support.v7.app.AppCompatActivity
-import android.util.DisplayMetrics
-import android.view.KeyCharacterMap
-import android.view.KeyEvent
import android.view.View
-import android.view.ViewConfiguration
+import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
@@ -24,165 +19,42 @@ import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.gallery.BuildConfig
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
-import com.simplemobiletools.gallery.helpers.IS_FROM_GALLERY
import com.simplemobiletools.gallery.helpers.NOMEDIA
-import com.simplemobiletools.gallery.helpers.REQUEST_EDIT_IMAGE
-import com.simplemobiletools.gallery.helpers.REQUEST_SET_AS
import com.simplemobiletools.gallery.models.Directory
import com.simplemobiletools.gallery.models.Medium
import com.simplemobiletools.gallery.views.MySquareImageView
+import pl.droidsonroids.gif.GifDrawable
import java.io.File
import java.util.*
-fun Activity.shareUri(medium: Medium, uri: Uri) {
- val shareTitle = resources.getString(R.string.share_via)
- Intent().apply {
- action = Intent.ACTION_SEND
- putExtra(Intent.EXTRA_STREAM, uri)
- type = medium.getMimeType()
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- startActivity(Intent.createChooser(this, shareTitle))
- }
+fun Activity.shareUri(uri: Uri) {
+ shareUri(uri, BuildConfig.APPLICATION_ID)
+}
+
+fun Activity.shareUris(uris: ArrayList) {
+ shareUris(uris, BuildConfig.APPLICATION_ID)
}
fun Activity.shareMedium(medium: Medium) {
- val shareTitle = resources.getString(R.string.share_via)
val file = File(medium.path)
- val uri = Uri.fromFile(file)
-
- Intent().apply {
- action = Intent.ACTION_SEND
- putExtra(Intent.EXTRA_STREAM, uri)
- type = medium.getMimeType()
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- startActivity(Intent.createChooser(this, shareTitle))
- }
+ shareUri(Uri.fromFile(file))
}
fun Activity.shareMedia(media: List) {
- val shareTitle = resources.getString(R.string.share_via)
- val uris = media.map { Uri.fromFile(File(it.path)) } as ArrayList
-
- Intent().apply {
- action = Intent.ACTION_SEND_MULTIPLE
- type = uris.getMimeType()
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
- startActivity(Intent.createChooser(this, shareTitle))
- }
+ val uris = media.map { getFilePublicUri(File(it.path), BuildConfig.APPLICATION_ID) } as ArrayList
+ shareUris(uris)
}
-fun Activity.trySetAs(file: File) {
- try {
- var uri = Uri.fromFile(file)
- if (!setAs(uri, file)) {
- uri = getFileContentUri(file)
- setAs(uri, file, false)
- }
- } catch (e: Exception) {
- toast(R.string.unknown_error_occurred)
- }
+fun Activity.setAs(uri: Uri) {
+ setAs(uri, BuildConfig.APPLICATION_ID)
}
-fun Activity.setAs(uri: Uri, file: File, showToast: Boolean = true): Boolean {
- var success = false
- Intent().apply {
- action = Intent.ACTION_ATTACH_DATA
- setDataAndType(uri, file.getMimeType())
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- val chooser = Intent.createChooser(this, getString(R.string.set_as))
-
- success = if (resolveActivity(packageManager) != null) {
- startActivityForResult(chooser, REQUEST_SET_AS)
- true
- } else {
- if (showToast) {
- toast(R.string.no_capable_app_found)
- }
- false
- }
- }
-
- return success
+fun Activity.openFile(uri: Uri, forceChooser: Boolean) {
+ openFile(uri, forceChooser, BuildConfig.APPLICATION_ID)
}
-fun Activity.getFileContentUri(file: File): Uri? {
- val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
- val projection = arrayOf(MediaStore.Images.Media._ID)
- val selection = "${MediaStore.Images.Media.DATA} = ?"
- val selectionArgs = arrayOf(file.absolutePath)
-
- var cursor: Cursor? = null
- try {
- cursor = contentResolver.query(uri, projection, selection, selectionArgs, null)
- if (cursor?.moveToFirst() == true) {
- val id = cursor.getIntValue(MediaStore.Images.Media._ID)
- return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "$id")
- }
- } finally {
- cursor?.close()
- }
- return null
-}
-
-fun Activity.openWith(file: File, forceChooser: Boolean = true) {
- val uri = Uri.fromFile(file)
- Intent().apply {
- action = Intent.ACTION_VIEW
- setDataAndType(uri, file.getMimeType())
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- putExtra(IS_FROM_GALLERY, true)
-
- if (resolveActivity(packageManager) != null) {
- val chooser = Intent.createChooser(this, getString(R.string.open_with))
- startActivity(if (forceChooser) chooser else this)
- } else {
- toast(R.string.no_app_found)
- }
- }
-}
-
-fun Activity.openFileEditor(file: File) {
- openEditor(Uri.fromFile(file))
-}
-
-fun Activity.openEditor(uri: Uri, forceChooser: Boolean = false) {
- Intent().apply {
- action = Intent.ACTION_EDIT
- setDataAndType(uri, "image/*")
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
-
- if (resolveActivity(packageManager) != null) {
- val chooser = Intent.createChooser(this, getString(R.string.edit_image_with))
- startActivityForResult(if (forceChooser) chooser else this, REQUEST_EDIT_IMAGE)
- } else {
- toast(R.string.no_editor_found)
- }
- }
-}
-
-fun Activity.hasNavBar(): Boolean {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- val display = windowManager.defaultDisplay
-
- val realDisplayMetrics = DisplayMetrics()
- display.getRealMetrics(realDisplayMetrics)
-
- val realHeight = realDisplayMetrics.heightPixels
- val realWidth = realDisplayMetrics.widthPixels
-
- val displayMetrics = DisplayMetrics()
- display.getMetrics(displayMetrics)
-
- val displayHeight = displayMetrics.heightPixels
- val displayWidth = displayMetrics.widthPixels
-
- realWidth - displayWidth > 0 || realHeight - displayHeight > 0
- } else {
- val hasMenuKey = ViewConfiguration.get(applicationContext).hasPermanentMenuKey()
- val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)
- !hasMenuKey && !hasBackKey
- }
+fun Activity.openEditor(uri: Uri) {
+ openEditor(uri, BuildConfig.APPLICATION_ID)
}
fun Activity.launchCamera() {
@@ -196,7 +68,7 @@ fun Activity.launchCamera() {
fun SimpleActivity.launchAbout() {
startAboutActivity(R.string.app_name, LICENSE_KOTLIN or LICENSE_GLIDE or LICENSE_CROPPER or LICENSE_MULTISELECT or LICENSE_RTL
- or LICENSE_PHOTOVIEW or LICENSE_SUBSAMPLING or LICENSE_PATTERN, BuildConfig.VERSION_NAME)
+ or LICENSE_SUBSAMPLING or LICENSE_PATTERN or LICENSE_REPRINT or LICENSE_GIF_DRAWABLE, BuildConfig.VERSION_NAME)
}
fun AppCompatActivity.showSystemUI() {
@@ -265,24 +137,28 @@ fun SimpleActivity.toggleFileVisibility(oldFile: File, hide: Boolean, callback:
}
}
-fun Activity.loadImage(path: String, target: MySquareImageView, verticalScroll: Boolean) {
- target.isVerticalScrolling = verticalScroll
+fun Activity.loadImage(path: String, target: MySquareImageView, horizontalScroll: Boolean, animateGifs: Boolean, cropThumbnails: Boolean) {
+ target.isHorizontalScrolling = horizontalScroll
if (path.isImageFast() || path.isVideoFast()) {
if (path.isPng()) {
- loadPng(path, target)
+ loadPng(path, target, cropThumbnails)
} else {
- loadJpg(path, target)
+ loadJpg(path, target, cropThumbnails)
}
} else if (path.isGif()) {
- if (config.animateGifs) {
- loadAnimatedGif(path, target)
+ val gifDrawable = GifDrawable(path)
+ target.setImageDrawable(gifDrawable)
+ if (animateGifs) {
+ gifDrawable.start()
} else {
- loadStaticGif(path, target)
+ gifDrawable.stop()
}
+
+ target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
}
}
-fun Activity.loadPng(path: String, target: MySquareImageView) {
+fun Activity.loadPng(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
val options = RequestOptions()
.signature(path.getFileSignature())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
@@ -292,11 +168,11 @@ fun Activity.loadPng(path: String, target: MySquareImageView) {
.asBitmap()
.load(path)
- if (config.cropThumbnails) options.centerCrop() else options.fitCenter()
+ if (cropThumbnails) options.centerCrop() else options.fitCenter()
builder.apply(options).into(target)
}
-fun Activity.loadJpg(path: String, target: MySquareImageView) {
+fun Activity.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
val options = RequestOptions()
.signature(path.getFileSignature())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
@@ -304,36 +180,10 @@ fun Activity.loadJpg(path: String, target: MySquareImageView) {
val builder = Glide.with(applicationContext)
.load(path)
- if (config.cropThumbnails) options.centerCrop() else options.fitCenter()
+ if (cropThumbnails) options.centerCrop() else options.fitCenter()
builder.apply(options).transition(DrawableTransitionOptions.withCrossFade()).into(target)
}
-fun Activity.loadAnimatedGif(path: String, target: MySquareImageView) {
- val options = RequestOptions()
- .signature(path.getFileSignature())
- .diskCacheStrategy(DiskCacheStrategy.NONE)
-
- val builder = Glide.with(applicationContext)
- .asGif()
- .load(path)
-
- if (config.cropThumbnails) options.centerCrop() else options.fitCenter()
- builder.apply(options).transition(DrawableTransitionOptions.withCrossFade()).into(target)
-}
-
-fun Activity.loadStaticGif(path: String, target: MySquareImageView) {
- val options = RequestOptions()
- .signature(path.getFileSignature())
- .diskCacheStrategy(DiskCacheStrategy.DATA)
-
- val builder = Glide.with(applicationContext)
- .asBitmap()
- .load(path)
-
- if (config.cropThumbnails) options.centerCrop() else options.fitCenter()
- builder.apply(options).into(target)
-}
-
fun Activity.getCachedDirectories(): ArrayList {
val token = object : TypeToken>() {}.type
return Gson().fromJson>(config.directories, token) ?: ArrayList(1)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
index cdda71ab7..d4b01c633 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/context.kt
@@ -5,12 +5,17 @@ import android.content.Intent
import android.content.res.Configuration
import android.graphics.Point
import android.media.AudioManager
+import android.net.Uri
import android.os.Build
import android.view.WindowManager
+import com.simplemobiletools.commons.extensions.getFilePublicUri
+import com.simplemobiletools.commons.extensions.getMimeTypeFromPath
import com.simplemobiletools.commons.extensions.humanizePath
+import com.simplemobiletools.gallery.BuildConfig
import com.simplemobiletools.gallery.activities.SettingsActivity
import com.simplemobiletools.gallery.helpers.Config
import com.simplemobiletools.gallery.models.Directory
+import java.io.File
val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt
index b865282d3..5852698d2 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt
@@ -13,12 +13,10 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.bumptech.glide.Glide
-import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
-import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
@@ -26,6 +24,7 @@ import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.R
+import com.simplemobiletools.gallery.activities.PhotoActivity
import com.simplemobiletools.gallery.activities.ViewPagerActivity
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.helpers.GlideRotateTransformation
@@ -33,15 +32,16 @@ import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
import it.sephiroth.android.library.exif2.ExifInterface
import kotlinx.android.synthetic.main.pager_photo_item.view.*
+import pl.droidsonroids.gif.GifDrawable
import java.io.File
import java.io.FileOutputStream
-import java.io.IOException
class PhotoFragment : ViewPagerFragment() {
private var isFragmentVisible = false
private var wasInit = false
private var storedShowExtendedDetails = false
private var storedExtendedDetails = 0
+ private var gifDrawable: GifDrawable? = null
lateinit var view: ViewGroup
lateinit var medium: Medium
@@ -49,11 +49,14 @@ class PhotoFragment : ViewPagerFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
view = inflater.inflate(R.layout.pager_photo_item, container, false) as ViewGroup
- medium = arguments.getSerializable(MEDIUM) as Medium
+ if (!isFragmentVisible && activity is PhotoActivity) {
+ isFragmentVisible = true
+ }
+ medium = arguments.getSerializable(MEDIUM) as Medium
if (medium.path.startsWith("content://")) {
val originalPath = medium.path
- medium.path = context.getRealPathFromURI(Uri.parse(medium.path)) ?: ""
+ medium.path = context.getRealPathFromURI(Uri.parse(originalPath)) ?: medium.path
if (medium.path.isEmpty()) {
var out: FileOutputStream? = null
@@ -63,7 +66,6 @@ class PhotoFragment : ViewPagerFragment() {
exif.readExif(inputStream, ExifInterface.Options.OPTION_ALL)
val tag = exif.getTag(ExifInterface.TAG_ORIENTATION)
val orientation = tag?.getValueAsInt(-1) ?: -1
-
inputStream = context.contentResolver.openInputStream(Uri.parse(originalPath))
val original = BitmapFactory.decodeStream(inputStream)
val rotated = rotateViaMatrix(original, orientation)
@@ -78,26 +80,13 @@ class PhotoFragment : ViewPagerFragment() {
activity.toast(R.string.unknown_error_occurred)
return view
} finally {
- try {
- out?.close()
- } catch (e: IOException) {
- }
+ out?.close()
}
}
}
- view.subsampling_view.setOnClickListener({ photoClicked() })
- view.photo_view.apply {
- maximumScale = 8f
- mediumScale = 3f
- setOnOutsidePhotoTapListener {
- photoClicked()
- }
-
- setOnPhotoTapListener { view, x, y ->
- photoClicked()
- }
- }
+ view.subsampling_view.setOnClickListener { photoClicked() }
+ view.gif_view.setOnClickListener { photoClicked() }
loadImage()
checkExtendedDetails()
@@ -123,14 +112,30 @@ class PhotoFragment : ViewPagerFragment() {
super.setMenuVisibility(menuVisible)
isFragmentVisible = menuVisible
if (wasInit) {
- if (menuVisible) {
- addZoomableView()
+ if (medium.isGif()) {
+ gifFragmentVisibilityChanged(menuVisible)
} else {
- view.subsampling_view.apply {
- recycle()
- beGone()
- background = ColorDrawable(Color.TRANSPARENT)
- }
+ photoFragmentVisibilityChanged(menuVisible)
+ }
+ }
+ }
+
+ private fun gifFragmentVisibilityChanged(isVisible: Boolean) {
+ if (isVisible) {
+ gifDrawable?.start()
+ } else {
+ gifDrawable?.stop()
+ }
+ }
+
+ private fun photoFragmentVisibilityChanged(isVisible: Boolean) {
+ if (isVisible) {
+ addZoomableView()
+ } else {
+ view.subsampling_view.apply {
+ recycle()
+ beGone()
+ background = ColorDrawable(Color.TRANSPARENT)
}
}
}
@@ -155,16 +160,17 @@ class PhotoFragment : ViewPagerFragment() {
private fun loadImage() {
if (medium.isGif()) {
- val options = RequestOptions()
- .priority(if (isFragmentVisible) Priority.IMMEDIATE else Priority.LOW)
- .diskCacheStrategy(DiskCacheStrategy.DATA)
+ gifDrawable = if (medium.path.startsWith("content://") || medium.path.startsWith("file://")) {
+ GifDrawable(context.contentResolver, Uri.parse(medium.path))
+ } else {
+ GifDrawable(medium.path)
+ }
- Glide.with(this)
- .asGif()
- .load(medium.path)
- .transition(DrawableTransitionOptions.withCrossFade())
- .apply(options)
- .into(view.photo_view)
+ if (!isFragmentVisible) {
+ gifDrawable!!.stop()
+ }
+
+ view.gif_view.setImageDrawable(gifDrawable)
} else {
loadBitmap()
}
@@ -193,7 +199,7 @@ class PhotoFragment : ViewPagerFragment() {
addZoomableView()
return false
}
- }).into(view.photo_view)
+ }).into(view.gif_view)
} else {
val options = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
@@ -204,7 +210,7 @@ class PhotoFragment : ViewPagerFragment() {
.load(medium.path)
.thumbnail(0.2f)
.apply(options)
- .into(view.photo_view)
+ .into(view.gif_view)
}
}
@@ -292,7 +298,7 @@ class PhotoFragment : ViewPagerFragment() {
super.onDestroyView()
context.isKitkatPlus()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && !activity.isDestroyed) {
- Glide.with(context).clear(view.photo_view)
+ Glide.with(context).clear(view.gif_view)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt
index e271e0b90..8985628c1 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt
@@ -15,6 +15,7 @@ import android.widget.SeekBar
import android.widget.TextView
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.R
+import com.simplemobiletools.gallery.activities.VideoActivity
import com.simplemobiletools.gallery.activities.ViewPagerActivity
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.helpers.MEDIUM
@@ -64,6 +65,11 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
mTimeHolder = mView.video_time_holder
medium = arguments.getSerializable(MEDIUM) as Medium
+ // setMenuVisibility is not called at VideoActivity (third party intent)
+ if (!mIsFragmentVisible && activity is VideoActivity) {
+ mIsFragmentVisible = true
+ }
+
setupPlayer()
if (savedInstanceState != null) {
mCurrTime = savedInstanceState.getInt(PROGRESS)
@@ -90,7 +96,6 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
override fun onPause() {
super.onPause()
pauseVideo()
- mIsFragmentVisible = false
mStoredShowExtendedDetails = context.config.showExtendedDetails
mStoredExtendedDetails = context.config.extendedDetails
}
@@ -285,7 +290,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
var right = res.getDimension(R.dimen.timer_padding).toInt()
var bottom = 0
- if (activity.hasNavBar()) {
+ if (hasNavBar()) {
if (res.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
bottom += height
} else {
@@ -303,6 +308,30 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
mTimeHolder.beInvisible()
}
+ private fun hasNavBar(): Boolean {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ val display = context.windowManager.defaultDisplay
+
+ val realDisplayMetrics = DisplayMetrics()
+ display.getRealMetrics(realDisplayMetrics)
+
+ val realHeight = realDisplayMetrics.heightPixels
+ val realWidth = realDisplayMetrics.widthPixels
+
+ val displayMetrics = DisplayMetrics()
+ display.getMetrics(displayMetrics)
+
+ val displayHeight = displayMetrics.heightPixels
+ val displayWidth = displayMetrics.widthPixels
+
+ realWidth - displayWidth > 0 || realHeight - displayHeight > 0
+ } else {
+ val hasMenuKey = ViewConfiguration.get(context).hasPermanentMenuKey()
+ val hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK)
+ !hasMenuKey && !hasBackKey
+ }
+ }
+
private fun setupTimeHolder() {
mSeekBar!!.max = mDuration
mView.video_duration.text = mDuration.getFormattedDuration()
@@ -435,6 +464,10 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
}
private fun videoCompleted() {
+ if (!isAdded) {
+ return
+ }
+
if (listener?.videoEnded() == false && context.config.loopVideos) {
playVideo()
} else {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/ViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/ViewPagerFragment.kt
index 31a2888c4..20a73b886 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/ViewPagerFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/ViewPagerFragment.kt
@@ -20,6 +20,10 @@ abstract class ViewPagerFragment : Fragment() {
fun getMediumExtendedDetails(medium: Medium): String {
val file = File(medium.path)
+ if (!file.exists()) {
+ return ""
+ }
+
val path = "${file.parent.trimEnd('/')}/"
val exif = android.media.ExifInterface(medium.path)
val details = StringBuilder()
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 663cf7706..23b5a2673 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/Constants.kt
@@ -59,18 +59,15 @@ val NOMEDIA = ".nomedia"
val DIRECTORY = "directory"
val MEDIUM = "medium"
+val PATH = "path"
val GET_IMAGE_INTENT = "get_image_intent"
val GET_VIDEO_INTENT = "get_video_intent"
val GET_ANY_INTENT = "get_any_intent"
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
-
// rotations
val ROTATE_BY_SYSTEM_SETTING = 0
val ROTATE_BY_DEVICE_ROTATION = 1
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/views/MySquareImageView.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/views/MySquareImageView.kt
index f254d4183..39a2f74be 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/views/MySquareImageView.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/views/MySquareImageView.kt
@@ -5,7 +5,7 @@ import android.util.AttributeSet
import android.widget.ImageView
class MySquareImageView : ImageView {
- var isVerticalScrolling = true
+ var isHorizontalScrolling = false
constructor(context: Context) : super(context)
@@ -14,7 +14,7 @@ class MySquareImageView : ImageView {
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- val spec = if (isVerticalScrolling) widthMeasureSpec else heightMeasureSpec
+ val spec = if (isHorizontalScrolling) heightMeasureSpec else widthMeasureSpec
super.onMeasure(spec, spec)
}
}
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 192ef7050..0090560db 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -348,6 +348,26 @@
+
+
+
+
+
+
-
+ android:layout_height="match_parent"
+ android:scaleType="fitCenter"/>
+
+
+
-
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..f4091292b
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-nodpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-nodpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..24b7f2986
Binary files /dev/null and b/app/src/main/res/mipmap-nodpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index b2b1b6986..209dc0b10 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -4,8 +4,6 @@
Gallery
Edit
Open camera
- Open with
- No valid app found
(hidden)
Pin folder
Unpin folder
@@ -22,7 +20,6 @@
Change cover image
Select photo
Use default
- Set as
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 48f819337..d835945cd 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -4,8 +4,6 @@
Galerie
Upravit
Spustit fotoaparát
- Otevřít pomocí
- Nebyla nalezena žádná vhodná aplikace
(skryté)
Připnout složku
Odepnout složku
@@ -22,7 +20,6 @@
Change cover image
Select photo
Use default
- Nastavit jako
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index da95fadc3..f216c800e 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -4,8 +4,6 @@
Galerie
Bearbeiten
Kamera öffnen
- Öffnen mit
- Keine passende App gefunden
(versteckt)
Ordner anheften
Ordner loslösen
@@ -14,7 +12,7 @@
Ansicht: Als Ordner
Ordner wählen
Auf Karte zeigen
- Unbekannter Ort
+ Unbekannter Pfad
Keine Karten-App gefunden
Keine Kamera-App gefunden
Kacheln verkleinern
@@ -22,10 +20,9 @@
Coverbild ändern
Auswählen
Standard
- Festlegen als
Lautstärke
Helligkeit
- Nicht erneut fragen (in dieser Session)
+ Nicht erneut fragen (in dieser Sitzung)
Filter
@@ -69,7 +66,7 @@
Bildbearbeitung fehlgeschlagen
Bild bearbeiten mit
Keine Bildeditor-App gefunden
- Unbekannter Dateiort
+ Unbekannter Dateipfad
Konnte Quelldatei nicht überschreiben
Nach links drehen
Nach rechts drehen
@@ -125,7 +122,7 @@
Systemleisten ausblenden im Vollbild
Nach Löschen leere Ordner löschen
Gesten für Videolautstärke/Helligkeit
- Show folder media count on the main view
+ Medienanzahl bei Ordnern anzeigen
Teilen/Drehen im Vollbild-Menü vertauschen
Eigenschaften anzeigen im Vollbild
Eigenschaften auswählen
@@ -134,11 +131,11 @@
Eine schlichte Galerie zum Betrachten von Bildern und Videos ohne Werbung.
- Ein schlichtes Tool zum Betrachten von Bildern und Videos. Die Medien können nach Datum, Größe, Name sowie auf- oder absteigend sortiert angezeigt werden, in Bilder kann hineingezoomt werden. Die Vorschau-Kacheln werden in mehreren Spalten abhängig von der Displaygröße angezeigt, die Spaltenanzahl ist mit Zweifingergesten änderbar. Die Medien können umbenannt, geteilt, gelöscht, kopiert, verschoben werden. Bilder können zugeschnitten, gedreht oder als Hintergrund festgelegt werden, direkt aus der App heraus.
+ Eine schlichte App zum Betrachten von Bildern und Videos. Die Medien können nach Datum, Größe, Name sowie auf- oder absteigend sortiert werden, in Bilder kann auch hineingezoomt werden. Die Vorschau-Kacheln werden in mehreren Spalten abhängig von der Displaygröße angezeigt, die Spaltenanzahl ist mit Zweifingergesten änderbar. Die Medien können umbenannt, geteilt, gelöscht, kopiert und verschoben werden. Bilder können direkt aus der App heraus zugeschnitten, gedreht oder als Hintergrund festgelegt werden.
- Die Galerie bietet auch für Drittparteien einige Funktionen an: zum Vorschauen von Bildern / Videos, zum Hinzufügen von Anhängen bei eMail-Clients, etc. Sie ist perfekt für den täglichen Gebrauch.
+ Diese Galerie bietet auch für Drittanbieter einige Funktionen an: zum Vorschauen von Bildern / Videos, zum Hinzufügen von Anhängen bei Email-Apps, etc. Sie ist perfekt für den täglichen Gebrauch.
- Beinhaltet keine Werbung oder unnötige Berechtigungen. Sie ist komplett Open Source, verwendete Farben sind anpassbar.
+ Beinhaltet keine Werbung oder unnötigen Berechtigungen. Sie ist komplett Open Source, verwendete Farben sind anpassbar.
Diese App ist nur eine aus einer größeren Serie von schlichten Apps. Der Rest davon findet sich auf http://www.simplemobiletools.com
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 8f9bb7813..037aa80de 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -4,8 +4,6 @@
Galería
Editar
Abrir cámara
- Abrir con…
- No se encontró una aplicación válida
(oculto)
Fijar carpeta
No fijar carpeta
@@ -22,7 +20,6 @@
Cambiar imagen de portada
Seleccionar imagen
Uso por defecto
- Establecer como
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 57e76daec..f6ccd7a8d 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -4,8 +4,6 @@
Galleria
Muokkaa
Avaa kamera
- Avaa
- Sovelluksia ei löydetty
(piilotettu)
Kiinnitä kansio
Poista kiinnitys
@@ -22,7 +20,6 @@
Vaihda kansikuva
Valitse kuva
Käytä oletuksia
- Aseta
Äänenvoimakkuus
Kirkkaus
Do not ask again in this session
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index efa023339..edf3e5d03 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -4,8 +4,6 @@
Galerie
Édition
Ouvrir appareil photo
- Ouvrir avec
- Aucune application valide trouvée
(caché)
Épingler le dossier
Désépingler le dossier
@@ -22,7 +20,6 @@
Changer l\'image de couverture
Sélectionner une photo
Utiliser par défaut
- Définir comme
Volume
Luminosité
Ne pas redemander pour cette session
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 2eb9d22d0..89abc717c 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -4,8 +4,6 @@
Gallery
Edit
Open camera
- Open with
- No valid app found
(hidden)
Pin folder
Unpin folder
@@ -22,7 +20,6 @@
Change cover image
Select photo
Use default
- Set as
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 66c2fd1f3..3e0b0643f 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -4,8 +4,6 @@
Galleria
Modifica
Apri fotocamera
- Apri con
- Nessun app valida trovata
(nascosta)
Blocca cartella
Sblocca cartella
@@ -22,10 +20,9 @@
Cambia immagine copertina
Seleziona foto
Usa predefinita
- Imposta come
Volume
Luminosità
- Do not ask again in this session
+ Non chiedere nuovamente in questa sessione
Filtra i media
@@ -125,10 +122,10 @@
Nascondi UI di sistema con media a schermo intero
Elimina cartelle vuote dopo averne eliminato il contenuto
Gestisci il volume e la luminosità dei video con gesti verticali
- Show folder media count on the main view
+ Mostra numero elementi nella cartella
Sostituisci Condividi con Ruota a schermo intero
- Show extended details over fullscreen media
- Manage extended details
+ Mostra informazioni estese su media a schermo intero
+ Gestisci le informazioni estese
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index dc2413462..2f9086eb3 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -4,8 +4,6 @@
ギャラリー
編集
カメラを開く
- 別のアプリで開く
- 有効なアプリが見つかりません
(非表示)
フォルダーをピン留めする
フォルダーのピン留めを外す
@@ -22,7 +20,6 @@
カバー画像を変更
写真を選択
デフォルトに戻す
- 他で使う
音量
明るさ
Do not ask again in this session
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 91e0ca7bf..a7d28d108 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -4,8 +4,6 @@
Gallerij
Bewerken
Camera
- Openen met
- Geen app gevonden om dit bestand mee te openen
(verborgen)
Map vastzetten
Map losmaken
@@ -22,7 +20,6 @@
Afbeelding voor omslag veranderen
Foto selecteren
Standaard gebruiken
- Instellen als
Volume
Helderheid
Onthouden voor deze sessie
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index c77a32cad..d153c70ba 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -4,8 +4,6 @@
Simple Gallery
Edytuj
Uruchom aplikację aparatu
- Otwórz w
- Nie znaleziono danych aplikacji
(ukryty)
Przypnij folder
Wypakuj folder
@@ -22,7 +20,6 @@
Zmień okładkę
Wybierz obraz
Użyj domyślnej
- Ustaw jako
Głośność
Jasność
Nie pytaj więcej w tej sesji
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 8c391f4b7..c9e953185 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -4,8 +4,6 @@
Galeria
Editar
Abrir câmera
- Abrir com
- Nenhum aplicativo encontrado
(oculto)
Fixar pasta
Desfixar pasta
@@ -22,7 +20,6 @@
Trocar imagem de capa
Selecionar foto
Usar padrão
- Definir como
Volume
Brilho
Não perguntar novamente por enquanto
@@ -125,7 +122,7 @@
Esconder interface do sistema automaticamente quando em tela cheia
Apagar pastas vazias após deleter seu conteúdo
Permitir controle do volume e brilho com gestos na vertical
- Show folder media count on the main view
+ Mostrar quantidade de arquivos das pastas
Substituir botão "Compartilhar" por "Rotação de tela" quando em tela cheia
Exibir detalhes extendidos quando em tela cheia
Gerenciar detalhes extendidos
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index bdbf21597..6242d94c4 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -4,8 +4,6 @@
Galeria
Editar
Abrir câmara
- Abrir com
- Nenhuma aplicação encontrada
(oculta)
Fixar pasta
Desafixar pasta
@@ -22,10 +20,9 @@
Alterar imagem de capa
Selecionar foto
Predefinição
- Definir como
Volume
Brilho
- Do not ask again in this session
+ Não perguntar de novo para esta sessão
Filtrar multimédia
@@ -127,8 +124,8 @@
Permitir controlo do volume e brilho dos vídeos através de gestos verticais
Show folder media count on the main view
Substituir a opção Partilhar pela opção Rodar se em ecrã completo
- Show extended details over fullscreen media
- Manage extended details
+ Mostrar detalhes se em ecrã completo
+ Gerir detalhes exibidos
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index d62e8711d..f480ce936 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -4,8 +4,6 @@
Галерея
Редактировать
Открыть камеру
- Открыть в
- Приложение не найдено
(Скрытый)
Закрепить папку
Открепить папку
@@ -17,15 +15,14 @@
Место съёмки не указано
Не найдено приложений с картами
Не найдено приложения камеры
- Добавить 1 столбец
- Убрать 1 столбец
+ Добавить столбец
+ Убрать столбец
Изменить обложку
Выбрать изображение
Использовать по умолчанию
- Установить как…
Громкость
Яркость
- Do not ask again in this session
+ Не спрашивать снова (до следующего запуска)
Фильтр медиа
@@ -87,8 +84,8 @@
Приложение не найдено
Установка обоев…
Обои успешно установлены
- Формат изображения
- Пейзажное соотношение сторон
+ Портрет
+ Ландшафт
Слайдшоу
@@ -125,10 +122,10 @@
Автоматически скрывать системный интерфейс в полноэкранном режиме
Удалять пустые папки после удаления их содержимого
Управлять громкостью и яркостью видео с помощью вертикальных жестов
- Show folder media count on the main view
+ Показывать количество файлов в папках
Заменить \'Поделиться\' на \'Повернуть\' в меню полноэкранного режима
- Show extended details over fullscreen media
- Manage extended details
+ Показывать детали файла
+ Выбрать детали файла
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f562dff8d..e4af5b81d 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -4,8 +4,6 @@
Galéria
Upraviť
Otvoriť fotoaparát
- Otvoriť pomocou
- Nenašla sa žiadna vhodná aplikácia
(skryté)
Pripnúť priečinok
Odopnúť priečinok
@@ -22,7 +20,6 @@
Zmeniť obal albumu
Zvoliť foto
Použiť predvolený
- Nastaviť ako
Hlasitosť
Jas
Nepýtať sa už v tomto spustení
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 106063a54..703575d53 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -4,8 +4,6 @@
Galleri
Redigera
Starta kameran
- Öppna med
- Hittade ingen giltig app
(dold)
Fäst mappen
Släpp mappen
@@ -22,7 +20,6 @@
Byt omslagsbild
Välj foto
Använd standard
- Ange som
Volym
Ljusstyrka
Do not ask again in this session
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index a9ac2f748..67ea088b9 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -4,8 +4,6 @@
Galeri
Düzenle
Kamerayı aç
- Bununla aç
- Geçerli bir uygulama bulunamadı
(gizli)
Pin klasör
Klasörü çöz
@@ -22,7 +20,6 @@
Change cover image
Select photo
Use default
- Set as
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 90412da97..74cfdfe11 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -4,8 +4,6 @@
简约图库
编辑
打开相机
- 打开方式
- 未找到可用应用
(隐藏)
锁定目录
解除锁定目录
@@ -22,7 +20,6 @@
更改封面图片
选择图片
使用默认
- 设置为
音量
亮度
不再提醒
@@ -30,7 +27,7 @@
要显示的媒体文件
图片
- 适配
+ 视频
GIFs
所选的过滤器没有找到媒体文件。
更改过滤器
@@ -44,7 +41,7 @@
是否排除父目录?
此目录及其子目录中的媒体将不会在“简约图库”中显示,但是其它应用可以访问。如果您想对其它应用隐藏,请使用隐藏功能。
移除全部
- 是否删除排除列表中的所有文件夹?此操作不会删除文件夹。
+ 是否删除排除列表中的所有项目?此操作不会删除文件夹本身。
包含目录
@@ -116,7 +113,7 @@
GIF 缩略图
浏览时最大亮度
裁剪缩略图
- 全屏时方向
+ 全屏方向
系统设置
设备方向
根据长宽比
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index bc5042450..ff138ebbd 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -4,8 +4,6 @@
簡易相簿
編輯
開啟相機
- 以其他應用程式開啟
- 找不到應用程式
(隱藏)
釘選資料夾
取消釘選資料夾
@@ -22,7 +20,6 @@
更換封面圖片
選擇相片
使用預設
- 設為
音量
亮度
Do not ask again in this session
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 8cb25a2bb..ee1e5614a 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -7,4 +7,6 @@
@color/default_dark_theme_text_color
@color/default_dark_theme_background_color
+
+ @color/color_primary
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index de109b996..a8c998266 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -2,6 +2,7 @@
+ Added an option to keep last-modified field at file copy/move/rename
Added an option to hide folder media count on the main screen
Added an option to show customizable extended details over fullscreen media
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b2b1b6986..209dc0b10 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -4,8 +4,6 @@
Gallery
Edit
Open camera
- Open with
- No valid app found
(hidden)
Pin folder
Unpin folder
@@ -22,7 +20,6 @@
Change cover image
Select photo
Use default
- Set as
Volume
Brightness
Do not ask again in this session
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
index 8d13fa177..ad4a8140d 100644
--- a/app/src/main/res/xml/provider_paths.xml
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -1,4 +1,5 @@
+