commit
5ac1fdb787
16
CHANGELOG.md
16
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)*
|
||||
----------------------------
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.simplemobiletools.gallery
|
||||
|
||||
import android.app.Application
|
||||
import android.support.multidex.MultiDexApplication
|
||||
import com.github.ajalt.reprint.core.Reprint
|
||||
import com.simplemobiletools.gallery.BuildConfig.USE_LEAK_CANARY
|
||||
import com.simplemobiletools.gallery.extensions.config
|
||||
import com.squareup.leakcanary.LeakCanary
|
||||
import java.util.*
|
||||
|
||||
class App : Application() {
|
||||
class App : MultiDexApplication() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (USE_LEAK_CANARY) {
|
||||
|
|
|
@ -1,45 +1,33 @@
|
|||
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.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_excluded_folders.*
|
||||
import kotlinx.android.synthetic.main.item_manage_folder.view.*
|
||||
import kotlinx.android.synthetic.main.activity_manage_folders.*
|
||||
|
||||
class ExcludedFoldersActivity : SimpleActivity() {
|
||||
class ExcludedFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_excluded_folders)
|
||||
setContentView(R.layout.activity_manage_folders)
|
||||
updateExcludedFolders()
|
||||
}
|
||||
|
||||
private fun updateExcludedFolders() {
|
||||
excluded_folders_holder.removeAllViews()
|
||||
val folders = config.excludedFolders
|
||||
excluded_folders_placeholder.beVisibleIf(folders.isEmpty())
|
||||
excluded_folders_placeholder.setTextColor(config.textColor)
|
||||
val folders = ArrayList<String>()
|
||||
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)
|
||||
|
|
|
@ -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<String>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Medium>()
|
||||
|
@ -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<String>) {
|
||||
Intent().apply {
|
||||
putExtra(PICKED_PATHS, paths)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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<File>, 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<Directory>): ArrayList<Directory> {
|
||||
val directories = ArrayList<Directory>()
|
||||
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()
|
||||
|
|
|
@ -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<Medium>) {
|
||||
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() {
|
||||
|
|
|
@ -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<Directory>, val listener: DirOperationsListener?, val isPickIntent: Boolean,
|
||||
val itemClick: (Directory) -> Unit) : RecyclerView.Adapter<DirectoryAdapter.ViewHolder>() {
|
||||
class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: MutableList<Directory>, 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<View>()
|
||||
private val selectedPositions = HashSet<Int>()
|
||||
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<Int> = 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<Direc
|
|||
RenameItemDialog(activity, dir.absolutePath) {
|
||||
activity.runOnUiThread {
|
||||
listener?.refreshItems()
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,14 +178,14 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
|
|||
private fun tryExcludeFolder() {
|
||||
ExcludeFolderDialog(activity, getSelectedPaths().toList()) {
|
||||
listener?.refreshItems()
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
||||
private fun noMediaHandled() {
|
||||
activity.runOnUiThread {
|
||||
listener?.refreshItems()
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,7 +199,7 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
|
|||
pinnedFolders = config.pinnedFolders
|
||||
listener?.recheckPinnedFolders()
|
||||
notifyDataSetChanged()
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
}
|
||||
|
||||
private fun copyMoveTo(isCopyOperation: Boolean) {
|
||||
|
@ -248,19 +215,10 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
|
|||
activity.tryCopyMoveFilesTo(files, isCopyOperation) {
|
||||
config.tempFolderPath = ""
|
||||
listener?.refreshItems()
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
||||
fun selectAll() {
|
||||
val cnt = dirs.size
|
||||
for (i in 0 until cnt) {
|
||||
selectedPositions.add(i)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
updateTitle(cnt)
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(activity) {
|
||||
deleteFiles()
|
||||
|
@ -302,7 +260,8 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
|
|||
.forEachIndexed { curIndex, i -> 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<Direc
|
|||
|
||||
private fun storeCovers(albumCovers: ArrayList<AlbumCover>) {
|
||||
activity.config.albumCovers = Gson().toJson(albumCovers)
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
listener?.refreshItems()
|
||||
}
|
||||
|
||||
|
@ -347,30 +306,18 @@ class DirectoryAdapter(val activity: SimpleActivity, var dirs: MutableList<Direc
|
|||
return paths
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
|
||||
val layoutType = if (isListViewType) R.layout.directory_item_list else R.layout.directory_item_grid
|
||||
val view = LayoutInflater.from(parent?.context).inflate(layoutType, parent, false)
|
||||
return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, isPickIntent, itemClick)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val dir = dirs[position]
|
||||
itemViews.put(position, holder.bindView(dir, pinnedFolders.contains(dir.path), scrollHorizontally, isListViewType, textColor, showMediaCount, 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?.dir_thumbnail)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = dirs.size
|
||||
|
||||
fun updateDirs(newDirs: ArrayList<Directory>) {
|
||||
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<Direc
|
|||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun updateTextColor(textColor: Int) {
|
||||
this.textColor = textColor
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
private fun setupView(view: View, directory: Directory) {
|
||||
view.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(pinnedFolders.contains(directory.path))
|
||||
dir_sd_card.beVisibleIf(activity.isPathOnSD(directory.path))
|
||||
photo_cnt.beVisibleIf(showMediaCount)
|
||||
|
||||
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) {
|
||||
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<Int>
|
||||
}
|
||||
|
||||
interface DirOperationsListener {
|
||||
fun refreshItems()
|
||||
|
||||
fun tryDeleteFolders(folders: ArrayList<File>)
|
||||
|
||||
fun itemLongClicked(position: Int)
|
||||
|
||||
fun recheckPinnedFolders()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<String>, 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<String>(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<View>()
|
||||
(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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Medium>, val listener: MediaOperationsListener?, val isAGetIntent: Boolean,
|
||||
val allowMultiplePicks: Boolean, val itemClick: (Medium) -> Unit) : RecyclerView.Adapter<MediaAdapter.ViewHolder>() {
|
||||
class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Medium>, 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<View>()
|
||||
private val selectedPositions = HashSet<Int>()
|
||||
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<Int> = 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<Medium>,
|
|||
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<Medium>,
|
|||
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<Medium>,
|
|||
val removeMedia = ArrayList<Medium>(selectedPositions.size)
|
||||
|
||||
if (media.size <= selectedPositions.first()) {
|
||||
actMode?.finish()
|
||||
finishActMode()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -257,7 +215,6 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
|
|||
}
|
||||
|
||||
media.removeAll(removeMedia)
|
||||
selectedPositions.clear()
|
||||
listener?.deleteFiles(files)
|
||||
|
||||
val newItems = SparseArray<View>()
|
||||
|
@ -266,7 +223,8 @@ class MediaAdapter(val activity: SimpleActivity, var media: MutableList<Medium>,
|
|||
.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<Medium>,
|
|||
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<Medium>) {
|
||||
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<Medium>,
|
|||
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<Int>
|
||||
}
|
||||
|
||||
interface MediaOperationsListener {
|
||||
fun refreshItems()
|
||||
|
||||
fun deleteFiles(files: ArrayList<File>)
|
||||
|
||||
fun itemLongClicked(position: Int)
|
||||
|
||||
fun selectedPaths(paths: ArrayList<String>)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String>, val callback: () -> Unit) {
|
||||
class ExcludeFolderDialog(val activity: BaseSimpleActivity, val selectedPaths: List<String>, val callback: () -> Unit) {
|
||||
val alternativePaths = getAlternativePathsList()
|
||||
var radioGroup: RadioGroup? = null
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<Directory>()
|
||||
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 {
|
||||
|
|
|
@ -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<Medium>()
|
||||
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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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('/')
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<File>, 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<Directory>): ArrayList<Directory> {
|
||||
val directories = ArrayList<Directory>()
|
||||
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())
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -247,7 +247,6 @@ class MediaFetcher(val context: Context) {
|
|||
private fun isThisOrParentExcluded(path: String, excludedPaths: MutableSet<String>, includedPaths: MutableSet<String>) =
|
||||
includedPaths.none { path.startsWith(it) } && excludedPaths.any { path.startsWith(it) }
|
||||
|
||||
|
||||
private fun getMediaInFolder(folder: String, curMedia: ArrayList<Medium>, 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<String> {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/excluded_folders_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/exclude_folders_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/excluded_folders_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/excluded_folders_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingLeft="@dimen/big_margin"
|
||||
android:paddingRight="@dimen/big_margin"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:text="@string/excluded_activity_placeholder"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/included_folders_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/include_folders_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/included_folders_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/included_folders_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingLeft="@dimen/big_margin"
|
||||
android:paddingRight="@dimen/big_margin"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:text="@string/included_activity_placeholder"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
|
@ -33,7 +33,7 @@
|
|||
android:text="@string/change_filters_underlined"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyScalableRecyclerView
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/directories_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/manage_folders_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/manage_folders_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/manage_folders_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingLeft="@dimen/big_margin"
|
||||
android:paddingRight="@dimen/big_margin"
|
||||
android:paddingTop="@dimen/activity_margin"
|
||||
android:text="@string/excluded_activity_placeholder"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</RelativeLayout>
|
|
@ -33,7 +33,7 @@
|
|||
android:text="@string/change_filters_underlined"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<com.simplemobiletools.commons.views.MyScalableRecyclerView
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/media_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/activity_margin">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyScalableRecyclerView
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/directories_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/activity_margin">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyScalableRecyclerView
|
||||
<com.simplemobiletools.commons.views.MyRecyclerView
|
||||
android:id="@+id/media_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
android:id="@+id/dir_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="1px">
|
||||
|
||||
<com.simplemobiletools.gallery.views.MySquareImageView
|
||||
|
@ -21,7 +23,8 @@
|
|||
android:layout_margin="@dimen/small_margin"
|
||||
android:background="@drawable/circle_background"
|
||||
android:padding="@dimen/tiny_margin"
|
||||
android:src="@drawable/ic_check"/>
|
||||
android:src="@drawable/ic_check"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dir_pin"
|
||||
|
@ -33,7 +36,8 @@
|
|||
android:layout_margin="@dimen/small_margin"
|
||||
android:background="@drawable/circle_black_background"
|
||||
android:padding="@dimen/small_margin"
|
||||
android:src="@drawable/ic_pin"/>
|
||||
android:src="@drawable/ic_pin"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dir_shadow_holder"
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/small_margin"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:paddingTop="@dimen/small_margin">
|
||||
|
||||
<com.simplemobiletools.gallery.views.MySquareImageView
|
||||
|
@ -22,7 +24,8 @@
|
|||
android:layout_margin="@dimen/small_margin"
|
||||
android:background="@drawable/circle_background"
|
||||
android:padding="@dimen/tiny_margin"
|
||||
android:src="@drawable/ic_check"/>
|
||||
android:src="@drawable/ic_check"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dir_name"
|
||||
|
|
|
@ -1,29 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/managed_folder_holder"
|
||||
android:id="@+id/manage_folder_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="@drawable/selector"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/managed_folder_title"
|
||||
android:id="@+id/manage_folder_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/medium_margin"
|
||||
android:layout_marginRight="@dimen/medium_margin"
|
||||
android:layout_toLeftOf="@+id/managed_folders_icon"
|
||||
android:layout_toStartOf="@+id/managed_folders_icon"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/managed_folders_icon"
|
||||
style="@style/MyBorderlessBackgroundStyle"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_cross"/>
|
||||
android:layout_marginTop="@dimen/medium_margin"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -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">
|
||||
|
||||
<com.simplemobiletools.gallery.views.MySquareImageView
|
||||
|
|
|
@ -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:paddingLeft="@dimen/small_margin"
|
||||
android:paddingTop="@dimen/small_margin">
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<background android:drawable="@color/color_primary"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<background android:drawable="@color/color_primary"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<string name="volume">Lautstärke</string>
|
||||
<string name="brightness">Helligkeit</string>
|
||||
<string name="do_not_ask_again">Nicht erneut fragen (in dieser Sitzung)</string>
|
||||
<string name="lock_orientation">Lock orientation</string>
|
||||
<string name="unlock_orientation">Unlock orientation</string>
|
||||
<string name="lock_orientation">Bildschirmausrichtung sperren</string>
|
||||
<string name="unlock_orientation">Bildschirmausrichtung entsperren</string>
|
||||
|
||||
<!-- Filter -->
|
||||
<string name="filter_media">Filter</string>
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<string name="volume">Volume</string>
|
||||
<string name="brightness">Luminosità</string>
|
||||
<string name="do_not_ask_again">Non chiedere nuovamente in questa sessione</string>
|
||||
<string name="lock_orientation">Lock orientation</string>
|
||||
<string name="unlock_orientation">Unlock orientation</string>
|
||||
<string name="lock_orientation">Blocca orientamento</string>
|
||||
<string name="unlock_orientation">Sblocca orientamento</string>
|
||||
|
||||
<!-- Filter -->
|
||||
<string name="filter_media">Filtra i media</string>
|
||||
|
@ -115,7 +115,7 @@
|
|||
<string name="animate_gifs">Anima le GIF in miniatura</string>
|
||||
<string name="max_brightness">Luminosità max durante visualizzazione</string>
|
||||
<string name="crop_thumbnails">Ritaglia le miniature in quadrati</string>
|
||||
<string name="screen_rotation_by">Ruota a schermo intero per</string>
|
||||
<string name="screen_rotation_by">Ruota schermo per</string>
|
||||
<string name="screen_rotation_system_setting">Impostazione di sistema</string>
|
||||
<string name="screen_rotation_device_rotation">Rotazione dispositivo</string>
|
||||
<string name="screen_rotation_aspect_ratio">Proporzioni</string>
|
||||
|
@ -133,7 +133,7 @@
|
|||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Una galleria per visualizzare foto e video senza pubblicità.</string>
|
||||
<string name="app_long_description">
|
||||
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.
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
<string name="unlock_orientation">Schermrotatie ontgrendelen</string>
|
||||
|
||||
<!-- Filter -->
|
||||
<string name="filter_media">Media kiezen</string>
|
||||
<string name="filter_media">Filter media</string>
|
||||
<string name="images">Afbeeldingen</string>
|
||||
<string name="videos">Video\'s</string>
|
||||
<string name="gifs">GIF-bestanden</string>
|
||||
<string name="no_media_with_filters">Geen bestanden gevonden met de huidige filters.</string>
|
||||
<string name="change_filters_underlined"><u>Media kiezen</u></string>
|
||||
<string name="change_filters_underlined"><u>Filters aanpassen</u></string>
|
||||
|
||||
<!-- Hide / Exclude -->
|
||||
<string name="hide_folder_description">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?</string>
|
||||
|
@ -46,8 +46,8 @@
|
|||
<string name="remove_all_description">Verwijder alles uit de lijst van uitgesloten mappen? Dit zal de mappen zelf niet verwijderen.</string>
|
||||
|
||||
<!-- Include folders -->
|
||||
<string name="include_folders">Ingesloten mappen</string>
|
||||
<string name="manage_included_folders">Ingesloten mappen beheren</string>
|
||||
<string name="include_folders">Toegevoegde mappen</string>
|
||||
<string name="manage_included_folders">Toegevoegde mappen beheren</string>
|
||||
<string name="add_folder">Map toevoegen</string>
|
||||
<string name="included_activity_placeholder">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.</string>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Simple Gallery</string>
|
||||
<string name="app_launcher_name">Simple Gallery</string>
|
||||
<string name="app_name">Prosta Galeria</string>
|
||||
<string name="app_launcher_name">Galeria</string>
|
||||
<string name="edit">Edytuj</string>
|
||||
<string name="open_camera">Uruchom aplikację aparatu</string>
|
||||
<string name="hidden">(ukryty)</string>
|
||||
|
@ -23,8 +23,8 @@
|
|||
<string name="volume">Głośność</string>
|
||||
<string name="brightness">Jasność</string>
|
||||
<string name="do_not_ask_again">Nie pytaj więcej w tej sesji</string>
|
||||
<string name="lock_orientation">Lock orientation</string>
|
||||
<string name="unlock_orientation">Unlock orientation</string>
|
||||
<string name="lock_orientation">Zablokuj orientację ekranu</string>
|
||||
<string name="unlock_orientation">Odblokuj orientację ekranu</string>
|
||||
|
||||
<!-- Filter -->
|
||||
<string name="filter_media">Filtruj multimedia</string>
|
||||
|
@ -35,7 +35,7 @@
|
|||
<string name="change_filters_underlined"><u>Zmień filtry</u></string>
|
||||
|
||||
<!-- Hide / Exclude -->
|
||||
<string name="hide_folder_description">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ć?</string>
|
||||
<string name="hide_folder_description">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ć?</string>
|
||||
<string name="exclude">Wyklucz</string>
|
||||
<string name="excluded_folders">Wykluczone foldery</string>
|
||||
<string name="manage_excluded_folders">Zarządzaj wykluczonymi folderami</string>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<string name="include_folders">Dołączone foldery</string>
|
||||
<string name="manage_included_folders">Zarządzaj dołączonymi folderami</string>
|
||||
<string name="add_folder">Dodaj folder</string>
|
||||
<string name="included_activity_placeholder">Jeśli masz jakieś foldery z multimediami, ale aplikacja ich nie wykryła, możesz je tutaj dodać ręcznie.</string>
|
||||
<string name="included_activity_placeholder">Jeśli masz jakieś foldery z multimediami, ale aplikacja ich nie wykryła, możesz je dodać ręcznie tutaj.</string>
|
||||
|
||||
<!-- Resizing -->
|
||||
<string name="resize">Zmień rozmiar</string>
|
||||
|
@ -131,13 +131,13 @@
|
|||
|
||||
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
|
||||
<!-- Short description has to have less than 80 chars -->
|
||||
<string name="app_short_description">Darmowa galeria bez reklam do przeglądania obrazów i filmów.</string>
|
||||
<string name="app_short_description">Prosta galeria bez reklam do przeglądania obrazów i filmów.</string>
|
||||
<string name="app_long_description">
|
||||
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
|
||||
</string>
|
||||
|
||||
<!--
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
<string name="volume">音量</string>
|
||||
<string name="brightness">亮度</string>
|
||||
<string name="do_not_ask_again">不再提醒</string>
|
||||
<string name="lock_orientation">Lock orientation</string>
|
||||
<string name="unlock_orientation">Unlock orientation</string>
|
||||
<string name="lock_orientation">锁定方向</string>
|
||||
<string name="unlock_orientation">解锁方向</string>
|
||||
|
||||
<!-- Filter -->
|
||||
<string name="filter_media">要显示的媒体文件</string>
|
||||
|
|
|
@ -7,6 +7,4 @@
|
|||
<!-- Default colors -->
|
||||
<color name="default_text_color">@color/default_dark_theme_text_color</color>
|
||||
<color name="default_background_color">@color/default_dark_theme_background_color</color>
|
||||
|
||||
<color name="ic_launcher_background">@color/color_primary</color>
|
||||
</resources>
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
<resources>
|
||||
|
||||
<!-- Release notes -->
|
||||
<string name="release_143">
|
||||
Added new options to use english language on non-english devices, to password protect whole app and to lock screen orientation at fullscreen view
|
||||
</string>
|
||||
<string name="release_138">Added an option to keep last-modified field at file copy/move/rename</string>
|
||||
<string name="release_137">Added an option to hide folder media count on the main screen</string>
|
||||
<string name="release_136">Added an option to show customizable extended details over fullscreen media</string>
|
||||
|
|
Loading…
Reference in New Issue