diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b2897c4b..6e90ef9f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,22 @@
Changelog
==========
+Version 2.18.1 *(2017-11-16)*
+----------------------------
+
+ * Fixed some double-tap zoom issues
+ * Misc smaller fixes and improvements here and there
+
+Version 2.18.0 *(2017-11-09)*
+----------------------------
+
+ * Added an option to use english language on non-english devices
+ * Added an option to password protect the whole app
+ * Added an option to lock screen orientation at fullscreen view
+ * Split the Rotate button to 3 buttons per degrees
+ * Changed the way fullscreen images are loaded for better quality
+ * Fixed many memory leaks and smaller issues
+
Version 2.17.4 *(2017-11-06)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index 42f9024db..38604d2c2 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,8 +10,10 @@ android {
applicationId "com.simplemobiletools.gallery"
minSdkVersion 16
targetSdkVersion 27
- versionCode 142
- versionName "2.17.4"
+ versionCode 144
+ versionName "2.18.1"
+ multiDexEnabled true
+ setProperty("archivesBaseName", "gallery")
}
signingConfigs {
@@ -45,10 +47,10 @@ ext {
}
dependencies {
- compile 'com.simplemobiletools:commons:2.37.12'
- compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.7.2'
+ compile 'com.simplemobiletools:commons:2.39.10'
+ compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.8.0'
compile 'com.theartofdev.edmodo:android-image-cropper:2.4.0'
- compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
+ compile 'com.android.support:multidex:1.0.2'
compile 'com.google.code.gson:gson:2.8.2'
compile 'it.sephiroth.android.exif:library:1.0.1'
compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.8'
@@ -59,7 +61,7 @@ dependencies {
}
buildscript {
- ext.kotlin_version = '1.1.51'
+ ext.kotlin_version = '1.1.60'
repositories {
mavenCentral()
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ff7ff3399..e0e44d1c3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
+
()
+ config.excludedFolders.mapTo(folders, { it })
+ manage_folders_placeholder.text = getString(R.string.excluded_activity_placeholder)
+ manage_folders_placeholder.beVisibleIf(folders.isEmpty())
+ manage_folders_placeholder.setTextColor(config.textColor)
- for (folder in folders) {
- layoutInflater.inflate(R.layout.item_manage_folder, null, false).apply {
- managed_folder_title.apply {
- text = folder
- setTextColor(config.textColor)
- }
- managed_folders_icon.apply {
- setColorFilter(config.textColor, PorterDuff.Mode.SRC_IN)
- setOnClickListener {
- config.removeExcludedFolder(folder)
- updateExcludedFolders()
- }
- }
- excluded_folders_holder.addView(this)
- }
- }
+ val adapter = ManageFoldersAdapter(this, folders, true, this, manage_folders_list) {}
+ adapter.setupDragListener(true)
+ manage_folders_list.adapter = adapter
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -55,6 +43,10 @@ class ExcludedFoldersActivity : SimpleActivity() {
return true
}
+ override fun refreshItems() {
+ updateExcludedFolders()
+ }
+
private fun addExcludedFolder() {
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden) {
config.addExcludedFolder(it)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/IncludedFoldersActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/IncludedFoldersActivity.kt
index f69f4f987..3f4067312 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/IncludedFoldersActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/IncludedFoldersActivity.kt
@@ -1,46 +1,34 @@
package com.simplemobiletools.gallery.activities
-import android.graphics.PorterDuff
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.scanPath
+import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.gallery.R
+import com.simplemobiletools.gallery.adapters.ManageFoldersAdapter
import com.simplemobiletools.gallery.extensions.config
-import kotlinx.android.synthetic.main.activity_included_folders.*
-import kotlinx.android.synthetic.main.item_manage_folder.view.*
+import kotlinx.android.synthetic.main.activity_manage_folders.*
-class IncludedFoldersActivity : SimpleActivity() {
+class IncludedFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_included_folders)
+ setContentView(R.layout.activity_manage_folders)
updateIncludedFolders()
}
private fun updateIncludedFolders() {
- included_folders_holder.removeAllViews()
- val folders = config.includedFolders
- included_folders_placeholder.beVisibleIf(folders.isEmpty())
- included_folders_placeholder.setTextColor(config.textColor)
+ val folders = ArrayList()
+ config.includedFolders.mapTo(folders, { it })
+ manage_folders_placeholder.text = getString(R.string.included_activity_placeholder)
+ manage_folders_placeholder.beVisibleIf(folders.isEmpty())
+ manage_folders_placeholder.setTextColor(config.textColor)
- for (folder in folders) {
- layoutInflater.inflate(R.layout.item_manage_folder, null, false).apply {
- managed_folder_title.apply {
- text = folder
- setTextColor(config.textColor)
- }
- managed_folders_icon.apply {
- setColorFilter(config.textColor, PorterDuff.Mode.SRC_IN)
- setOnClickListener {
- config.removeIncludedFolder(folder)
- updateIncludedFolders()
- }
- }
- included_folders_holder.addView(this)
- }
- }
+ val adapter = ManageFoldersAdapter(this, folders, false, this, manage_folders_list) {}
+ adapter.setupDragListener(true)
+ manage_folders_list.adapter = adapter
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -56,11 +44,15 @@ class IncludedFoldersActivity : SimpleActivity() {
return true
}
+ override fun refreshItems() {
+ updateIncludedFolders()
+ }
+
private fun addIncludedFolder() {
FilePickerDialog(this, pickFile = false, showHidden = config.shouldShowHidden) {
config.addIncludedFolder(it)
updateIncludedFolders()
- scanPath(it) {}
+ scanPath(it)
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt
index 62c143735..25806c41e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MainActivity.kt
@@ -4,7 +4,6 @@ import android.app.Activity
import android.content.ClipData
import android.content.Intent
import android.net.Uri
-import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.provider.MediaStore
@@ -23,7 +22,7 @@ import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_TAKEN
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.Release
-import com.simplemobiletools.commons.views.MyScalableRecyclerView
+import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.BuildConfig
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.adapters.DirectoryAdapter
@@ -64,6 +63,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
private var mLatestMediaId = 0L
private var mLastMediaHandler = Handler()
private var mCurrAsyncTask: GetDirectoriesAsynctask? = null
+ private var mZoomListener: MyRecyclerView.MyZoomListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -178,7 +178,6 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
directories_refresh_layout.isRefreshing = false
mIsGettingDirs = false
storeStateVariables()
- directories_grid.listener = null
mLastMediaHandler.removeCallbacksAndMessages(null)
if (!mDirs.isEmpty()) {
@@ -209,7 +208,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
val newFolder = File(config.tempFolderPath)
if (newFolder.exists() && newFolder.isDirectory) {
if (newFolder.list()?.isEmpty() == true) {
- deleteFileBg(newFolder, true) { }
+ deleteFileBg(newFolder, true)
}
}
config.tempFolderPath = ""
@@ -341,6 +340,11 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
} else {
setupListLayoutManager()
}
+
+ getDirectoryAdapter()?.apply {
+ setupZoomListener(mZoomListener)
+ setupDragListener(true)
+ }
}
private fun setupGridLayoutManager() {
@@ -353,42 +357,30 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
directories_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
- directories_grid.isDragSelectionEnabled = true
- directories_grid.isZoomingEnabled = true
layoutManager.spanCount = config.dirColumnCnt
- directories_grid.listener = object : MyScalableRecyclerView.MyScalableRecyclerViewListener {
+ mZoomListener = object : MyRecyclerView.MyZoomListener {
override fun zoomIn() {
if (layoutManager.spanCount > 1) {
reduceColumnCount()
- getRecyclerAdapter().actMode?.finish()
+ getRecyclerAdapter().finishActMode()
}
}
override fun zoomOut() {
if (layoutManager.spanCount < MAX_COLUMN_COUNT) {
increaseColumnCount()
- getRecyclerAdapter().actMode?.finish()
+ getRecyclerAdapter().finishActMode()
}
}
-
- override fun selectItem(position: Int) {
- getRecyclerAdapter().selectItem(position)
- }
-
- override fun selectRange(initialSelection: Int, lastDraggedIndex: Int, minReached: Int, maxReached: Int) {
- getRecyclerAdapter().selectRange(initialSelection, lastDraggedIndex, minReached, maxReached)
- }
}
}
private fun setupListLayoutManager() {
- directories_grid.isDragSelectionEnabled = true
- directories_grid.isZoomingEnabled = false
-
val layoutManager = directories_grid.layoutManager as GridLayoutManager
layoutManager.spanCount = 1
layoutManager.orientation = GridLayoutManager.VERTICAL
directories_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ mZoomListener = null
}
private fun createNewFolder() {
@@ -451,7 +443,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
else -> fillIntentPath(resultData, resultIntent)
}
} else if ((mIsPickImageIntent || mIsPickVideoIntent)) {
- val path = resultData.data.path
+ val path = resultData.data?.path
val uri = getFilePublicUri(File(path), BuildConfig.APPLICATION_ID)
resultIntent.data = uri
resultIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
@@ -560,8 +552,8 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
private fun setupAdapter() {
val currAdapter = directories_grid.adapter
if (currAdapter == null) {
- directories_grid.adapter = DirectoryAdapter(this, mDirs, this, isPickIntent(intent) || isGetAnyContentIntent(intent)) {
- itemClicked(it.path)
+ directories_grid.adapter = DirectoryAdapter(this, mDirs, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent)) {
+ itemClicked((it as Directory).path)
}
} else {
(currAdapter as DirectoryAdapter).updateDirs(mDirs)
@@ -587,7 +579,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
}
private fun checkLastMediaChanged() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isDestroyed)
+ if (isActivityDestroyed())
return
mLastMediaHandler.removeCallbacksAndMessages(null)
@@ -610,10 +602,6 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
getDirectories()
}
- override fun itemLongClicked(position: Int) {
- directories_grid.setDragSelectActive(position)
- }
-
override fun recheckPinnedFolders() {
gotDirectories(movePinnedDirectoriesToFront(mDirs), true)
}
@@ -659,6 +647,7 @@ class MainActivity : SimpleActivity(), DirectoryAdapter.DirOperationsListener {
add(Release(136, R.string.release_136))
add(Release(137, R.string.release_137))
add(Release(138, R.string.release_138))
+ add(Release(143, R.string.release_143))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt
index b500af01e..d4fdd4955 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/MediaActivity.kt
@@ -5,7 +5,6 @@ import android.app.WallpaperManager
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
-import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.support.v7.widget.GridLayoutManager
@@ -24,7 +23,7 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE
import com.simplemobiletools.commons.models.RadioItem
-import com.simplemobiletools.commons.views.MyScalableRecyclerView
+import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.adapters.MediaAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
@@ -59,6 +58,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
private var mLatestMediaId = 0L
private var mLastMediaHandler = Handler()
private var mCurrAsyncTask: GetMediaAsynctask? = null
+ private var mZoomListener: MyRecyclerView.MyZoomListener? = null
companion object {
var mMedia = ArrayList()
@@ -120,7 +120,6 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
mIsGettingMedia = false
media_refresh_layout.isRefreshing = false
storeStateVariables()
- media_grid.listener = null
mLastMediaHandler.removeCallbacksAndMessages(null)
if (!mMedia.isEmpty()) {
@@ -177,8 +176,8 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
val currAdapter = media_grid.adapter
if (currAdapter == null) {
- media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetImageIntent || mIsGetVideoIntent || mIsGetAnyIntent, mAllowPickingMultiple) {
- itemClicked(it.path)
+ media_grid.adapter = MediaAdapter(this, mMedia, this, mIsGetImageIntent || mIsGetVideoIntent || mIsGetAnyIntent, mAllowPickingMultiple, media_grid) {
+ itemClicked((it as Medium).path)
}
} else {
(currAdapter as MediaAdapter).updateMedia(mMedia)
@@ -204,7 +203,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
}
private fun checkLastMediaChanged() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isDestroyed)
+ if (isActivityDestroyed())
return
mLastMediaHandler.removeCallbacksAndMessages(null)
@@ -347,7 +346,7 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
private fun deleteDirectoryIfEmpty() {
val file = File(mPath)
if (config.deleteEmptyFolders && !file.isDownloadsFolder() && file.isDirectory && file.listFiles()?.isEmpty() == true) {
- deleteFile(file, true) {}
+ deleteFile(file, true)
}
}
@@ -398,10 +397,16 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
private fun getRecyclerAdapter() = (media_grid.adapter as MediaAdapter)
private fun setupLayoutManager() {
- if (config.viewTypeFiles == VIEW_TYPE_GRID)
+ if (config.viewTypeFiles == VIEW_TYPE_GRID) {
setupGridLayoutManager()
- else
+ } else {
setupListLayoutManager()
+ }
+
+ getMediaAdapter()?.apply {
+ setupZoomListener(mZoomListener)
+ setupDragListener(true)
+ }
}
private fun setupGridLayoutManager() {
@@ -414,42 +419,30 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
media_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
- media_grid.isDragSelectionEnabled = true
- media_grid.isZoomingEnabled = true
layoutManager.spanCount = config.mediaColumnCnt
- media_grid.listener = object : MyScalableRecyclerView.MyScalableRecyclerViewListener {
+ mZoomListener = object : MyRecyclerView.MyZoomListener {
override fun zoomIn() {
if (layoutManager.spanCount > 1) {
reduceColumnCount()
- getRecyclerAdapter().actMode?.finish()
+ getRecyclerAdapter().finishActMode()
}
}
override fun zoomOut() {
if (layoutManager.spanCount < MAX_COLUMN_COUNT) {
increaseColumnCount()
- getRecyclerAdapter().actMode?.finish()
+ getRecyclerAdapter().finishActMode()
}
}
-
- override fun selectItem(position: Int) {
- getRecyclerAdapter().selectItem(position)
- }
-
- override fun selectRange(initialSelection: Int, lastDraggedIndex: Int, minReached: Int, maxReached: Int) {
- getRecyclerAdapter().selectRange(initialSelection, lastDraggedIndex, minReached, maxReached)
- }
}
}
private fun setupListLayoutManager() {
- media_grid.isDragSelectionEnabled = true
- media_grid.isZoomingEnabled = false
-
val layoutManager = media_grid.layoutManager as GridLayoutManager
layoutManager.spanCount = 1
layoutManager.orientation = GridLayoutManager.VERTICAL
media_refresh_layout.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ mZoomListener = null
}
private fun increaseColumnCount() {
@@ -575,10 +568,6 @@ class MediaActivity : SimpleActivity(), MediaAdapter.MediaOperationsListener {
}, 1000)
}
- override fun itemLongClicked(position: Int) {
- media_grid.setDragSelectActive(position)
- }
-
override fun selectedPaths(paths: ArrayList) {
Intent().apply {
putExtra(PICKED_PATHS, paths)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt
index 960db4d14..e92593e3b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/PhotoVideoActivity.kt
@@ -59,14 +59,14 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
mIsFromGallery = intent.getBooleanExtra(IS_FROM_GALLERY, false)
if (mUri!!.scheme == "file") {
- scanPath(mUri!!.path) {}
+ scanPath(mUri!!.path)
sendViewPagerIntent(mUri!!.path)
finish()
return
} else {
val path = applicationContext.getRealPathFromURI(mUri!!) ?: ""
if (path != mUri.toString() && path.isNotEmpty()) {
- scanPath(mUri!!.path) {}
+ scanPath(mUri!!.path)
sendViewPagerIntent(path)
finish()
return
@@ -114,9 +114,11 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
override fun onCreateOptionsMenu(menu: Menu): Boolean {
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 && mUri?.scheme == "file"
- menu.findItem(R.id.menu_properties).isVisible = mUri?.scheme == "file"
+ menu.apply {
+ findItem(R.id.menu_set_as).isVisible = mMedium?.isImage() == true
+ findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true && mUri?.scheme == "file"
+ findItem(R.id.menu_properties).isVisible = mUri?.scheme == "file"
+ }
return true
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SetWallpaperActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SetWallpaperActivity.kt
index 9d2fddb3c..07a493239 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SetWallpaperActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SetWallpaperActivity.kt
@@ -5,10 +5,10 @@ import android.app.WallpaperManager
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
-import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
+import com.simplemobiletools.commons.extensions.isActivityDestroyed
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
import com.theartofdev.edmodo.cropper.CropImageView
@@ -61,8 +61,10 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_set_wallpaper, menu)
- menu.findItem(R.id.portrait_aspect_ratio).isVisible = isLandscapeRatio
- menu.findItem(R.id.landscape_aspect_ratio).isVisible = !isLandscapeRatio
+ menu.apply {
+ findItem(R.id.portrait_aspect_ratio).isVisible = isLandscapeRatio
+ findItem(R.id.landscape_aspect_ratio).isVisible = !isLandscapeRatio
+ }
return true
}
@@ -84,7 +86,7 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
}
override fun onCropImageComplete(view: CropImageView?, result: CropImageView.CropResult) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isDestroyed)
+ if (isActivityDestroyed())
return
if (result.error == null) {
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 a09c3bd53..4bb90d013 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SettingsActivity.kt
@@ -67,7 +67,7 @@ class SettingsActivity : SimpleActivity() {
}
private fun setupUseEnglish() {
- settings_use_english_holder.beVisibleIf(Locale.getDefault().language != "en")
+ settings_use_english_holder.beVisibleIf(config.wasUseEnglishToggled || Locale.getDefault().language != "en")
settings_use_english.isChecked = config.useEnglish
settings_use_english_holder.setOnClickListener {
settings_use_english.toggle()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SimpleActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SimpleActivity.kt
index f30d65e31..42e8828dc 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SimpleActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/SimpleActivity.kt
@@ -1,36 +1,5 @@
package com.simplemobiletools.gallery.activities
import com.simplemobiletools.commons.activities.BaseSimpleActivity
-import com.simplemobiletools.commons.extensions.getFilenameFromPath
-import com.simplemobiletools.commons.extensions.toast
-import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.dialogs.PickDirectoryDialog
-import com.simplemobiletools.gallery.extensions.config
-import com.simplemobiletools.gallery.models.Directory
-import java.io.File
-import java.util.*
-open class SimpleActivity : BaseSimpleActivity() {
- fun tryCopyMoveFilesTo(files: ArrayList, isCopyOperation: Boolean, callback: () -> Unit) {
- if (files.isEmpty()) {
- toast(R.string.unknown_error_occurred)
- return
- }
-
- val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
- PickDirectoryDialog(this, source) {
- copyMoveFilesTo(files, source.trimEnd('/'), it, isCopyOperation, true, callback)
- }
- }
-
- fun addTempFolderIfNeeded(dirs: ArrayList): ArrayList {
- val directories = ArrayList()
- val tempFolderPath = config.tempFolderPath
- if (tempFolderPath.isNotEmpty()) {
- val newFolder = Directory(tempFolderPath, "", tempFolderPath.getFilenameFromPath(), 0, 0, 0, 0L)
- directories.add(newFolder)
- }
- directories.addAll(dirs)
- return directories
- }
-}
+open class SimpleActivity : BaseSimpleActivity()
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 2a8099959..1c00f66a8 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/activities/ViewPagerActivity.kt
@@ -23,6 +23,7 @@ import android.support.v4.view.ViewPager
import android.util.DisplayMetrics
import android.view.*
import android.view.animation.DecelerateInterpolator
+import com.bumptech.glide.Glide
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.*
@@ -73,6 +74,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
companion object {
var screenWidth = 0
var screenHeight = 0
+ var wasDecodedByGlide = false
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -185,7 +187,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
title = mPath.getFilenameFromPath()
view_pager.onGlobalLayout {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 || !isDestroyed) {
+ if (!isActivityDestroyed()) {
if (mMedia.isNotEmpty()) {
gotMedia(mMedia)
}
@@ -193,7 +195,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
reloadViewPager()
- scanPath(mPath) {}
+ scanPath(mPath)
if (config.darkBackground)
view_pager.background = ColorDrawable(Color.BLACK)
@@ -226,8 +228,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 60..134 -> ORIENT_LANDSCAPE_RIGHT
- in 225..299 -> ORIENT_LANDSCAPE_LEFT
+ in 75..134 -> ORIENT_LANDSCAPE_RIGHT
+ in 225..285 -> ORIENT_LANDSCAPE_LEFT
else -> ORIENT_PORTRAIT
}
@@ -303,7 +305,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun updatePagerItems(media: MutableList) {
val pagerAdapter = MyPagerAdapter(this, supportFragmentManager, media)
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 || !isDestroyed) {
+ if (!isActivityDestroyed()) {
view_pager.apply {
adapter = pagerAdapter
currentItem = mPos
@@ -321,7 +323,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun startSlideshow() {
if (getMediaForSlideshow()) {
view_pager.onGlobalLayout {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 || !isDestroyed) {
+ if (!isActivityDestroyed()) {
hideSystemUI()
mSlideshowInterval = config.slideshowInterval
mSlideshowMoveBackwards = config.slideshowMoveBackwards
@@ -401,7 +403,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
if (mIsSlideshowActive) {
if (getCurrentMedium()!!.isImage() || getCurrentMedium()!!.isGif()) {
mSlideshowHandler.postDelayed({
- if (mIsSlideshowActive && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && !isDestroyed) {
+ if (mIsSlideshowActive && !isActivityDestroyed()) {
swipeToNextMedium()
}
}, mSlideshowInterval * 1000L)
@@ -494,52 +496,64 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun saveImageAs() {
val currPath = getCurrentPath()
SaveAsDialog(this, currPath, false) {
- Thread({
- val selectedFile = File(it)
- handleSAFDialog(selectedFile) {
- toast(R.string.saving)
- val tmpFile = File(filesDir, ".tmp_${it.getFilenameFromPath()}")
- try {
- val bitmap = BitmapFactory.decodeFile(currPath)
- getFileOutputStream(tmpFile) {
- if (it == null) {
- toast(R.string.unknown_error_occurred)
- return@getFileOutputStream
- }
+ val selectedFile = File(it)
+ handleSAFDialog(selectedFile) {
+ Thread({
+ saveImageToFile(currPath, it)
+ }).start()
+ }
+ }
+ }
- val oldLastModified = getCurrentFile().lastModified()
- if (currPath.isJpg()) {
- saveRotation(getCurrentFile(), tmpFile)
- } else {
- saveFile(tmpFile, bitmap, it as FileOutputStream)
- }
-
- if (tmpFile.length() > 0 && selectedFile.exists()) {
- deleteFile(selectedFile) {}
- }
- copyFile(tmpFile, selectedFile)
- scanFile(selectedFile) {}
- toast(R.string.file_saved)
-
- if (config.keepLastModified) {
- selectedFile.setLastModified(oldLastModified)
- updateLastModified(selectedFile, oldLastModified)
- }
-
- it.flush()
- it.close()
- mRotationDegrees = 0f
- invalidateOptionsMenu()
- }
- } catch (e: OutOfMemoryError) {
- toast(R.string.out_of_memory_error)
- } catch (e: Exception) {
- showErrorToast(e)
- } finally {
- deleteFile(tmpFile) {}
- }
+ private fun saveImageToFile(oldPath: String, newPath: String) {
+ val newFile = File(newPath)
+ toast(R.string.saving)
+ val tmpFile = File(filesDir, ".tmp_${newPath.getFilenameFromPath()}")
+ try {
+ val bitmap = BitmapFactory.decodeFile(oldPath)
+ getFileOutputStream(tmpFile) {
+ if (it == null) {
+ toast(R.string.unknown_error_occurred)
+ return@getFileOutputStream
}
- }).start()
+
+ val oldLastModified = getCurrentFile().lastModified()
+ if (oldPath.isJpg()) {
+ saveRotation(getCurrentFile(), tmpFile)
+ } else {
+ saveFile(tmpFile, bitmap, it as FileOutputStream)
+ }
+
+ if (tmpFile.length() > 0 && newFile.exists()) {
+ deleteFile(newFile)
+ }
+ copyFile(tmpFile, newFile)
+ scanFile(newFile)
+ toast(R.string.file_saved)
+
+ if (config.keepLastModified) {
+ newFile.setLastModified(oldLastModified)
+ updateLastModified(newFile, oldLastModified)
+ }
+
+ it.flush()
+ it.close()
+ mRotationDegrees = 0f
+ invalidateOptionsMenu()
+
+ // we cannot refresh a specific image in Glide Cache, so just clear it all
+ val glide = Glide.get(applicationContext)
+ glide.clearDiskCache()
+ runOnUiThread {
+ glide.clearMemory()
+ }
+ }
+ } catch (e: OutOfMemoryError) {
+ toast(R.string.out_of_memory_error)
+ } catch (e: Exception) {
+ showErrorToast(e)
+ } finally {
+ deleteFile(tmpFile)
}
}
@@ -780,10 +794,10 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun deleteDirectoryIfEmpty() {
val file = File(mDirectory)
if (config.deleteEmptyFolders && !file.isDownloadsFolder() && file.isDirectory && file.listFiles()?.isEmpty() == true) {
- deleteFile(file, true) {}
+ deleteFile(file, true)
}
- scanPath(mDirectory) {}
+ scanPath(mDirectory)
}
private fun checkOrientation() {
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 b2f585e07..74a25b4a9 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/DirectoryAdapter.kt
@@ -1,22 +1,20 @@
package com.simplemobiletools.gallery.adapters
import android.graphics.PorterDuff
-import android.os.Build
-import android.support.v7.view.ActionMode
-import android.support.v7.widget.RecyclerView
import android.util.SparseArray
-import android.view.*
-import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
-import com.bignerdranch.android.multiselector.MultiSelector
-import com.bignerdranch.android.multiselector.SwappingHolder
+import android.view.Menu
+import android.view.View
+import android.view.ViewGroup
import com.bumptech.glide.Glide
import com.google.gson.Gson
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
+import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.dialogs.ExcludeFolderDialog
import com.simplemobiletools.gallery.dialogs.PickMediumDialog
import com.simplemobiletools.gallery.extensions.*
@@ -27,134 +25,103 @@ import kotlinx.android.synthetic.main.directory_item_list.view.*
import java.io.File
import java.util.*
-class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList, val listener: DirOperationsListener?, val isPickIntent: Boolean,
- val itemClick: (Directory) -> Unit) : RecyclerView.Adapter() {
+class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: MutableList, val listener: DirOperationsListener?, recyclerView: MyRecyclerView,
+ val isPickIntent: Boolean, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
private val config = activity.config
- var actMode: ActionMode? = null
- var primaryColor = config.primaryColor
-
- private val multiSelector = MultiSelector()
private val isListViewType = config.viewTypeFolders == VIEW_TYPE_LIST
- private var itemViews = SparseArray()
- private val selectedPositions = HashSet()
- 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) {
- if (itemViews[pos] != null) {
- itemViews[pos].dir_check?.background?.setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN)
- selectedPositions.add(pos)
- }
- } else {
- selectedPositions.remove(pos)
- }
-
- itemViews[pos]?.dir_check?.beVisibleIf(select)
-
- if (selectedPositions.isEmpty()) {
- actMode?.finish()
- return
- }
-
- updateTitle(selectedPositions.size)
+ init {
+ selectableItemCount = dirs.count()
}
- private fun updateTitle(cnt: Int) {
- actMode?.title = "$cnt / ${dirs.size}"
- actMode?.invalidate()
+ override fun getActionMenuId() = R.menu.cab_directories
+
+ override fun prepareItemSelection(view: View) {
+ view.dir_check?.background?.applyColorFilter(primaryColor)
}
- private val adapterListener = object : MyAdapterListener {
- override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
- toggleItemSelection(select, position)
- }
-
- override fun getSelectedPositions(): HashSet = selectedPositions
+ override fun markItemSelection(select: Boolean, view: View?) {
+ view?.dir_check?.beVisibleIf(select)
}
- private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
- override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.cab_properties -> showProperties()
- R.id.cab_rename -> renameDir()
- R.id.cab_pin -> pinFolders(true)
- R.id.cab_unpin -> pinFolders(false)
- R.id.cab_hide -> toggleFoldersVisibility(true)
- R.id.cab_unhide -> toggleFoldersVisibility(false)
- R.id.cab_exclude -> tryExcludeFolder()
- R.id.cab_copy_to -> copyMoveTo(true)
- R.id.cab_move_to -> copyMoveTo(false)
- R.id.cab_select_all -> selectAll()
- R.id.cab_delete -> askConfirmDelete()
- R.id.cab_select_photo -> changeAlbumCover(false)
- R.id.cab_use_default -> changeAlbumCover(true)
- else -> return false
+ override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
+ val layoutType = if (isListViewType) R.layout.directory_item_list else R.layout.directory_item_grid
+ return createViewHolder(layoutType, parent)
+ }
+
+ override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
+ val dir = dirs[position]
+ val view = holder.bindView(dir, !isPickIntent) {
+ setupView(it, dir)
+ }
+ bindViewHolder(holder, position, view)
+ }
+
+ override fun getItemCount() = dirs.size
+
+ override fun prepareActionMode(menu: Menu) {
+ menu.apply {
+ findItem(R.id.cab_rename).isVisible = selectedPositions.size == 1
+ findItem(R.id.cab_change_cover_image).isVisible = selectedPositions.size == 1
+
+ checkHideBtnVisibility(this)
+ checkPinBtnVisibility(this)
+ }
+ }
+
+ override fun actionItemPressed(id: Int) {
+ when (id) {
+ R.id.cab_properties -> showProperties()
+ R.id.cab_rename -> renameDir()
+ R.id.cab_pin -> pinFolders(true)
+ R.id.cab_unpin -> pinFolders(false)
+ R.id.cab_hide -> toggleFoldersVisibility(true)
+ R.id.cab_unhide -> toggleFoldersVisibility(false)
+ R.id.cab_exclude -> tryExcludeFolder()
+ R.id.cab_copy_to -> copyMoveTo(true)
+ R.id.cab_move_to -> copyMoveTo(false)
+ R.id.cab_select_all -> selectAll()
+ R.id.cab_delete -> askConfirmDelete()
+ R.id.cab_select_photo -> changeAlbumCover(false)
+ R.id.cab_use_default -> changeAlbumCover(true)
+ }
+ }
+
+ private fun checkHideBtnVisibility(menu: Menu) {
+ var hiddenCnt = 0
+ var unhiddenCnt = 0
+ selectedPositions.mapNotNull { dirs.getOrNull(it)?.path }.forEach {
+ if (File(it).containsNoMedia()) {
+ hiddenCnt++
+ } else {
+ unhiddenCnt++
}
- return true
}
- override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
- super.onCreateActionMode(actionMode, menu)
- actMode = actionMode
- activity.menuInflater.inflate(R.menu.cab_directories, menu)
- return true
- }
+ menu.findItem(R.id.cab_hide).isVisible = unhiddenCnt > 0
+ menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
+ }
- override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
- menu.findItem(R.id.cab_rename).isVisible = selectedPositions.size <= 1
- menu.findItem(R.id.cab_change_cover_image).isVisible = selectedPositions.size <= 1
-
- checkHideBtnVisibility(menu)
- checkPinBtnVisibility(menu)
-
- return true
- }
-
- override fun onDestroyActionMode(actionMode: ActionMode?) {
- super.onDestroyActionMode(actionMode)
- selectedPositions.forEach {
- itemViews[it]?.dir_check?.beGone()
+ private fun checkPinBtnVisibility(menu: Menu) {
+ val pinnedFolders = config.pinnedFolders
+ var pinnedCnt = 0
+ var unpinnedCnt = 0
+ selectedPositions.mapNotNull { dirs.getOrNull(it)?.path }.forEach {
+ if (pinnedFolders.contains(it)) {
+ pinnedCnt++
+ } else {
+ unpinnedCnt++
}
- selectedPositions.clear()
- actMode = null
}
- fun checkHideBtnVisibility(menu: Menu) {
- var hiddenCnt = 0
- var unhiddenCnt = 0
- selectedPositions.mapNotNull { dirs.getOrNull(it)?.path }.forEach {
- if (File(it).containsNoMedia()) {
- hiddenCnt++
- } else {
- unhiddenCnt++
- }
- }
-
- menu.findItem(R.id.cab_hide).isVisible = unhiddenCnt > 0
- menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
- }
-
- fun checkPinBtnVisibility(menu: Menu) {
- val pinnedFolders = config.pinnedFolders
- var pinnedCnt = 0
- var unpinnedCnt = 0
- selectedPositions.mapNotNull { dirs.getOrNull(it)?.path }.forEach {
- if (pinnedFolders.contains(it)) {
- pinnedCnt++
- } else {
- unpinnedCnt++
- }
- }
-
- menu.findItem(R.id.cab_pin).isVisible = unpinnedCnt > 0
- menu.findItem(R.id.cab_unpin).isVisible = pinnedCnt > 0
- }
+ menu.findItem(R.id.cab_pin).isVisible = unpinnedCnt > 0
+ menu.findItem(R.id.cab_unpin).isVisible = pinnedCnt > 0
}
private fun showProperties() {
@@ -178,7 +145,7 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList newItems.put(curIndex, itemViews[i]) }
itemViews = newItems
- actMode?.finish()
+ selectableItemCount = dirs.size
+ finishActMode()
}
}
@@ -337,7 +296,7 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList) {
activity.config.albumCovers = Gson().toJson(albumCovers)
- actMode?.finish()
+ finishActMode()
listener?.refreshItems()
}
@@ -347,30 +306,18 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList) {
dirs = newDirs
+ selectableItemCount = dirs.size
notifyDataSetChanged()
- actMode?.finish()
+ finishActMode()
}
fun updateAnimateGifs(animateGifs: Boolean) {
@@ -393,117 +340,31 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList -1 && min < to) {
- (min until to).filter { it != from }
- .forEach { toggleItemSelection(false, it) }
- }
- if (max > -1) {
- for (i in from + 1..max)
- toggleItemSelection(false, i)
- }
- } else {
- for (i in from..to)
- toggleItemSelection(true, i)
-
- if (max > -1 && max > to) {
- (to + 1..max).filter { it != from }
- .forEach { toggleItemSelection(false, it) }
- }
-
- if (min > -1) {
- for (i in min until from)
- toggleItemSelection(false, i)
+ if (isListViewType) {
+ dir_name.setTextColor(textColor)
+ dir_path.setTextColor(textColor)
+ photo_cnt.setTextColor(textColor)
+ dir_pin.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
+ dir_sd_card.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
}
}
}
- class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
- val multiSelector: MultiSelector, val listener: DirOperationsListener?, val isPickIntent: Boolean, val itemClick: (Directory) -> (Unit)) :
- SwappingHolder(view, MultiSelector()) {
- 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, scrollHorizontally, animateGifs, cropThumbnails)
- dir_pin.beVisibleIf(isPinned)
- dir_sd_card.beVisibleIf(activity.isPathOnSD(directory.path))
- photo_cnt.beVisibleIf(showMediaCount)
-
- if (isListView) {
- dir_name.setTextColor(textColor)
- dir_path.setTextColor(textColor)
- photo_cnt.setTextColor(textColor)
- dir_pin.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
- dir_sd_card.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
- }
-
- setOnClickListener { viewClicked(directory) }
- setOnLongClickListener { if (isPickIntent) viewClicked(directory) else viewLongClicked(); true }
- }
- return itemView
- }
-
- private fun viewClicked(directory: Directory) {
- if (multiSelector.isSelectable) {
- val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition)
- adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition)
- } else {
- itemClick(directory)
- }
- }
-
- private fun viewLongClicked() {
- if (listener != null) {
- if (!multiSelector.isSelectable) {
- activity.startSupportActionMode(multiSelectorCallback)
- adapterListener.toggleItemSelectionAdapter(true, adapterPosition)
- }
-
- listener.itemLongClicked(adapterPosition)
- }
- }
-
- fun stopLoad() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 || !activity.isDestroyed)
- Glide.with(activity).clear(view.dir_thumbnail)
- }
- }
-
- interface MyAdapterListener {
- fun toggleItemSelectionAdapter(select: Boolean, position: Int)
-
- fun getSelectedPositions(): HashSet
- }
-
interface DirOperationsListener {
fun refreshItems()
fun tryDeleteFolders(folders: ArrayList)
- fun itemLongClicked(position: Int)
-
fun recheckPinnedFolders()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt
new file mode 100644
index 000000000..675490a0c
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/ManageFoldersAdapter.kt
@@ -0,0 +1,99 @@
+package com.simplemobiletools.gallery.adapters
+
+import android.util.SparseArray
+import android.view.Menu
+import android.view.View
+import android.view.ViewGroup
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
+import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
+import com.simplemobiletools.commons.dialogs.ConfirmationDialog
+import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
+import com.simplemobiletools.commons.views.MyRecyclerView
+import com.simplemobiletools.gallery.R
+import com.simplemobiletools.gallery.extensions.config
+import kotlinx.android.synthetic.main.item_manage_folder.view.*
+import java.util.*
+
+class ManageFoldersAdapter(activity: BaseSimpleActivity, var folders: ArrayList, val isShowingExcludedFolders: Boolean, val listener: RefreshRecyclerViewListener?,
+ recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
+
+ private val config = activity.config
+
+ init {
+ selectableItemCount = folders.size
+ }
+
+ override fun getActionMenuId() = R.menu.cab_delete_only
+
+ override fun prepareActionMode(menu: Menu) {}
+
+ override fun prepareItemSelection(view: View) {}
+
+ override fun markItemSelection(select: Boolean, view: View?) {
+ view?.manage_folder_holder?.isSelected = select
+ }
+
+ override fun actionItemPressed(id: Int) {
+ when (id) {
+ R.id.cab_delete -> askConfirmDelete()
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) = createViewHolder(R.layout.item_manage_folder, parent)
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val folder = folders[position]
+ val view = holder.bindView(folder) {
+ setupView(it, folder)
+ }
+ bindViewHolder(holder, position, view)
+ }
+
+ override fun getItemCount() = folders.size
+
+ private fun setupView(view: View, folder: String) {
+ view.apply {
+ manage_folder_title.apply {
+ text = folder
+ setTextColor(config.textColor)
+ }
+ }
+ }
+
+ private fun askConfirmDelete() {
+ ConfirmationDialog(activity) {
+ deleteSelection()
+ }
+ }
+
+ private fun deleteSelection() {
+ val removeFolders = ArrayList(selectedPositions.size)
+
+ selectedPositions.sortedDescending().forEach {
+ val folder = folders[it]
+ removeFolders.add(folder)
+ notifyItemRemoved(it)
+ itemViews.put(it, null)
+ if (isShowingExcludedFolders) {
+ config.removeExcludedFolder(folder)
+ } else {
+ config.removeIncludedFolder(folder)
+ }
+ }
+
+ folders.removeAll(removeFolders)
+ selectedPositions.clear()
+
+ val newItems = SparseArray()
+ (0 until itemViews.size())
+ .filter { itemViews[it] != null }
+ .forEachIndexed { curIndex, i -> newItems.put(curIndex, itemViews[i]) }
+
+ itemViews = newItems
+ selectableItemCount = folders.size
+ finishActMode()
+ if (folders.isEmpty()) {
+ listener?.refreshItems()
+ }
+ }
+}
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 039ac332a..c1a4a2c1d 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/adapters/MediaAdapter.kt
@@ -2,21 +2,20 @@ 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
import android.util.SparseArray
-import android.view.*
-import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
-import com.bignerdranch.android.multiselector.MultiSelector
-import com.bignerdranch.android.multiselector.SwappingHolder
+import android.view.Menu
+import android.view.View
+import android.view.ViewGroup
import com.bumptech.glide.Glide
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
+import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
-import com.simplemobiletools.commons.extensions.beGone
+import com.simplemobiletools.commons.extensions.applyColorFilter
import com.simplemobiletools.commons.extensions.beVisibleIf
+import com.simplemobiletools.commons.extensions.isActivityDestroyed
+import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.dialogs.DeleteWithRememberDialog
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.helpers.VIEW_TYPE_LIST
@@ -25,119 +24,88 @@ import kotlinx.android.synthetic.main.photo_video_item_grid.view.*
import java.io.File
import java.util.*
-class MediaAdapter(val activity: SimpleActivity, var media: MutableList, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
- val allowMultiplePicks: Boolean, val itemClick: (Medium) -> Unit) : RecyclerView.Adapter() {
+class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
+ val allowMultiplePicks: Boolean, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
private val config = activity.config
- var actMode: ActionMode? = null
- var primaryColor = config.primaryColor
-
- 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) {
- if (itemViews[pos] != null) {
- itemViews[pos].medium_check?.background?.setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN)
- selectedPositions.add(pos)
- }
- } else {
- selectedPositions.remove(pos)
- }
-
- itemViews[pos]?.medium_check?.beVisibleIf(select)
-
- if (selectedPositions.isEmpty()) {
- actMode?.finish()
- return
- }
-
- updateTitle(selectedPositions.size)
+ init {
+ selectableItemCount = media.count()
}
- private fun updateTitle(cnt: Int) {
- actMode?.title = "$cnt / ${media.size}"
- actMode?.invalidate()
+ override fun getActionMenuId() = R.menu.cab_media
+
+ override fun prepareItemSelection(view: View) {
+ view.medium_check?.background?.applyColorFilter(primaryColor)
}
- private val adapterListener = object : MyAdapterListener {
- override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
- toggleItemSelection(select, position)
- }
-
- override fun getSelectedPositions(): HashSet = selectedPositions
+ override fun markItemSelection(select: Boolean, view: View?) {
+ view?.medium_check?.beVisibleIf(select)
}
- private val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
- override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.cab_confirm_selection -> confirmSelection()
- R.id.cab_properties -> showProperties()
- R.id.cab_rename -> renameFile()
- R.id.cab_edit -> editFile()
- R.id.cab_hide -> toggleFileVisibility(true)
- R.id.cab_unhide -> toggleFileVisibility(false)
- R.id.cab_share -> shareMedia()
- 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
+ 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
+ return createViewHolder(layoutType, parent)
+ }
+
+ override fun onBindViewHolder(holder: MyRecyclerViewAdapter.ViewHolder, position: Int) {
+ val medium = media[position]
+ val view = holder.bindView(medium, !allowMultiplePicks) {
+ setupView(it, medium)
+ }
+ bindViewHolder(holder, position, view)
+ }
+
+ override fun getItemCount() = media.size
+
+ override fun prepareActionMode(menu: Menu) {
+ menu.apply {
+ findItem(R.id.cab_rename).isVisible = selectedPositions.size == 1
+ findItem(R.id.cab_open_with).isVisible = selectedPositions.size == 1
+ findItem(R.id.cab_confirm_selection).isVisible = isAGetIntent && allowMultiplePicks && selectedPositions.size > 0
+
+ checkHideBtnVisibility(this)
+ }
+ }
+
+ override fun actionItemPressed(id: Int) {
+ when (id) {
+ R.id.cab_confirm_selection -> confirmSelection()
+ R.id.cab_properties -> showProperties()
+ R.id.cab_rename -> renameFile()
+ R.id.cab_edit -> editFile()
+ R.id.cab_hide -> toggleFileVisibility(true)
+ R.id.cab_unhide -> toggleFileVisibility(false)
+ R.id.cab_share -> shareMedia()
+ 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()
+ }
+ }
+
+ private fun checkHideBtnVisibility(menu: Menu) {
+ var hiddenCnt = 0
+ var unhiddenCnt = 0
+ selectedPositions.mapNotNull { media.getOrNull(it) }.forEach {
+ if (it.name.startsWith('.')) {
+ hiddenCnt++
+ } else {
+ unhiddenCnt++
}
- return true
}
- override fun onCreateActionMode(actionMode: ActionMode?, menu: Menu?): Boolean {
- super.onCreateActionMode(actionMode, menu)
- actMode = actionMode
- activity.menuInflater.inflate(R.menu.cab_media, menu)
- return true
- }
-
- override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
- 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 = isAGetIntent && allowMultiplePicks && selectedPositions.size > 0
-
- checkHideBtnVisibility(menu)
-
- return true
- }
-
- override fun onDestroyActionMode(actionMode: ActionMode?) {
- super.onDestroyActionMode(actionMode)
- selectedPositions.forEach {
- itemViews[it]?.medium_check?.beGone()
- }
- selectedPositions.clear()
- actMode = null
- }
-
- fun checkHideBtnVisibility(menu: Menu) {
- var hiddenCnt = 0
- var unhiddenCnt = 0
- selectedPositions.mapNotNull { media.getOrNull(it) }.forEach {
- if (it.name.startsWith('.')) {
- hiddenCnt++
- } else {
- unhiddenCnt++
- }
- }
-
- menu.findItem(R.id.cab_hide).isVisible = unhiddenCnt > 0
- menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
- }
+ menu.findItem(R.id.cab_hide).isVisible = unhiddenCnt > 0
+ menu.findItem(R.id.cab_unhide).isVisible = hiddenCnt > 0
}
private fun confirmSelection() {
@@ -159,25 +127,25 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
RenameItemDialog(activity, getCurrentFile().absolutePath) {
activity.runOnUiThread {
listener?.refreshItems()
- actMode?.finish()
+ finishActMode()
}
}
}
private fun editFile() {
activity.openEditor(Uri.fromFile(getCurrentFile()))
- actMode?.finish()
+ finishActMode()
}
private fun toggleFileVisibility(hide: Boolean) {
Thread({
getSelectedMedia().forEach {
val oldFile = File(it.path)
- activity.toggleFileVisibility(oldFile, hide) {}
+ activity.toggleFileVisibility(oldFile, hide)
}
activity.runOnUiThread {
listener?.refreshItems()
- actMode?.finish()
+ finishActMode()
}
}).start()
}
@@ -199,20 +167,10 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
if (!isCopyOperation) {
listener?.refreshItems()
}
- actMode?.finish()
+ finishActMode()
}
}
- fun selectAll() {
- val cnt = media.size
- for (i in 0 until cnt) {
- selectedPositions.add(i)
- multiSelector.setSelected(i, 0, true)
- notifyItemChanged(i)
- }
- updateTitle(cnt)
- }
-
private fun checkDeleteConfirmation() {
if (skipConfirmationDialog) {
deleteConfirmed()
@@ -243,7 +201,7 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
val removeMedia = ArrayList(selectedPositions.size)
if (media.size <= selectedPositions.first()) {
- actMode?.finish()
+ finishActMode()
return
}
@@ -257,7 +215,6 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
}
media.removeAll(removeMedia)
- selectedPositions.clear()
listener?.deleteFiles(files)
val newItems = SparseArray()
@@ -266,7 +223,8 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
.forEachIndexed { curIndex, i -> newItems.put(curIndex, itemViews[i]) }
itemViews = newItems
- actMode?.finish()
+ selectableItemCount = media.size
+ finishActMode()
}
}
@@ -276,29 +234,18 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
return selectedMedia
}
- override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
- val layoutType = if (isListViewType) R.layout.photo_video_item_list else R.layout.photo_video_item_grid
- val view = LayoutInflater.from(parent?.context).inflate(layoutType, parent, false)
- return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, allowMultiplePicks || !isAGetIntent, itemClick)
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- itemViews.put(position, holder.bindView(media[position], displayFilenames, scrollHorizontally, isListViewType, textColor, animateGifs, cropThumbnails))
- toggleItemSelection(selectedPositions.contains(position), position)
- holder.itemView.tag = holder
- }
-
override fun onViewRecycled(holder: ViewHolder?) {
super.onViewRecycled(holder)
- holder?.stopLoad()
+ if (!activity.isActivityDestroyed()) {
+ Glide.with(activity).clear(holder?.itemView?.medium_thumbnail)
+ }
}
- override fun getItemCount() = media.size
-
fun updateMedia(newMedia: ArrayList) {
media = newMedia
+ selectableItemCount = media.size
notifyDataSetChanged()
- actMode?.finish()
+ finishActMode()
}
fun updateDisplayFilenames(displayFilenames: Boolean) {
@@ -321,112 +268,25 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList,
notifyDataSetChanged()
}
- fun updateTextColor(textColor: Int) {
- this.textColor = textColor
- notifyDataSetChanged()
- }
+ private fun setupView(view: View, medium: Medium) {
+ view.apply {
+ play_outline.beVisibleIf(medium.video)
+ photo_name.beVisibleIf(displayFilenames || isListViewType)
+ photo_name.text = medium.name
+ activity.loadImage(medium.path, medium_thumbnail, scrollHorizontally, animateGifs, cropThumbnails)
- fun selectItem(pos: Int) {
- toggleItemSelection(true, pos)
- }
-
- fun selectRange(from: Int, to: Int, min: Int, max: Int) {
- if (from == to) {
- (min..max).filter { it != from }
- .forEach { toggleItemSelection(false, it) }
- return
- }
-
- if (to < from) {
- for (i in to..from)
- toggleItemSelection(true, i)
-
- if (min > -1 && min < to) {
- (min until to).filter { it != from }
- .forEach { toggleItemSelection(false, it) }
- }
- if (max > -1) {
- for (i in from + 1..max)
- toggleItemSelection(false, i)
- }
- } else {
- for (i in from..to)
- toggleItemSelection(true, i)
-
- if (max > -1 && max > to) {
- (to + 1..max).filter { it != from }
- .forEach { toggleItemSelection(false, it) }
- }
-
- if (min > -1) {
- for (i in min until from)
- toggleItemSelection(false, i)
+ if (isListViewType) {
+ photo_name.setTextColor(textColor)
+ play_outline.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
}
}
}
- class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
- val multiSelector: MultiSelector, val listener: MediaOperationsListener?, val allowMultiplePicks: Boolean,
- val itemClick: (Medium) -> (Unit)) :
- SwappingHolder(view, MultiSelector()) {
- 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, scrollHorizontally, animateGifs, cropThumbnails)
-
- if (isListViewType) {
- photo_name.setTextColor(textColor)
- play_outline.setColorFilter(textColor, PorterDuff.Mode.SRC_IN)
- }
-
- setOnClickListener { viewClicked(medium) }
- setOnLongClickListener { if (allowMultiplePicks) viewLongClicked() else viewClicked(medium); true }
- }
- return itemView
- }
-
- private fun viewClicked(medium: Medium) {
- if (multiSelector.isSelectable) {
- val isSelected = adapterListener.getSelectedPositions().contains(adapterPosition)
- adapterListener.toggleItemSelectionAdapter(!isSelected, adapterPosition)
- } else {
- itemClick(medium)
- }
- }
-
- private fun viewLongClicked() {
- if (listener != null) {
- if (!multiSelector.isSelectable) {
- activity.startSupportActionMode(multiSelectorCallback)
- adapterListener.toggleItemSelectionAdapter(true, adapterPosition)
- }
-
- listener.itemLongClicked(adapterPosition)
- }
- }
-
- fun stopLoad() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1 || !activity.isDestroyed)
- Glide.with(activity).clear(view.medium_thumbnail)
- }
- }
-
- interface MyAdapterListener {
- fun toggleItemSelectionAdapter(select: Boolean, position: Int)
-
- fun getSelectedPositions(): HashSet
- }
-
interface MediaOperationsListener {
fun refreshItems()
fun deleteFiles(files: ArrayList)
- fun itemLongClicked(position: Int)
-
fun selectedPaths(paths: ArrayList)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ChangeSortingDialog.kt
index 95513a98e..0af86fd6a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ChangeSortingDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ChangeSortingDialog.kt
@@ -4,15 +4,15 @@ import android.content.DialogInterface
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.extensions.config
import kotlinx.android.synthetic.main.dialog_change_sorting.view.*
-class ChangeSortingDialog(val activity: SimpleActivity, val isDirectorySorting: Boolean, showFolderCheckbox: Boolean,
+class ChangeSortingDialog(val activity: BaseSimpleActivity, val isDirectorySorting: Boolean, showFolderCheckbox: Boolean,
val path: String = "", val callback: () -> Unit) :
DialogInterface.OnClickListener {
private var currSorting = 0
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ExcludeFolderDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ExcludeFolderDialog.kt
index ea386870f..e676fe0ad 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ExcludeFolderDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ExcludeFolderDialog.kt
@@ -5,15 +5,15 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.RadioButton
import android.widget.RadioGroup
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.getBasePath
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.extensions.config
import kotlinx.android.synthetic.main.dialog_exclude_folder.view.*
-class ExcludeFolderDialog(val activity: SimpleActivity, val selectedPaths: List, val callback: () -> Unit) {
+class ExcludeFolderDialog(val activity: BaseSimpleActivity, val selectedPaths: List, val callback: () -> Unit) {
val alternativePaths = getAlternativePathsList()
var radioGroup: RadioGroup? = null
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt
index f99fc98c3..ce20eae97 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/FilterMediaDialog.kt
@@ -3,16 +3,16 @@ package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.GIFS
import com.simplemobiletools.gallery.helpers.IMAGES
import com.simplemobiletools.gallery.helpers.VIDEOS
import kotlinx.android.synthetic.main.dialog_filter_media.view.*
-class FilterMediaDialog(val activity: SimpleActivity, val callback: (result: Int) -> Unit) {
+class FilterMediaDialog(val activity: BaseSimpleActivity, val callback: (result: Int) -> Unit) {
private var view: View = LayoutInflater.from(activity).inflate(R.layout.dialog_filter_media, null)
init {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ManageExtendedDetailsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ManageExtendedDetailsDialog.kt
index 3d8c5e3a7..bbc70402a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ManageExtendedDetailsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ManageExtendedDetailsDialog.kt
@@ -3,6 +3,7 @@ package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.SimpleActivity
@@ -10,7 +11,7 @@ import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.*
import kotlinx.android.synthetic.main.dialog_manage_extended_details.view.*
-class ManageExtendedDetailsDialog(val activity: SimpleActivity, val callback: (result: Int) -> Unit) {
+class ManageExtendedDetailsDialog(val activity: BaseSimpleActivity, val callback: (result: Int) -> Unit) {
private var view: View = LayoutInflater.from(activity).inflate(R.layout.dialog_manage_extended_details, null)
init {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt
index e72a3395c..937f98e07 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickDirectoryDialog.kt
@@ -3,15 +3,16 @@ package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.support.v7.widget.GridLayoutManager
import android.view.LayoutInflater
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.beGoneIf
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.adapters.DirectoryAdapter
import com.simplemobiletools.gallery.asynctasks.GetDirectoriesAsynctask
+import com.simplemobiletools.gallery.extensions.addTempFolderIfNeeded
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.getCachedDirectories
import com.simplemobiletools.gallery.extensions.getSortedDirectories
@@ -19,7 +20,7 @@ import com.simplemobiletools.gallery.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.models.Directory
import kotlinx.android.synthetic.main.dialog_directory_picker.view.*
-class PickDirectoryDialog(val activity: SimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) {
+class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) {
var dialog: AlertDialog
var shownDirectories = ArrayList()
var view = LayoutInflater.from(activity).inflate(R.layout.dialog_directory_picker, null)
@@ -62,8 +63,8 @@ class PickDirectoryDialog(val activity: SimpleActivity, val sourcePath: String,
return
shownDirectories = dirs
- val adapter = DirectoryAdapter(activity, dirs, null, true) {
- if (it.path.trimEnd('/') == sourcePath) {
+ val adapter = DirectoryAdapter(activity, dirs, null, view.directories_grid, true) {
+ if ((it as Directory).path.trimEnd('/') == sourcePath) {
activity.toast(R.string.source_and_destination_same)
return@DirectoryAdapter
} else {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt
index 3596a6907..ad579e02c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/PickMediumDialog.kt
@@ -3,11 +3,11 @@ package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.support.v7.widget.GridLayoutManager
import android.view.LayoutInflater
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.beGoneIf
import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.adapters.MediaAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.extensions.config
@@ -16,7 +16,7 @@ import com.simplemobiletools.gallery.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.dialog_medium_picker.view.*
-class PickMediumDialog(val activity: SimpleActivity, val path: String, val callback: (path: String) -> Unit) {
+class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val callback: (path: String) -> Unit) {
var dialog: AlertDialog
var shownMedia = ArrayList()
val view = LayoutInflater.from(activity).inflate(R.layout.dialog_medium_picker, null)
@@ -58,8 +58,8 @@ class PickMediumDialog(val activity: SimpleActivity, val path: String, val callb
return
shownMedia = media
- val adapter = MediaAdapter(activity, media, null, true, false) {
- callback(it.path)
+ val adapter = MediaAdapter(activity, media, null, true, false, view.media_grid) {
+ callback((it as Medium).path)
dialog.dismiss()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ResizeDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ResizeDialog.kt
index c82c5fdce..cc2e9432f 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ResizeDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/ResizeDialog.kt
@@ -7,14 +7,14 @@ import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.WindowManager
import android.widget.EditText
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.extensions.value
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import kotlinx.android.synthetic.main.resize_image.view.*
-class ResizeDialog(val activity: SimpleActivity, val size: Point, val callback: (newSize: Point) -> Unit) {
+class ResizeDialog(val activity: BaseSimpleActivity, val size: Point, val callback: (newSize: Point) -> Unit) {
init {
val view = LayoutInflater.from(activity).inflate(R.layout.resize_image, null)
val widthView = view.image_width
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 f97e2fb99..4a401e289 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SaveAsDialog.kt
@@ -3,15 +3,15 @@ package com.simplemobiletools.gallery.dialogs
import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.WindowManager
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.R
-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 appendFilename: Boolean, val callback: (savePath: String) -> Unit) {
+class SaveAsDialog(val activity: BaseSimpleActivity, val path: String, val appendFilename: Boolean, val callback: (savePath: String) -> Unit) {
init {
var realPath = File(path).parent.trimEnd('/')
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SlideshowDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SlideshowDialog.kt
index 493e8a980..e9dc60b49 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SlideshowDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/dialogs/SlideshowDialog.kt
@@ -4,16 +4,16 @@ import android.support.v7.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.hideKeyboard
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.gallery.R
-import com.simplemobiletools.gallery.activities.SimpleActivity
import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.helpers.SLIDESHOW_DEFAULT_INTERVAL
import kotlinx.android.synthetic.main.dialog_slideshow.view.*
-class SlideshowDialog(val activity: SimpleActivity, val callback: () -> Unit) {
+class SlideshowDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
val view: View
init {
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 200b2897b..9910aa225 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/extensions/activity.kt
@@ -14,11 +14,13 @@ import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
+import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
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.dialogs.PickDirectoryDialog
import com.simplemobiletools.gallery.helpers.NOMEDIA
import com.simplemobiletools.gallery.models.Directory
import com.simplemobiletools.gallery.models.Medium
@@ -89,7 +91,7 @@ fun AppCompatActivity.hideSystemUI() {
View.SYSTEM_UI_FLAG_IMMERSIVE
}
-fun SimpleActivity.addNoMedia(path: String, callback: () -> Unit) {
+fun BaseSimpleActivity.addNoMedia(path: String, callback: () -> Unit) {
val file = File(path, NOMEDIA)
if (file.exists())
return
@@ -116,14 +118,14 @@ fun SimpleActivity.addNoMedia(path: String, callback: () -> Unit) {
}
}
-fun SimpleActivity.removeNoMedia(path: String, callback: () -> Unit) {
+fun BaseSimpleActivity.removeNoMedia(path: String, callback: (() -> Unit)? = null) {
val file = File(path, NOMEDIA)
deleteFile(file) {
- callback()
+ callback?.invoke()
}
}
-fun SimpleActivity.toggleFileVisibility(oldFile: File, hide: Boolean, callback: (newFile: File) -> Unit) {
+fun BaseSimpleActivity.toggleFileVisibility(oldFile: File, hide: Boolean, callback: ((newFile: File) -> Unit)? = null) {
val path = oldFile.parent
var filename = oldFile.name
filename = if (hide) {
@@ -133,7 +135,7 @@ fun SimpleActivity.toggleFileVisibility(oldFile: File, hide: Boolean, callback:
}
val newFile = File(path, filename)
renameFile(oldFile, newFile) {
- callback(newFile)
+ callback?.invoke(newFile)
}
}
@@ -158,10 +160,35 @@ fun Activity.loadImage(path: String, target: MySquareImageView, horizontalScroll
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
} catch (e: Exception) {
loadJpg(path, target, cropThumbnails)
+ } catch (e: OutOfMemoryError) {
+ loadJpg(path, target, cropThumbnails)
}
}
}
+fun BaseSimpleActivity.tryCopyMoveFilesTo(files: ArrayList, isCopyOperation: Boolean, callback: () -> Unit) {
+ if (files.isEmpty()) {
+ toast(R.string.unknown_error_occurred)
+ return
+ }
+
+ val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
+ PickDirectoryDialog(this, source) {
+ copyMoveFilesTo(files, source.trimEnd('/'), it, isCopyOperation, true, callback)
+ }
+}
+
+fun BaseSimpleActivity.addTempFolderIfNeeded(dirs: ArrayList): ArrayList {
+ val directories = ArrayList()
+ val tempFolderPath = config.tempFolderPath
+ if (tempFolderPath.isNotEmpty()) {
+ val newFolder = Directory(tempFolderPath, "", tempFolderPath.getFilenameFromPath(), 0, 0, 0, 0L)
+ directories.add(newFolder)
+ }
+ directories.addAll(dirs)
+ return directories
+}
+
fun Activity.loadPng(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
val options = RequestOptions()
.signature(path.getFileSignature())
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 345ca57e4..323731665 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/PhotoFragment.kt
@@ -7,7 +7,6 @@ import android.graphics.Color
import android.graphics.Matrix
import android.graphics.drawable.ColorDrawable
import android.net.Uri
-import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -27,6 +26,7 @@ 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.GlideDecoder
import com.simplemobiletools.gallery.helpers.GlideRotateTransformation
import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
@@ -37,7 +37,9 @@ import java.io.File
import java.io.FileOutputStream
class PhotoFragment : ViewPagerFragment() {
+ private var DEFAULT_DOUBLE_TAP_ZOOM = 5f
private var isFragmentVisible = false
+ private var isFullscreen = false
private var wasInit = false
private var storedShowExtendedDetails = false
private var storedExtendedDetails = 0
@@ -85,6 +87,7 @@ class PhotoFragment : ViewPagerFragment() {
}
}
+ isFullscreen = activity!!.window.decorView.systemUiVisibility and View.SYSTEM_UI_FLAG_FULLSCREEN == View.SYSTEM_UI_FLAG_FULLSCREEN
view.subsampling_view.setOnClickListener { photoClicked() }
view.gif_view.setOnClickListener { photoClicked() }
loadImage()
@@ -131,12 +134,6 @@ class PhotoFragment : ViewPagerFragment() {
private fun photoFragmentVisibilityChanged(isVisible: Boolean) {
if (isVisible) {
addZoomableView()
- } else {
- view.subsampling_view.apply {
- recycle()
- beGone()
- background = ColorDrawable(Color.TRANSPARENT)
- }
}
}
@@ -224,9 +221,10 @@ class PhotoFragment : ViewPagerFragment() {
}
private fun addZoomableView() {
- if ((medium.isImage()) && isFragmentVisible && view.subsampling_view.visibility == View.GONE) {
+ if ((medium.isImage()) && isFragmentVisible && view.subsampling_view.isGone()) {
+ ViewPagerActivity.wasDecodedByGlide = false
view.subsampling_view.apply {
- //setBitmapDecoderClass(GlideDecoder::class.java) // causing random crashes on Android 7+, at rotating
+ setBitmapDecoderClass(GlideDecoder::class.java)
maxScale = 10f
beVisible()
setImage(ImageSource.uri(medium.path))
@@ -268,20 +266,28 @@ class PhotoFragment : ViewPagerFragment() {
val height = bitmapOptions.outHeight
val bitmapAspectRatio = height / (width).toFloat()
- if (context == null)
- return 2f
-
- return if (context!!.portrait && bitmapAspectRatio <= 1f) {
+ return if (context == null) {
+ DEFAULT_DOUBLE_TAP_ZOOM
+ } else if (ViewPagerActivity.screenHeight / ViewPagerActivity.screenWidth.toFloat() == bitmapAspectRatio) {
+ DEFAULT_DOUBLE_TAP_ZOOM
+ } else if (ViewPagerActivity.wasDecodedByGlide) {
+ 1f
+ } else if (context!!.portrait && bitmapAspectRatio <= 1f) {
ViewPagerActivity.screenHeight / height.toFloat()
+ } else if (context!!.portrait && bitmapAspectRatio > 1f) {
+ ViewPagerActivity.screenHeight / width.toFloat()
} else if (!context!!.portrait && bitmapAspectRatio >= 1f) {
ViewPagerActivity.screenWidth / width.toFloat()
+ } else if (!context!!.portrait && bitmapAspectRatio < 1f) {
+ ViewPagerActivity.screenWidth / height.toFloat()
} else {
- 2f
+ DEFAULT_DOUBLE_TAP_ZOOM
}
}
fun rotateImageViewBy(degrees: Float) {
- view.subsampling_view.beGone()
+ // do not make Subsampling view Gone, because it gets recycled and can crash with "Error, cannot access an invalid/free'd bitmap here!"
+ view.subsampling_view.beInvisible()
loadBitmap(degrees)
}
@@ -292,9 +298,8 @@ class PhotoFragment : ViewPagerFragment() {
setTextColor(context.config.textColor)
beVisibleIf(text.isNotEmpty())
onGlobalLayout {
- if (height != 0) {
- val smallMargin = resources.getDimension(R.dimen.small_margin)
- y = context.usableScreenSize.y - height - if (context.navigationBarHeight == 0) smallMargin else 0f
+ if (height != 0 && isAdded) {
+ y = getExtendedDetailsY(height)
}
}
}
@@ -305,7 +310,7 @@ class PhotoFragment : ViewPagerFragment() {
override fun onDestroyView() {
super.onDestroyView()
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && !activity!!.isDestroyed) {
+ if (activity?.isActivityDestroyed() == false) {
Glide.with(context).clear(view.gif_view)
}
}
@@ -321,13 +326,17 @@ class PhotoFragment : ViewPagerFragment() {
}
override fun fullscreenToggled(isFullscreen: Boolean) {
+ this.isFullscreen = isFullscreen
view.photo_details.apply {
- if (visibility == View.VISIBLE) {
- val smallMargin = resources.getDimension(R.dimen.small_margin)
- val fullscreenOffset = context.navigationBarHeight.toFloat() - smallMargin
- val newY = context.usableScreenSize.y - height + if (isFullscreen) fullscreenOffset else -(if (context.navigationBarHeight == 0) smallMargin else 0f)
- animate().y(newY)
+ if (isVisible()) {
+ animate().y(getExtendedDetailsY(height))
}
}
}
+
+ private fun getExtendedDetailsY(height: Int): Float {
+ val smallMargin = resources.getDimension(R.dimen.small_margin)
+ val fullscreenOffset = context!!.navigationBarHeight.toFloat() - smallMargin
+ return context!!.usableScreenSize.y - height + if (isFullscreen) fullscreenOffset else -(if (context!!.navigationBarHeight == 0) smallMargin else 0f)
+ }
}
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 e6433e246..423ecd1ea 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/fragments/VideoFragment.kt
@@ -34,6 +34,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
private var mCurrTimeView: TextView? = null
private var mTimerHandler: Handler? = null
private var mSeekBar: SeekBar? = null
+ private var mTimeHolder: View? = null
private var mIsPlaying = false
private var mIsDragged = false
@@ -60,7 +61,6 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
lateinit var mView: View
lateinit var medium: Medium
- lateinit var mTimeHolder: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.pager_video_item, container, false)
@@ -287,8 +287,8 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
private fun initTimeHolder() {
val res = resources
val height = context!!.navigationBarHeight
- val left = mTimeHolder.paddingLeft
- val top = mTimeHolder.paddingTop
+ val left = mTimeHolder!!.paddingLeft
+ val top = mTimeHolder!!.paddingTop
var right = res.getDimension(R.dimen.timer_padding).toInt()
var bottom = 0
@@ -299,7 +299,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
right += height
bottom += context!!.navigationBarHeight
}
- mTimeHolder.setPadding(left, top, right, bottom)
+ mTimeHolder!!.setPadding(left, top, right, bottom)
}
mCurrTimeView = mView.video_curr_time
@@ -307,7 +307,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
mSeekBar!!.setOnSeekBarChangeListener(this)
if (mIsFullscreen)
- mTimeHolder.beInvisible()
+ mTimeHolder!!.beInvisible()
}
private fun hasNavBar(): Boolean {
@@ -375,7 +375,7 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
AnimationUtils.loadAnimation(activity, anim).apply {
duration = 150
fillAfter = true
- mTimeHolder.startAnimation(this)
+ mTimeHolder?.startAnimation(this)
}
}
@@ -457,9 +457,13 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
releaseMediaPlayer()
mSeekBar?.progress = 0
mTimerHandler?.removeCallbacksAndMessages(null)
+ mSurfaceView = null
+ mSurfaceHolder?.removeCallback(this)
+ mSurfaceHolder = null
}
private fun releaseMediaPlayer() {
+ mMediaPlayer?.setSurface(null)
mMediaPlayer?.release()
mMediaPlayer = null
}
@@ -551,10 +555,8 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
setTextColor(context.config.textColor)
beVisibleIf(text.isNotEmpty())
onGlobalLayout {
- if (height != 0) {
- val smallMargin = resources.getDimension(R.dimen.small_margin)
- val timeHolderHeight = mTimeHolder.height - context.navigationBarHeight
- y = context.usableScreenSize.y - height - timeHolderHeight - if (context.navigationBarHeight == 0) smallMargin else 0f
+ if (height != 0 && isAdded) {
+ y = getExtendedDetailsY(height)
}
}
}
@@ -592,13 +594,16 @@ class VideoFragment : ViewPagerFragment(), SurfaceHolder.Callback, SeekBar.OnSee
mIsFullscreen = isFullscreen
checkFullscreen()
mView.video_details.apply {
- if (visibility == View.VISIBLE) {
- val smallMargin = resources.getDimension(R.dimen.small_margin)
- val timeHolderHeight = mTimeHolder.height - context.navigationBarHeight.toFloat()
- val fullscreenOffset = context.navigationBarHeight.toFloat() - smallMargin
- val newY = context.usableScreenSize.y - height + if (mIsFullscreen) fullscreenOffset else -(timeHolderHeight + if (context.navigationBarHeight == 0) smallMargin else 0f)
- animate().y(newY)
+ if (isVisible()) {
+ animate().y(getExtendedDetailsY(height))
}
}
}
+
+ private fun getExtendedDetailsY(height: Int): Float {
+ val smallMargin = resources.getDimension(R.dimen.small_margin)
+ val timeHolderHeight = mTimeHolder!!.height - context!!.navigationBarHeight.toFloat()
+ val fullscreenOffset = context!!.navigationBarHeight.toFloat() - smallMargin
+ return context!!.usableScreenSize.y - height + if (mIsFullscreen) fullscreenOffset else -(timeHolderHeight + if (context!!.navigationBarHeight == 0) smallMargin else 0f)
+ }
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/GlideDecoder.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/GlideDecoder.kt
index 78ea3c9dc..55e12722a 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/GlideDecoder.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/GlideDecoder.kt
@@ -23,6 +23,7 @@ class GlideDecoder : ImageDecoder {
val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth
val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight
+ ViewPagerActivity.wasDecodedByGlide = true
val options = RequestOptions()
.signature(uri.path.getFileSignature())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt
index c42db1b4e..cce57aa36 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/helpers/MediaFetcher.kt
@@ -247,7 +247,6 @@ class MediaFetcher(val context: Context) {
private fun isThisOrParentExcluded(path: String, excludedPaths: MutableSet, includedPaths: MutableSet) =
includedPaths.none { path.startsWith(it) } && excludedPaths.any { path.startsWith(it) }
-
private fun getMediaInFolder(folder: String, curMedia: ArrayList, isPickImage: Boolean, isPickVideo: Boolean, filterMedia: Int) {
val files = File(folder).listFiles() ?: return
for (file in files) {
@@ -282,7 +281,7 @@ class MediaFetcher(val context: Context) {
val isAlreadyAdded = curMedia.any { it.path == file.absolutePath }
if (!isAlreadyAdded) {
curMedia.add(medium)
- context.scanPath(file.absolutePath) {}
+ context.scanPath(file.absolutePath)
}
}
}
@@ -296,10 +295,11 @@ class MediaFetcher(val context: Context) {
else -> MediaStore.Images.Media.DATE_TAKEN
}
- return if (sorting and SORT_DESCENDING > 0)
+ return if (sorting and SORT_DESCENDING > 0) {
"$sortValue DESC"
- else
+ } else {
"$sortValue ASC"
+ }
}
private fun getNoMediaFolders(): ArrayList {
diff --git a/app/src/main/res/layout/activity_excluded_folders.xml b/app/src/main/res/layout/activity_excluded_folders.xml
deleted file mode 100644
index 64df37244..000000000
--- a/app/src/main/res/layout/activity_excluded_folders.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_included_folders.xml b/app/src/main/res/layout/activity_included_folders.xml
deleted file mode 100644
index 527cdd94a..000000000
--- a/app/src/main/res/layout/activity_included_folders.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 9432206a7..073f3fd19 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -33,7 +33,7 @@
android:text="@string/change_filters_underlined"
android:visibility="gone"/>
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_media.xml b/app/src/main/res/layout/activity_media.xml
index 94422b430..95bc05417 100644
--- a/app/src/main/res/layout/activity_media.xml
+++ b/app/src/main/res/layout/activity_media.xml
@@ -33,7 +33,7 @@
android:text="@string/change_filters_underlined"
android:visibility="gone"/>
-
-
-
+ android:src="@drawable/ic_check"
+ android:visibility="gone"/>
+ android:src="@drawable/ic_pin"
+ android:visibility="gone"/>
+ android:src="@drawable/ic_check"
+ android:visibility="gone"/>
-
-
+ android:layout_marginTop="@dimen/medium_margin"/>
diff --git a/app/src/main/res/layout/photo_video_item_grid.xml b/app/src/main/res/layout/photo_video_item_grid.xml
index a8fdf5d21..4ec84403d 100644
--- a/app/src/main/res/layout/photo_video_item_grid.xml
+++ b/app/src/main/res/layout/photo_video_item_grid.xml
@@ -4,6 +4,8 @@
android:id="@+id/media_item_holder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:clickable="true"
+ android:focusable="true"
android:padding="1px">
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index f4091292b..07b53a1c9 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,5 +1,5 @@
-
-
+
+
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
index f4091292b..07b53a1c9 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
-
+
+
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 0a90b0dcd..9676c7754 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -23,8 +23,8 @@
Lautstärke
Helligkeit
Nicht erneut fragen (in dieser Sitzung)
- Lock orientation
- Unlock orientation
+ Bildschirmausrichtung sperren
+ Bildschirmausrichtung entsperren
Filter
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 7f9f0e294..3498ff272 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -23,8 +23,8 @@
Volume
Luminosità
Non chiedere nuovamente in questa sessione
- Lock orientation
- Unlock orientation
+ Blocca orientamento
+ Sblocca orientamento
Filtra i media
@@ -115,7 +115,7 @@
Anima le GIF in miniatura
Luminosità max durante visualizzazione
Ritaglia le miniature in quadrati
- Ruota a schermo intero per
+ Ruota schermo per
Impostazione di sistema
Rotazione dispositivo
Proporzioni
@@ -133,7 +133,7 @@
Una galleria per visualizzare foto e video senza pubblicità.
- Un semplice strumento per visualizzare foto e video. Gli elementi possono essere ordinati per data, dimensioni, nome sia ascendente che discendente; le foto possono essere ingrandite. I file sono mostrati in colonne multiple a seconda delle dimensioni dello schermo, puoi modificare il numero di colonne con il tocco. Possono essere rinominate, condivise, eliminate, copiate, spostate. Le immagini possono anche essere ritagliate, ruotate o impostate come sfondo direttamente dall\'app.
+ Un semplice strumento per visualizzare foto e video. Gli elementi possono essere ordinati per data, dimensioni, nome sia ascendente che discendente; le foto possono essere ingrandite. I file sono mostrati in colonne multiple a seconda delle dimensioni dello schermo, puoi modificare il numero di colonne con il tocco. Possono essere rinominate, condivise, eliminate, copiate, spostate. Le immagini possono anche essere ritagliate, ruotate o impostate come sfondo direttamente dalla app.
Simple Gallery è anche offerta per utilizzo di terze parti per anteprime di immagini / video, aggiunta di allegati ai client email, ecc. È perfetta per un uso quotidiano.
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 1f49212f3..bbd0a82dd 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -27,12 +27,12 @@
Schermrotatie ontgrendelen
- Media kiezen
+ Filter media
Afbeeldingen
Video\'s
GIF-bestanden
Geen bestanden gevonden met de huidige filters.
- Media kiezen
+ Filters aanpassen
Deze functie verbergt de map door het bestand \'.nomedia\' toe te voegen. Alle submappen zullen ook worden verborgen. Kies \'Verborgen mappen tonen\' in de instellingen om toch verborgen mappen te kunnen inzien. Doorgaan?
@@ -46,8 +46,8 @@
Verwijder alles uit de lijst van uitgesloten mappen? Dit zal de mappen zelf niet verwijderen.
- Ingesloten mappen
- Ingesloten mappen beheren
+ Toegevoegde mappen
+ Toegevoegde mappen beheren
Map toevoegen
Als er mappen zijn die wel media bevatten, maar niet niet door de galerij worden herkend, voeg deze mappen dan hier handmatig toe.\n\nHet hier toevoegen van mappen zal andere mappen niet uitsluiten.
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index c6b18239b..eb749c168 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -1,7 +1,7 @@
- Simple Gallery
- Simple Gallery
+ Prosta Galeria
+ Galeria
Edytuj
Uruchom aplikację aparatu
(ukryty)
@@ -23,8 +23,8 @@
Głośność
Jasność
Nie pytaj więcej w tej sesji
- Lock orientation
- Unlock orientation
+ Zablokuj orientację ekranu
+ Odblokuj orientację ekranu
Filtruj multimedia
@@ -35,7 +35,7 @@
Zmień filtry
- Ta funkcja ukrywa foldery dodając do nich pusty plik .nomedia. Aby móc je zobaczyć, należy włączyć opcję \'Pokazuj ukryte foldery\' w ustawieniach. Kontyntynuować?
+ Ta funkcja ukrywa foldery, dodając do nich pusty plik .nomedia. Aby móc je zobaczyć, należy włączyć opcję \'Pokazuj ukryte foldery\' w ustawieniach. Kontynuować?
Wyklucz
Wykluczone foldery
Zarządzaj wykluczonymi folderami
@@ -49,7 +49,7 @@
Dołączone foldery
Zarządzaj dołączonymi folderami
Dodaj folder
- Jeśli masz jakieś foldery z multimediami, ale aplikacja ich nie wykryła, możesz je tutaj dodać ręcznie.
+ Jeśli masz jakieś foldery z multimediami, ale aplikacja ich nie wykryła, możesz je dodać ręcznie tutaj.
Zmień rozmiar
@@ -131,13 +131,13 @@
- Darmowa galeria bez reklam do przeglądania obrazów i filmów.
+ Prosta galeria bez reklam do przeglądania obrazów i filmów.
- Prosta aplikacja galerii do oglądania obrazów i filmów. Pliki mogą być sortowane według daty, rozmiaru i nazwy, zarówno w porządku rosnącym, jak i malejącym. W zależności od wielkości ekranu wyświetlane mogą być w wielu kolumnach. Liczbę kolumn można zmieniać za pomocą gestów. Zdjęcia mogą być powiększane, przycinane, obracane lub ustawiane jako tapeta bezpośrednio z poziomu aplikacji. Kolory aplikacji można dowolnie ustawiać.
+ Prosta aplikacja galerii do oglądania obrazów i filmów. Pliki mogą być sortowane według daty, rozmiaru i nazwy, zarówno w porządku rosnącym, jak i malejącym. W zależności od wielkości ekranu, wyświetlane mogą być w wielu kolumnach. Liczbę kolumn można zmieniać za pomocą gestów, a zdjęcia mogą być powiększane, przycinane, obracane lub ustawiane jako tapeta bezpośrednio z poziomu Prostej Galerii. Kolory aplikacji można dowolnie ustawiać.
- Aplikacja nie zawiera żadnych reklam ani niepotrzebnych uprawnień. Jest też w pełni otawrtoźrodłowa.
-
- Niniejsza aplikacja jest tylko częścią naszego zestawu prostych aplikacji. Znajdziecie je na stronie http://www.simplemobiletools.com.
+ Nie zawiera natomiast żadnych reklam i nie potrzebuje całej masy uprawnień. Jest w pełni otwartoźródłowa i w pełni podatna na kolorowanie.
+
+ Niniejsza aplikacja jest tylko częścią naszej kolekcji prostych narzędzi. Ta, jak i pozostałe, dostępne są na stronie http://www.simplemobiletools.com
要显示的媒体文件
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index ee1e5614a..8cb25a2bb 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -7,6 +7,4 @@
@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 a8c998266..5475edd14 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -2,6 +2,9 @@
+
+ Added new options to use english language on non-english devices, to password protect whole app and to lock screen orientation at fullscreen view
+
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