diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2aa135e11..522324963 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,23 @@
Changelog
==========
+Version 6.8.2 *(2019-07-02)*
+----------------------------
+
+ * Allow password protecting individual folders
+ * Let's try using dark theme menu
+ * Fixed the performance of scrolling GIF thumbnails
+ * Fixed some video stucking issues
+ * Some other stability and translation improvements
+
+Version 6.8.1 *(2019-06-27)*
+----------------------------
+
+ * Improved Search on the main screen, allow using it for searching all files, not folders
+ * Added Print functionality at fullscreen images
+ * Fixed a glitch at PNGs getting deleted after rotating
+ * Other stability, translation and performance improvements
+
Version 6.8.0 *(2019-06-21)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index eb5bc1b49..9b4abdd3b 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
applicationId "com.simplemobiletools.gallery.pro"
minSdkVersion 21
targetSdkVersion 28
- versionCode 254
- versionName "6.8.0"
+ versionCode 256
+ versionName "6.8.2"
multiDexEnabled true
setProperty("archivesBaseName", "gallery")
}
@@ -61,7 +61,7 @@ android {
}
dependencies {
- implementation 'com.simplemobiletools:commons:5.14.0'
+ implementation 'com.simplemobiletools:commons:5.14.18'
implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'it.sephiroth.android.exif:library:1.0.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index aa2a48308..25f4250ff 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,14 +36,6 @@
android:name=".activities.MainActivity"
android:resizeableActivity="true">
-
-
-
-
-
-
@@ -81,6 +73,21 @@
+
+
+
+
+
+
+
+
+
{
val currentFilter = getFiltersAdapter()?.getCurrentFilter()
if (currentFilter == null) {
toast(R.string.unknown_error_occurred)
- return@Thread
+ return@ensureBackgroundThread
}
val originalBitmap = Glide.with(applicationContext).asBitmap().load(uri).submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get()
- currentFilter!!.filter.processFilter(originalBitmap)
+ currentFilter.filter.processFilter(originalBitmap)
shareBitmap(originalBitmap)
}
crop_image_view.isVisible() -> {
@@ -371,12 +368,12 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
}
editor_draw_canvas.isVisible() -> shareBitmap(editor_draw_canvas.getBitmap())
}
- }.start()
+ }
}
private fun getTempImagePath(bitmap: Bitmap, callback: (path: String?) -> Unit) {
val bytes = ByteArrayOutputStream()
- bitmap.compress(Bitmap.CompressFormat.PNG, 0, bytes)
+ bitmap.compress(CompressFormat.PNG, 0, bytes)
val folder = File(cacheDir, TEMP_FOLDER_NAME)
if (!folder.exists()) {
@@ -581,20 +578,27 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_editor_draw_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_DRAW)
if (currPrimaryAction == PRIMARY_ACTION_FILTER && bottom_actions_filter_list.adapter == null) {
- Thread {
+ ensureBackgroundThread {
val thumbnailSize = resources.getDimension(R.dimen.bottom_filters_thumbnail_size).toInt()
- val bitmap = Glide.with(this)
- .asBitmap()
- .load(uri).listener(object : RequestListener {
- override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean {
- showErrorToast(e.toString())
- return false
- }
- override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean) = false
- })
- .submit(thumbnailSize, thumbnailSize)
- .get()
+ val bitmap = try {
+ Glide.with(this)
+ .asBitmap()
+ .load(uri).listener(object : RequestListener {
+ override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean {
+ showErrorToast(e.toString())
+ return false
+ }
+
+ override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean) = false
+ })
+ .submit(thumbnailSize, thumbnailSize)
+ .get()
+ } catch (e: GlideException) {
+ showErrorToast(e)
+ finish()
+ return@ensureBackgroundThread
+ }
runOnUiThread {
val filterThumbnailsManager = FilterThumbnailsManager()
@@ -623,7 +627,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_actions_filter_list.adapter = adapter
adapter.notifyDataSetChanged()
}
- }.start()
+ }
}
if (currPrimaryAction != PRIMARY_ACTION_CROP_ROTATE) {
@@ -804,7 +808,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
private fun saveBitmapToFile(bitmap: Bitmap, path: String, showSavingToast: Boolean) {
try {
- Thread {
+ ensureBackgroundThread {
val file = File(path)
val fileDirItem = FileDirItem(path, path.getFilenameFromPath())
getFileOutputStream(fileDirItem, true) {
@@ -814,7 +818,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
toast(R.string.image_editing_failed)
}
}
- }.start()
+ }
} catch (e: Exception) {
showErrorToast(e)
} catch (e: OutOfMemoryError) {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/HiddenFoldersActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/HiddenFoldersActivity.kt
index 98d5eb9d9..a7a5002ba 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/HiddenFoldersActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/HiddenFoldersActivity.kt
@@ -5,6 +5,7 @@ import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.beVisibleIf
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.ManageHiddenFoldersAdapter
@@ -55,11 +56,11 @@ class HiddenFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun addFolder() {
FilePickerDialog(this, config.lastFilepickerPath, false, config.shouldShowHidden, false, true) {
config.lastFilepickerPath = it
- Thread {
+ ensureBackgroundThread {
addNoMedia(it) {
updateFolders()
}
- }.start()
+ }
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt
index 117eda6f8..fb3de0bde 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MainActivity.kt
@@ -1,9 +1,7 @@
package com.simplemobiletools.gallery.pro.activities
import android.app.Activity
-import android.app.SearchManager
import android.content.ClipData
-import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
@@ -14,8 +12,6 @@ import android.view.MenuItem
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.Toast
-import androidx.appcompat.widget.SearchView
-import androidx.core.view.MenuItemCompat
import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.CreateNewFolderDialog
@@ -65,7 +61,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mIsPasswordProtectionPending = false
private var mWasProtectionHandled = false
private var mShouldStopFetching = false
- private var mIsSearchOpen = false
private var mLatestMediaId = 0L
private var mLatestMediaDateId = 0L
private var mCurrentPathPrefix = "" // used at "Group direct subfolders" for navigation
@@ -73,7 +68,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mLastMediaHandler = Handler()
private var mTempShowHiddenHandler = Handler()
private var mZoomListener: MyRecyclerView.MyZoomListener? = null
- private var mSearchMenuItem: MenuItem? = null
private var mDirs = ArrayList()
private var mStoredAnimateGifs = true
@@ -224,8 +218,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
override fun onStop() {
super.onStop()
- mSearchMenuItem?.collapseActionView()
-
if (config.temporarilyShowHidden || config.tempSkipDeleteConfirmation) {
mTempShowHiddenHandler.postDelayed({
config.temporarilyShowHidden = false
@@ -276,7 +268,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
findItem(R.id.reduce_column_count).isVisible = config.viewTypeFolders == VIEW_TYPE_GRID && config.dirColumnCnt > 1
findItem(R.id.hide_the_recycle_bin).isVisible = useBin && config.showRecycleBinAtFolders
findItem(R.id.show_the_recycle_bin).isVisible = useBin && !config.showRecycleBinAtFolders
- setupSearch(this)
}
}
@@ -288,6 +279,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
+ R.id.search -> launchSearchActivity()
R.id.sort -> showSortingDialog()
R.id.filter -> showFilterMediaDialog()
R.id.open_camera -> launchCamera()
@@ -331,43 +323,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
}
- private fun setupSearch(menu: Menu) {
- val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
- mSearchMenuItem = menu.findItem(R.id.search)
- (mSearchMenuItem?.actionView as? SearchView)?.apply {
- setSearchableInfo(searchManager.getSearchableInfo(componentName))
- isSubmitButtonEnabled = false
- setOnQueryTextListener(object : SearchView.OnQueryTextListener {
- override fun onQueryTextSubmit(query: String) = false
-
- override fun onQueryTextChange(newText: String): Boolean {
- if (mIsSearchOpen) {
- setupAdapter(mDirs, newText)
- }
- return true
- }
- })
- }
-
- MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, object : MenuItemCompat.OnActionExpandListener {
- override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
- mIsSearchOpen = true
- directories_refresh_layout.isEnabled = false
- return true
- }
-
- // this triggers on device rotation too, avoid doing anything
- override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
- if (mIsSearchOpen) {
- mIsSearchOpen = false
- directories_refresh_layout.isEnabled = config.enablePullToRefresh
- setupAdapter(mDirs, "")
- }
- return true
- }
- })
- }
-
private fun startNewPhotoFetcher() {
if (isNougatPlus()) {
val photoFetcher = NewPhotoFetcher()
@@ -391,7 +346,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
private fun checkOTGPath() {
- Thread {
+ ensureBackgroundThread {
if (!config.wasOTGHandled && hasPermission(PERMISSION_WRITE_STORAGE) && hasOTGConnected() && config.OTGPath.isEmpty()) {
getStorageDirectories().firstOrNull { it.trimEnd('/') != internalStoragePath && it.trimEnd('/') != sdCardPath }?.apply {
config.wasOTGHandled = true
@@ -409,7 +364,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
}
}
- }.start()
+ }
}
private fun checkDefaultSpamFolders() {
@@ -467,15 +422,21 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
}
+ private fun launchSearchActivity() {
+ Intent(this, SearchActivity::class.java).apply {
+ startActivity(this)
+ }
+ }
+
private fun showSortingDialog() {
ChangeSortingDialog(this, true, false) {
directories_grid.adapter = null
if (config.directorySorting and SORT_BY_DATE_MODIFIED > 0 || config.directorySorting and SORT_BY_DATE_TAKEN > 0) {
getDirectories()
} else {
- Thread {
+ ensureBackgroundThread {
gotDirectories(getCurrentlyDisplayedDirs())
- }.start()
+ }
}
}
}
@@ -579,11 +540,11 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
refreshItems()
}
- Thread {
+ ensureBackgroundThread {
folders.filter { !it.exists() }.forEach {
mDirectoryDao.deleteDirPath(it.absolutePath)
}
- }.start()
+ }
}
}
@@ -668,22 +629,22 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private fun toggleRecycleBin(show: Boolean) {
config.showRecycleBinAtFolders = show
invalidateOptionsMenu()
- Thread {
+ ensureBackgroundThread {
var dirs = getCurrentlyDisplayedDirs()
if (!show) {
dirs = dirs.filter { it.path != RECYCLE_BIN } as ArrayList
}
gotDirectories(dirs)
- }.start()
+ }
}
private fun createNewFolder() {
FilePickerDialog(this, internalStoragePath, false, config.shouldShowHidden, false, true) {
CreateNewFolderDialog(this, it) {
config.tempFolderPath = it
- Thread {
+ ensureBackgroundThread {
gotDirectories(addTempFolderIfNeeded(getCurrentlyDisplayedDirs()))
- }.start()
+ }
}
}
}
@@ -808,9 +769,13 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
private fun itemClicked(path: String) {
- Intent(this, MediaActivity::class.java).apply {
- putExtra(DIRECTORY, path)
- handleMediaIntent(this)
+ handleLockedFolderOpening(path) { success ->
+ if (success) {
+ Intent(this, MediaActivity::class.java).apply {
+ putExtra(DIRECTORY, path)
+ handleMediaIntent(this)
+ }
+ }
}
}
@@ -1003,7 +968,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (dirs.isEmpty() && config.filterMedia == TYPE_DEFAULT_FILTER) {
directories_empty_text_label.text = getString(R.string.no_media_add_included)
directories_empty_text.text = getString(R.string.add_folder)
- directories_empty_text.underlineText()
directories_empty_text.setOnClickListener {
showAddIncludedFolderDialog {
@@ -1013,11 +977,13 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} else {
directories_empty_text_label.text = getString(R.string.no_media_with_filters)
directories_empty_text.text = getString(R.string.change_filters_underlined)
+
directories_empty_text.setOnClickListener {
showFilterMediaDialog()
}
}
+ directories_empty_text.underlineText()
directories_grid.beVisibleIf(directories_empty_text_label.isGone())
}
@@ -1136,12 +1102,12 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
?: ""
private fun setupLatestMediaId() {
- Thread {
+ ensureBackgroundThread {
if (hasPermission(PERMISSION_READ_STORAGE)) {
mLatestMediaId = getLatestMediaId()
mLatestMediaDateId = getLatestMediaByDateId()
}
- }.start()
+ }
}
private fun checkLastMediaChanged() {
@@ -1150,7 +1116,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
mLastMediaHandler.postDelayed({
- Thread {
+ ensureBackgroundThread {
val mediaId = getLatestMediaId()
val mediaDateId = getLatestMediaByDateId()
if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) {
@@ -1163,7 +1129,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
mLastMediaHandler.removeCallbacksAndMessages(null)
checkLastMediaChanged()
}
- }.start()
+ }
}, LAST_MEDIA_CHECK_PERIOD)
}
@@ -1171,12 +1137,12 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (config.useRecycleBin && config.lastBinCheck < System.currentTimeMillis() - DAY_SECONDS * 1000) {
config.lastBinCheck = System.currentTimeMillis()
Handler().postDelayed({
- Thread {
+ ensureBackgroundThread {
try {
mMediumDao.deleteOldRecycleBinItems(System.currentTimeMillis() - MONTH_MILLISECONDS)
} catch (e: Exception) {
}
- }.start()
+ }
}, 3000L)
}
}
@@ -1185,7 +1151,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
// /storage/emulated/0/Android/data/com.facebook.orca/files/stickers/175139712676531/209575122566323
// /storage/emulated/0/Android/data/com.facebook.orca/files/stickers/497837993632037/499671223448714
private fun excludeSpamFolders() {
- Thread {
+ ensureBackgroundThread {
try {
val internalPath = internalStoragePath
val checkedPaths = ArrayList()
@@ -1222,7 +1188,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
} catch (e: Exception) {
}
- }.start()
+ }
}
override fun refreshItems() {
@@ -1230,16 +1196,16 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
}
override fun recheckPinnedFolders() {
- Thread {
+ ensureBackgroundThread {
gotDirectories(movePinnedDirectoriesToFront(getCurrentlyDisplayedDirs()))
- }.start()
+ }
}
override fun updateDirectories(directories: ArrayList) {
- Thread {
+ ensureBackgroundThread {
storeDirectoryItems(directories, mDirectoryDao)
removeInvalidDBDirectories()
- }.start()
+ }
}
private fun checkWhatsNewDialog() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
index e2043f87d..f79e0a1f5 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
@@ -27,6 +27,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.helpers.SORT_BY_RANDOM
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.commons.views.MyRecyclerView
@@ -327,18 +328,25 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun searchQueryChanged(text: String) {
- Thread {
+ ensureBackgroundThread {
try {
val filtered = mMedia.filter { it is Medium && it.name.contains(text, true) } as ArrayList
filtered.sortBy { it is Medium && !it.name.startsWith(text, true) }
val grouped = MediaFetcher(applicationContext).groupMedia(filtered as ArrayList, mPath)
runOnUiThread {
+ if (grouped.isEmpty()) {
+ media_empty_text_label.text = getString(R.string.no_items_found)
+ media_empty_text_label.beVisible()
+ } else {
+ media_empty_text_label.beGone()
+ }
+
getMediaAdapter()?.updateMedia(grouped)
measureRecyclerViewContent(grouped)
}
} catch (ignored: Exception) {
}
- }.start()
+ }
}
private fun tryLoadGallery() {
@@ -428,7 +436,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
mLastMediaHandler.removeCallbacksAndMessages(null)
mLastMediaHandler.postDelayed({
- Thread {
+ ensureBackgroundThread {
val mediaId = getLatestMediaId()
val mediaDateId = getLatestMediaByDateId()
if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) {
@@ -440,7 +448,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} else {
checkLastMediaChanged()
}
- }.start()
+ }
}, LAST_MEDIA_CHECK_PERIOD)
}
@@ -480,9 +488,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
private fun restoreAllFiles() {
val paths = mMedia.filter { it is Medium }.map { (it as Medium).path } as ArrayList
restoreRecycleBinPaths(paths, mMediumDao) {
- Thread {
+ ensureBackgroundThread {
mDirectoryDao.deleteDirPath(RECYCLE_BIN)
- }.start()
+ }
finish()
}
}
@@ -586,7 +594,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
private fun startAsyncTask() {
mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
- Thread {
+ ensureBackgroundThread {
val oldMedia = mMedia.clone() as ArrayList
val newMedia = it
gotMedia(newMedia, false)
@@ -596,7 +604,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
} catch (e: Exception) {
}
- }.start()
+ }
}
mCurrAsyncTask!!.execute()
@@ -610,9 +618,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
if (mPath == FAVORITES) {
- Thread {
+ ensureBackgroundThread {
mDirectoryDao.deleteDirPath(FAVORITES)
- }.start()
+ }
}
finish()
@@ -623,9 +631,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun deleteDBDirectory() {
- Thread {
+ ensureBackgroundThread {
mDirectoryDao.deleteDirPath(mPath)
- }.start()
+ }
}
private fun createNewFolder() {
@@ -846,6 +854,10 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
media_refresh_layout.isRefreshing = false
media_empty_text_label.beVisibleIf(media.isEmpty() && !isFromCache)
media_empty_text.beVisibleIf(media.isEmpty() && !isFromCache)
+
+ if (media_empty_text_label.isVisible()) {
+ media_empty_text_label.text = getString(R.string.no_media_with_filters)
+ }
media_grid.beVisibleIf(media_empty_text_label.isGone())
val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath)
@@ -899,14 +911,14 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
mMedia.removeAll { filtered.map { it.path }.contains((it as? Medium)?.path) }
- Thread {
+ ensureBackgroundThread {
val useRecycleBin = config.useRecycleBin
filtered.forEach {
if (it.path.startsWith(recycleBinPath) || !useRecycleBin) {
deleteDBPath(mMediumDao, it.path)
}
}
- }.start()
+ }
if (mMedia.isEmpty()) {
deleteDirectoryIfEmpty()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaPhotoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaPhotoActivity.kt
index fa8dcfb54..c69cd5271 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaPhotoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PanoramaPhotoActivity.kt
@@ -15,6 +15,7 @@ import com.simplemobiletools.commons.extensions.onGlobalLayout
import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.PATH
@@ -94,7 +95,7 @@ open class PanoramaPhotoActivity : SimpleActivity() {
try {
val options = VrPanoramaView.Options()
options.inputType = VrPanoramaView.Options.TYPE_MONO
- Thread {
+ ensureBackgroundThread {
val bitmap = getBitmapToLoad(path)
runOnUiThread {
panorama_view.apply {
@@ -120,7 +121,7 @@ open class PanoramaPhotoActivity : SimpleActivity() {
})
}
}
- }.start()
+ }
} catch (e: Exception) {
showErrorToast(e)
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
index a596d86cb..80e922610 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/PhotoVideoActivity.kt
@@ -97,9 +97,16 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
val realPath = intent.extras!!.getString(REAL_FILE_PATH)
if (realPath != null && File(realPath).exists()) {
if (realPath.getFilenameFromPath().contains('.') || filename.contains('.')) {
- sendViewPagerIntent(realPath)
- finish()
- return
+ if (isFileTypeVisible(realPath)) {
+ bottom_actions.beGone()
+ handleLockedFolderOpening(realPath.getParentPath()) { success ->
+ if (success) {
+ sendViewPagerIntent(realPath)
+ }
+ finish()
+ }
+ return
+ }
} else {
filename = realPath.getFilenameFromPath()
}
@@ -108,18 +115,30 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
if (mUri!!.scheme == "file") {
if (filename.contains('.')) {
- rescanPaths(arrayListOf(mUri!!.path))
- sendViewPagerIntent(mUri!!.path)
- finish()
- return
+ bottom_actions.beGone()
+ handleLockedFolderOpening(mUri!!.path.getParentPath()) { success ->
+ if (success) {
+ rescanPaths(arrayListOf(mUri!!.path))
+ sendViewPagerIntent(mUri!!.path)
+ }
+ finish()
+ }
}
+ return
} else {
val path = applicationContext.getRealPathFromURI(mUri!!) ?: ""
if (path != mUri.toString() && path.isNotEmpty() && mUri!!.authority != "mms" && filename.contains('.') && File(path).exists()) {
- rescanPaths(arrayListOf(mUri!!.path))
- sendViewPagerIntent(path)
- finish()
- return
+ if (isFileTypeVisible(path)) {
+ bottom_actions.beGone()
+ handleLockedFolderOpening(path.getParentPath()) { success ->
+ if (success) {
+ rescanPaths(arrayListOf(mUri!!.path))
+ sendViewPagerIntent(path)
+ }
+ finish()
+ }
+ return
+ }
}
}
@@ -228,6 +247,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
findItem(R.id.menu_edit).isVisible = mMedium?.isImage() == true && mUri?.scheme == "file" && visibleBottomActions and BOTTOM_ACTION_EDIT == 0
findItem(R.id.menu_properties).isVisible = mUri?.scheme == "file" && visibleBottomActions and BOTTOM_ACTION_PROPERTIES == 0
findItem(R.id.menu_share).isVisible = visibleBottomActions and BOTTOM_ACTION_SHARE == 0
+ findItem(R.id.menu_show_on_map).isVisible = visibleBottomActions and BOTTOM_ACTION_SHOW_ON_MAP == 0
}
return true
@@ -244,6 +264,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
R.id.menu_share -> sharePath(mUri!!.toString())
R.id.menu_edit -> openEditor(mUri!!.toString())
R.id.menu_properties -> showProperties()
+ R.id.menu_show_on_map -> showFileOnMap(mUri!!.toString())
else -> return super.onOptionsItemSelected(item)
}
return true
@@ -253,6 +274,15 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
PropertiesDialog(this, mUri!!.path)
}
+ private fun isFileTypeVisible(path: String): Boolean {
+ val filter = config.filterMedia
+ return !(path.isImageFast() && filter and TYPE_IMAGES == 0 ||
+ path.isVideoFast() && filter and TYPE_VIDEOS == 0 ||
+ path.isGif() && filter and TYPE_GIFS == 0 ||
+ path.isRawFast() && filter and TYPE_RAWS == 0 ||
+ path.isSvg() && filter and TYPE_SVGS == 0)
+ }
+
private fun initBottomActions() {
initBottomActionsLayout()
initBottomActionButtons()
@@ -292,6 +322,11 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
bottom_set_as.setOnClickListener {
setAs(mUri!!.toString())
}
+
+ bottom_show_on_map.beVisibleIf(visibleBottomActions and BOTTOM_ACTION_SHOW_ON_MAP != 0)
+ bottom_show_on_map.setOnClickListener {
+ showFileOnMap(mUri!!.toString())
+ }
}
override fun fragmentClicked() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SearchActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SearchActivity.kt
new file mode 100644
index 000000000..33901c1d4
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SearchActivity.kt
@@ -0,0 +1,340 @@
+package com.simplemobiletools.gallery.pro.activities
+
+import android.app.SearchManager
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.view.ViewGroup
+import android.widget.RelativeLayout
+import androidx.appcompat.widget.SearchView
+import androidx.core.view.MenuItemCompat
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
+import com.simplemobiletools.commons.models.FileDirItem
+import com.simplemobiletools.commons.views.MyGridLayoutManager
+import com.simplemobiletools.gallery.pro.R
+import com.simplemobiletools.gallery.pro.adapters.MediaAdapter
+import com.simplemobiletools.gallery.pro.asynctasks.GetMediaAsynctask
+import com.simplemobiletools.gallery.pro.extensions.*
+import com.simplemobiletools.gallery.pro.helpers.*
+import com.simplemobiletools.gallery.pro.interfaces.MediaOperationsListener
+import com.simplemobiletools.gallery.pro.models.Medium
+import com.simplemobiletools.gallery.pro.models.ThumbnailItem
+import com.simplemobiletools.gallery.pro.models.ThumbnailSection
+import kotlinx.android.synthetic.main.activity_search.*
+import java.io.File
+
+class SearchActivity : SimpleActivity(), MediaOperationsListener {
+ private var mIsSearchOpen = false
+ private var mLastSearchedText = ""
+
+ private var mSearchMenuItem: MenuItem? = null
+ private var mCurrAsyncTask: GetMediaAsynctask? = null
+ private var mAllMedia = ArrayList()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_search)
+ media_empty_text_label.setTextColor(config.textColor)
+ getAllMedia()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mCurrAsyncTask?.stopFetching()
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_search, menu)
+ setupSearch(menu)
+ return true
+ }
+
+ private fun setupSearch(menu: Menu) {
+ val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
+ mSearchMenuItem = menu.findItem(R.id.search)
+ (mSearchMenuItem?.actionView as? SearchView)?.apply {
+ setSearchableInfo(searchManager.getSearchableInfo(componentName))
+ isSubmitButtonEnabled = false
+ setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+ override fun onQueryTextSubmit(query: String) = false
+
+ override fun onQueryTextChange(newText: String): Boolean {
+ if (mIsSearchOpen) {
+ mLastSearchedText = newText
+ textChanged(newText)
+ }
+ return true
+ }
+ })
+ }
+
+ MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, object : MenuItemCompat.OnActionExpandListener {
+ override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
+ mIsSearchOpen = true
+ return true
+ }
+
+ // this triggers on device rotation too, avoid doing anything
+ override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
+ if (mIsSearchOpen) {
+ mIsSearchOpen = false
+ mLastSearchedText = ""
+ }
+ return true
+ }
+ })
+ mSearchMenuItem?.expandActionView()
+ }
+
+ private fun textChanged(text: String) {
+ ensureBackgroundThread {
+ try {
+ val filtered = mAllMedia.filter { it is Medium && it.name.contains(text, true) } as ArrayList
+ filtered.sortBy { it is Medium && !it.name.startsWith(text, true) }
+ val grouped = MediaFetcher(applicationContext).groupMedia(filtered as ArrayList, "")
+ runOnUiThread {
+ if (grouped.isEmpty()) {
+ media_empty_text_label.text = getString(R.string.no_items_found)
+ media_empty_text_label.beVisible()
+ } else {
+ media_empty_text_label.beGone()
+ }
+
+ getMediaAdapter()?.updateMedia(grouped)
+ measureRecyclerViewContent(grouped)
+ }
+ } catch (ignored: Exception) {
+ }
+ }
+ }
+
+ private fun setupAdapter() {
+ val currAdapter = media_grid.adapter
+ if (currAdapter == null) {
+ val fastscroller = if (config.scrollHorizontally) media_horizontal_fastscroller else media_vertical_fastscroller
+ MediaAdapter(this, ArrayList(), this, false, false, "", media_grid, fastscroller) {
+ if (it is Medium) {
+ itemClicked(it.path)
+ }
+ }.apply {
+ media_grid.adapter = this
+ }
+ setupLayoutManager()
+ } else {
+ (currAdapter as MediaAdapter).updateMedia(mAllMedia)
+ }
+
+ measureRecyclerViewContent(mAllMedia)
+ setupScrollDirection()
+ }
+
+ private fun getMediaAdapter() = media_grid.adapter as? MediaAdapter
+
+ private fun itemClicked(path: String) {
+ val isVideo = path.isVideoFast()
+ if (isVideo) {
+ openPath(path, false)
+ } else {
+ Intent(this, ViewPagerActivity::class.java).apply {
+ putExtra(PATH, path)
+ putExtra(SHOW_ALL, false)
+ startActivity(this)
+ }
+ }
+ }
+
+ private fun setupLayoutManager() {
+ val viewType = config.getFolderViewType(SHOW_ALL)
+ if (viewType == VIEW_TYPE_GRID) {
+ setupGridLayoutManager()
+ } else {
+ setupListLayoutManager()
+ }
+ }
+
+ private fun setupGridLayoutManager() {
+ val layoutManager = media_grid.layoutManager as MyGridLayoutManager
+ if (config.scrollHorizontally) {
+ layoutManager.orientation = RecyclerView.HORIZONTAL
+ media_grid.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
+ } else {
+ layoutManager.orientation = RecyclerView.VERTICAL
+ media_grid.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+ }
+
+ layoutManager.spanCount = config.mediaColumnCnt
+ val adapter = getMediaAdapter()
+ layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
+ override fun getSpanSize(position: Int): Int {
+ return if (adapter?.isASectionTitle(position) == true) {
+ layoutManager.spanCount
+ } else {
+ 1
+ }
+ }
+ }
+ }
+
+ private fun setupListLayoutManager() {
+ val layoutManager = media_grid.layoutManager as MyGridLayoutManager
+ layoutManager.spanCount = 1
+ layoutManager.orientation = RecyclerView.VERTICAL
+ }
+
+ private fun setupScrollDirection() {
+ val viewType = config.getFolderViewType(SHOW_ALL)
+ val allowHorizontalScroll = config.scrollHorizontally && viewType == VIEW_TYPE_GRID
+ media_vertical_fastscroller.isHorizontal = false
+ media_vertical_fastscroller.beGoneIf(allowHorizontalScroll)
+
+ media_horizontal_fastscroller.isHorizontal = true
+ media_horizontal_fastscroller.beVisibleIf(allowHorizontalScroll)
+
+ val sorting = config.getFileSorting(SHOW_ALL)
+ if (allowHorizontalScroll) {
+ media_horizontal_fastscroller.allowBubbleDisplay = config.showInfoBubble
+ media_horizontal_fastscroller.setViews(media_grid) {
+ media_horizontal_fastscroller.updateBubbleText(getBubbleTextItem(it, sorting))
+ }
+ } else {
+ media_vertical_fastscroller.allowBubbleDisplay = config.showInfoBubble
+ media_vertical_fastscroller.setViews(media_grid) {
+ media_vertical_fastscroller.updateBubbleText(getBubbleTextItem(it, sorting))
+ }
+ }
+ }
+
+ private fun getBubbleTextItem(index: Int, sorting: Int): String {
+ var realIndex = index
+ val mediaAdapter = getMediaAdapter()
+ if (mediaAdapter?.isASectionTitle(index) == true) {
+ realIndex++
+ }
+ return mediaAdapter?.getItemBubbleText(realIndex, sorting) ?: ""
+ }
+
+ private fun measureRecyclerViewContent(media: ArrayList) {
+ media_grid.onGlobalLayout {
+ if (config.scrollHorizontally) {
+ calculateContentWidth(media)
+ } else {
+ calculateContentHeight(media)
+ }
+ }
+ }
+
+ private fun calculateContentWidth(media: ArrayList) {
+ val layoutManager = media_grid.layoutManager as MyGridLayoutManager
+ val thumbnailWidth = layoutManager.getChildAt(0)?.width ?: 0
+ val fullWidth = ((media.size - 1) / layoutManager.spanCount + 1) * thumbnailWidth
+ media_horizontal_fastscroller.setContentWidth(fullWidth)
+ media_horizontal_fastscroller.setScrollToX(media_grid.computeHorizontalScrollOffset())
+ }
+
+ private fun calculateContentHeight(media: ArrayList) {
+ val layoutManager = media_grid.layoutManager as MyGridLayoutManager
+ val pathToCheck = SHOW_ALL
+ val hasSections = config.getFolderGrouping(pathToCheck) and GROUP_BY_NONE == 0 && !config.scrollHorizontally
+ val sectionTitleHeight = if (hasSections) layoutManager.getChildAt(0)?.height ?: 0 else 0
+ val thumbnailHeight = if (hasSections) layoutManager.getChildAt(1)?.height ?: 0 else layoutManager.getChildAt(0)?.height ?: 0
+
+ var fullHeight = 0
+ var curSectionItems = 0
+ media.forEach {
+ if (it is ThumbnailSection) {
+ fullHeight += sectionTitleHeight
+ if (curSectionItems != 0) {
+ val rows = ((curSectionItems - 1) / layoutManager.spanCount + 1)
+ fullHeight += rows * thumbnailHeight
+ }
+ curSectionItems = 0
+ } else {
+ curSectionItems++
+ }
+ }
+
+ fullHeight += ((curSectionItems - 1) / layoutManager.spanCount + 1) * thumbnailHeight
+ media_vertical_fastscroller.setContentHeight(fullHeight)
+ media_vertical_fastscroller.setScrollToY(media_grid.computeVerticalScrollOffset())
+ }
+
+ private fun getAllMedia() {
+ getCachedMedia("") {
+ if (it.isNotEmpty()) {
+ mAllMedia = it.clone() as ArrayList
+ }
+ runOnUiThread {
+ setupAdapter()
+ }
+ startAsyncTask(false)
+ }
+ }
+
+ private fun startAsyncTask(updateItems: Boolean) {
+ mCurrAsyncTask?.stopFetching()
+ mCurrAsyncTask = GetMediaAsynctask(applicationContext, "", showAll = true) {
+ mAllMedia = it.clone() as ArrayList
+ if (updateItems) {
+ textChanged(mLastSearchedText)
+ }
+ }
+
+ mCurrAsyncTask!!.execute()
+ }
+
+ override fun refreshItems() {
+ startAsyncTask(true)
+ }
+
+ override fun tryDeleteFiles(fileDirItems: ArrayList) {
+ val filtered = fileDirItems.filter { File(it.path).isFile && it.path.isMediaFile() } as ArrayList
+ if (filtered.isEmpty()) {
+ return
+ }
+
+ if (config.useRecycleBin && !filtered.first().path.startsWith(recycleBinPath)) {
+ val movingItems = resources.getQuantityString(R.plurals.moving_items_into_bin, filtered.size, filtered.size)
+ toast(movingItems)
+
+ movePathsInRecycleBin(filtered.map { it.path } as ArrayList, galleryDB.MediumDao()) {
+ if (it) {
+ deleteFilteredFiles(filtered)
+ } else {
+ toast(R.string.unknown_error_occurred)
+ }
+ }
+ } else {
+ val deletingItems = resources.getQuantityString(R.plurals.deleting_items, filtered.size, filtered.size)
+ toast(deletingItems)
+ deleteFilteredFiles(filtered)
+ }
+ }
+
+ private fun deleteFilteredFiles(filtered: ArrayList) {
+ deleteFiles(filtered) {
+ if (!it) {
+ toast(R.string.unknown_error_occurred)
+ return@deleteFiles
+ }
+
+ mAllMedia.removeAll { filtered.map { it.path }.contains((it as? Medium)?.path) }
+
+ ensureBackgroundThread {
+ val useRecycleBin = config.useRecycleBin
+ filtered.forEach {
+ if (it.path.startsWith(recycleBinPath) || !useRecycleBin) {
+ deleteDBPath(galleryDB.MediumDao(), it.path)
+ }
+ }
+ }
+ }
+ }
+
+ override fun selectedPaths(paths: ArrayList) {
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SetWallpaperActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SetWallpaperActivity.kt
index 946e0176f..2ceafc06b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SetWallpaperActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SetWallpaperActivity.kt
@@ -11,6 +11,7 @@ import android.view.Menu
import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.toast
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.gallery.pro.R
@@ -117,7 +118,7 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
if (result.error == null) {
toast(R.string.setting_wallpaper)
- Thread {
+ ensureBackgroundThread {
val bitmap = result.bitmap
val wantedHeight = wallpaperManager.desiredMinimumHeight
val ratio = wantedHeight / bitmap.height.toFloat()
@@ -135,7 +136,7 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
setResult(Activity.RESULT_CANCELED)
}
finish()
- }.start()
+ }
} else {
toast("${getString(R.string.image_editing_failed)}: ${result.error.message}")
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SettingsActivity.kt
index a8df6dc58..c1e278770 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SettingsActivity.kt
@@ -572,7 +572,7 @@ class SettingsActivity : SimpleActivity() {
}
private fun setupEmptyRecycleBin() {
- Thread {
+ ensureBackgroundThread {
try {
mRecycleBinContentSize = galleryDB.MediumDao().getDeletedMedia().sumByLong { it.size }
} catch (ignored: Exception) {
@@ -580,7 +580,7 @@ class SettingsActivity : SimpleActivity() {
runOnUiThread {
settings_empty_recycle_bin_size.text = mRecycleBinContentSize.formatSize()
}
- }.start()
+ }
settings_empty_recycle_bin_holder.setOnClickListener {
if (mRecycleBinContentSize == 0L) {
@@ -686,13 +686,13 @@ class SettingsActivity : SimpleActivity() {
private fun setupImportSettings() {
settings_import_holder.setOnClickListener {
FilePickerDialog(this) {
- Thread {
+ ensureBackgroundThread {
try {
parseFile(it)
} catch (e: Exception) {
showErrorToast(e)
}
- }.start()
+ }
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SimpleActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SimpleActivity.kt
index 8b3505972..da2a95982 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SimpleActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/SimpleActivity.kt
@@ -10,6 +10,7 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.getParentPath
import com.simplemobiletools.commons.extensions.getRealPathFromURI
import com.simplemobiletools.commons.extensions.scanPathRecursively
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isPiePlus
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.addPathToDB
@@ -87,9 +88,9 @@ open class SimpleActivity : BaseSimpleActivity() {
config.lastFilepickerPath = it
config.addIncludedFolder(it)
callback()
- Thread {
+ ensureBackgroundThread {
scanPathRecursively(it)
- }.start()
+ }
}
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt
index a1f0c225e..bed9bc018 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/VideoPlayerActivity.kt
@@ -25,6 +25,7 @@ import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.video.VideoListener
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.*
@@ -566,10 +567,10 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
private fun releaseExoPlayer() {
mExoPlayer?.stop()
- Thread {
+ ensureBackgroundThread {
mExoPlayer?.release()
mExoPlayer = null
- }.start()
+ }
}
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
@@ -602,9 +603,9 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
- Thread {
+ ensureBackgroundThread {
mExoPlayer?.setVideoSurface(Surface(video_surface!!.surfaceTexture))
- }.start()
+ }
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
index 285277d44..db5f4d639 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
@@ -10,6 +10,7 @@ import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import android.content.res.Configuration
import android.database.Cursor
+import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon
@@ -24,7 +25,15 @@ import android.view.View
import android.view.WindowManager
import android.view.animation.DecelerateInterpolator
import android.widget.Toast
+import androidx.print.PrintHelper
import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.bumptech.glide.load.DataSource
+import com.bumptech.glide.load.engine.DiskCacheStrategy
+import com.bumptech.glide.load.engine.GlideException
+import com.bumptech.glide.request.RequestListener
+import com.bumptech.glide.request.RequestOptions
+import com.bumptech.glide.request.target.Target
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.*
@@ -160,6 +169,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
findItem(R.id.menu_copy_to).isVisible = visibleBottomActions and BOTTOM_ACTION_COPY == 0
findItem(R.id.menu_move_to).isVisible = visibleBottomActions and BOTTOM_ACTION_MOVE == 0
findItem(R.id.menu_save_as).isVisible = rotationDegrees != 0
+ findItem(R.id.menu_print).isVisible = currentMedium.isImage() || currentMedium.isRaw()
findItem(R.id.menu_hide).isVisible = !currentMedium.isHidden() && visibleBottomActions and BOTTOM_ACTION_TOGGLE_VISIBILITY == 0 && !currentMedium.getIsInRecycleBin()
findItem(R.id.menu_unhide).isVisible = currentMedium.isHidden() && visibleBottomActions and BOTTOM_ACTION_TOGGLE_VISIBILITY == 0 && !currentMedium.getIsInRecycleBin()
findItem(R.id.menu_add_to_favorites).isVisible = !currentMedium.isFavorite && visibleBottomActions and BOTTOM_ACTION_TOGGLE_FAVORITE == 0 && !currentMedium.getIsInRecycleBin()
@@ -197,9 +207,10 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
R.id.menu_share -> shareMediumPath(getCurrentPath())
R.id.menu_delete -> checkDeleteConfirmation()
R.id.menu_rename -> renameFile()
+ R.id.menu_print -> printFile()
R.id.menu_edit -> openEditor(getCurrentPath())
R.id.menu_properties -> showProperties()
- R.id.menu_show_on_map -> showOnMap()
+ R.id.menu_show_on_map -> showFileOnMap(getCurrentPath())
R.id.menu_rotate_right -> rotateImage(90)
R.id.menu_rotate_left -> rotateImage(-90)
R.id.menu_rotate_one_eighty -> rotateImage(180)
@@ -324,7 +335,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
if (intent.action == "com.android.camera.action.REVIEW") {
- Thread {
+ ensureBackgroundThread {
val mediumDao = galleryDB.MediumDao()
if (mediumDao.getMediaFromPath(mPath).isEmpty()) {
val type = when {
@@ -341,7 +352,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
val medium = Medium(null, mPath.getFilenameFromPath(), mPath, mPath.getParentPath(), ts, ts, File(mPath).length(), type, duration, isFavorite, 0)
mediumDao.insert(medium)
}
- }.start()
+ }
}
}
@@ -351,9 +362,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
private fun initFavorites() {
- Thread {
+ ensureBackgroundThread {
mFavoritePaths = getFavoritePaths()
- }.start()
+ }
}
private fun setupOrientation() {
@@ -624,14 +635,14 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
val newPath = it
handleSAFDialog(it) {
toast(R.string.saving)
- Thread {
- val photoFragment = getCurrentPhotoFragment() ?: return@Thread
+ ensureBackgroundThread {
+ val photoFragment = getCurrentPhotoFragment() ?: return@ensureBackgroundThread
saveRotatedImageToFile(currPath, newPath, photoFragment.mCurrentRotationDegrees, true) {
toast(R.string.file_saved)
getCurrentPhotoFragment()?.mCurrentRotationDegrees = 0
invalidateOptionsMenu()
}
- }.start()
+ }
}
}
}
@@ -690,69 +701,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
}
- private fun showOnMap() {
- val exif: ExifInterface
- try {
- exif = ExifInterface(getCurrentPath())
- } catch (e: Exception) {
- showErrorToast(e)
- return
- }
- val lat = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE)
- val lat_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF)
- val lon = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE)
- val lon_ref = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF)
-
- if (lat == null || lat_ref == null || lon == null || lon_ref == null) {
- toast(R.string.unknown_location)
- } else {
- val geoLat = if (lat_ref == "N") {
- convertToDegree(lat)
- } else {
- 0 - convertToDegree(lat)
- }
-
- val geoLon = if (lon_ref == "E") {
- convertToDegree(lon)
- } else {
- 0 - convertToDegree(lon)
- }
-
- val uriBegin = "geo:$geoLat,$geoLon"
- val query = "$geoLat, $geoLon"
- val encodedQuery = Uri.encode(query)
- val uriString = "$uriBegin?q=$encodedQuery&z=16"
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uriString))
- val packageManager = packageManager
- if (intent.resolveActivity(packageManager) != null) {
- startActivity(intent)
- } else {
- toast(R.string.no_app_found)
- }
- }
- }
-
- private fun convertToDegree(stringDMS: String): Float {
- val dms = stringDMS.split(",".toRegex(), 3).toTypedArray()
-
- val stringD = dms[0].split("/".toRegex(), 2).toTypedArray()
- val d0 = stringD[0].toDouble()
- val d1 = stringD[1].toDouble()
- val floatD = d0 / d1
-
- val stringM = dms[1].split("/".toRegex(), 2).toTypedArray()
- val m0 = stringM[0].toDouble()
- val m1 = stringM[1].toDouble()
- val floatM = m0 / m1
-
- val stringS = dms[2].split("/".toRegex(), 2).toTypedArray()
- val s0 = stringS[0].toDouble()
- val s1 = stringS[1].toDouble()
- val floatS = s0 / s1
-
- return (floatD + floatM / 60 + floatS / 3600).toFloat()
- }
-
private fun initBottomActionsLayout() {
bottom_actions.layoutParams.height = resources.getDimension(R.dimen.bottom_actions_height).toInt() + navigationBarHeight
if (config.bottomActions) {
@@ -812,7 +760,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
bottom_show_on_map.beVisibleIf(visibleBottomActions and BOTTOM_ACTION_SHOW_ON_MAP != 0)
bottom_show_on_map.setOnClickListener {
- showOnMap()
+ showFileOnMap(getCurrentPath())
}
bottom_toggle_file_visibility.beVisibleIf(visibleBottomActions and BOTTOM_ACTION_TOGGLE_VISIBILITY != 0)
@@ -863,7 +811,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun toggleFavorite() {
val medium = getCurrentMedium() ?: return
medium.isFavorite = !medium.isFavorite
- Thread {
+ ensureBackgroundThread {
galleryDB.MediumDao().updateFavorite(medium.path, medium.isFavorite)
if (medium.isFavorite) {
mFavoritePaths.add(medium.path)
@@ -871,7 +819,60 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
mFavoritePaths.remove(medium.path)
}
invalidateOptionsMenu()
- }.start()
+ }
+ }
+
+ private fun printFile() {
+ sendPrintIntent(getCurrentPath())
+ }
+
+ private fun sendPrintIntent(path: String) {
+ val printHelper = PrintHelper(this)
+ printHelper.scaleMode = PrintHelper.SCALE_MODE_FIT
+ printHelper.orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+
+ try {
+ val resolution = path.getImageResolution()
+ if (resolution == null) {
+ toast(R.string.unknown_error_occurred)
+ return
+ }
+
+ var requestedWidth = resolution.x
+ var requestedHeight = resolution.y
+
+ if (requestedWidth >= MAX_PRINT_SIDE_SIZE) {
+ requestedHeight = (requestedHeight / (requestedWidth / MAX_PRINT_SIDE_SIZE.toFloat())).toInt()
+ requestedWidth = MAX_PRINT_SIDE_SIZE
+ } else if (requestedHeight >= MAX_PRINT_SIDE_SIZE) {
+ requestedWidth = (requestedWidth / (requestedHeight / MAX_PRINT_SIDE_SIZE.toFloat())).toInt()
+ requestedHeight = MAX_PRINT_SIDE_SIZE
+ }
+
+ val options = RequestOptions()
+ .skipMemoryCache(true)
+ .diskCacheStrategy(DiskCacheStrategy.NONE)
+
+ Glide.with(this)
+ .asBitmap()
+ .load(path)
+ .apply(options)
+ .listener(object : RequestListener {
+ override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean {
+ showErrorToast(e?.localizedMessage ?: "")
+ return false
+ }
+
+ override fun onResourceReady(bitmap: Bitmap?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
+ if (bitmap != null) {
+ printHelper.printBitmap(path.getFilenameFromPath(), bitmap)
+ }
+
+ return false
+ }
+ }).submit(requestedWidth, requestedHeight)
+ } catch (e: Exception) {
+ }
}
private fun restoreFile() {
@@ -989,9 +990,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
name = it.getFilenameFromPath()
}
- Thread {
+ ensureBackgroundThread {
updateDBMediaPath(oldPath, it)
- }.start()
+ }
updateActionbarTitle()
}
}
@@ -1092,8 +1093,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
override fun launchViewVideoIntent(path: String) {
- Thread {
- val newUri = getFinalUriFromPath(path, BuildConfig.APPLICATION_ID) ?: return@Thread
+ ensureBackgroundThread {
+ val newUri = getFinalUriFromPath(path, BuildConfig.APPLICATION_ID) ?: return@ensureBackgroundThread
val mimeType = getUriMimeType(path, newUri)
Intent().apply {
action = Intent.ACTION_VIEW
@@ -1116,7 +1117,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
}
}
- }.start()
+ }
}
private fun checkSystemUI() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt
index 20feaa695..f34a23e9b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt
@@ -10,6 +10,7 @@ import android.widget.RelativeLayout
import android.widget.RemoteViews
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.dialogs.PickDirectoryDialog
import com.simplemobiletools.gallery.pro.extensions.*
@@ -89,9 +90,9 @@ class WidgetConfigureActivity : SimpleActivity() {
AppWidgetManager.getInstance(this).updateAppWidget(mWidgetId, views)
config.showWidgetFolderName = folder_picker_show_folder_name.isChecked
val widget = Widget(null, mWidgetId, mFolderPath)
- Thread {
+ ensureBackgroundThread {
widgetsDB.insertOrUpdate(widget)
- }.start()
+ }
storeWidgetColors()
requestWidgetUpdate()
@@ -161,14 +162,14 @@ class WidgetConfigureActivity : SimpleActivity() {
config_folder_name.text = getFolderNameFromPath(folderPath)
}
- Thread {
+ ensureBackgroundThread {
val path = directoryDB.getDirectoryThumbnail(folderPath)
if (path != null) {
runOnUiThread {
loadJpg(path, config_image, config.cropThumbnails)
}
}
- }.start()
+ }
}
private fun handleFolderNameDisplay() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
index fc6e60851..cb1e7dba7 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
+import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon
import android.view.Menu
import android.view.View
@@ -12,11 +13,10 @@ 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.dialogs.RenameItemsDialog
+import com.simplemobiletools.commons.dialogs.*
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.SHOW_ALL_TABS
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isOreoPlus
import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.views.FastScroller
@@ -31,6 +31,13 @@ import com.simplemobiletools.gallery.pro.helpers.*
import com.simplemobiletools.gallery.pro.interfaces.DirectoryOperationsListener
import com.simplemobiletools.gallery.pro.models.AlbumCover
import com.simplemobiletools.gallery.pro.models.Directory
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_check
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_location
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_lock
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_name
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_pin
+import kotlinx.android.synthetic.main.directory_item_grid.view.dir_thumbnail
+import kotlinx.android.synthetic.main.directory_item_grid.view.photo_cnt
import kotlinx.android.synthetic.main.directory_item_list.view.*
import java.io.File
@@ -47,9 +54,11 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList()
init {
setupDragListener(true)
+ fillLockedFolders()
}
override fun getActionMenuId() = R.menu.cab_directories
@@ -80,6 +89,9 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList toggleFoldersVisibility(true)
R.id.cab_unhide -> toggleFoldersVisibility(false)
R.id.cab_exclude -> tryExcludeFolder()
+ R.id.cab_lock -> tryLockFolder()
+ R.id.cab_unlock -> unlockFolder()
R.id.cab_copy_to -> copyMoveTo(true)
R.id.cab_move_to -> moveFilesTo()
R.id.cab_select_all -> selectAll()
- R.id.cab_create_shortcut -> createShortcut()
+ R.id.cab_create_shortcut -> tryCreateShortcut()
R.id.cab_delete -> askConfirmDelete()
- R.id.cab_select_photo -> changeAlbumCover(false)
- R.id.cab_use_default -> changeAlbumCover(true)
+ R.id.cab_select_photo -> tryChangeAlbumCover(false)
+ R.id.cab_use_default -> tryChangeAlbumCover(true)
}
}
@@ -145,10 +159,16 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ PropertiesDialog(activity, path, config.shouldShowHidden)
+ }
+ }
}
} else {
- PropertiesDialog(activity, getSelectedPaths().filter { it != FAVORITES && it != RECYCLE_BIN }.toMutableList(), config.shouldShowHidden)
+ PropertiesDialog(activity, getSelectedPaths().filter {
+ it != FAVORITES && it != RECYCLE_BIN && !activity.config.isFolderProtected(it)
+ }.toMutableList(), config.shouldShowHidden)
}
}
@@ -162,22 +182,26 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ RenameItemDialog(activity, dir.absolutePath) {
+ activity.runOnUiThread {
+ firstDir.apply {
+ path = it
+ name = it.getFilenameFromPath()
+ tmb = File(it, tmb.getFilenameFromPath()).absolutePath
+ }
+ updateDirs(dirs)
+ ensureBackgroundThread {
+ activity.galleryDB.DirectoryDao().updateDirectoryAfterRename(firstDir.tmb, firstDir.name, firstDir.path, sourcePath)
+ listener?.refreshItems()
+ }
+ }
}
- updateDirs(dirs)
- Thread {
- activity.galleryDB.DirectoryDao().updateDirectoryAfterRename(firstDir.tmb, firstDir.name, firstDir.path, sourcePath)
- listener?.refreshItems()
- }.start()
}
}
} else {
- val paths = getSelectedPaths().filter { !activity.isAStorageRootFolder(it) } as ArrayList
+ val paths = getSelectedPaths().filter { !activity.isAStorageRootFolder(it) && !activity.config.isFolderProtected(it) } as ArrayList
RenameItemsDialog(activity, paths) {
listener?.refreshItems()
}
@@ -194,25 +218,37 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ hideFolder(path)
+ }
+ }
} else {
config.wasHideFolderTooltipShown = true
ConfirmationDialog(activity, activity.getString(R.string.hide_folder_description)) {
- hideFolder(path)
+ activity.handleLockedFolderOpening(path) { success ->
+ if (success) {
+ hideFolder(path)
+ }
+ }
}
}
} else {
- activity.removeNoMedia(path) {
- if (activity.config.shouldShowHidden) {
- updateFolderNames()
- } else {
- activity.runOnUiThread {
- listener?.refreshItems()
- finishActMode()
+ activity.handleLockedFolderOpening(path) { success ->
+ if (success) {
+ activity.removeNoMedia(path) {
+ if (activity.config.shouldShowHidden) {
+ updateFolderNames()
+ } else {
+ activity.runOnUiThread {
+ listener?.refreshItems()
+ finishActMode()
+ }
+ }
}
}
}
@@ -231,15 +267,23 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ activity.emptyTheRecycleBin {
+ listener?.refreshItems()
+ }
+ }
}
}
private fun emptyAndDisableRecycleBin() {
- activity.showRecycleBinEmptyingDialog {
- activity.emptyAndDisableTheRecycleBin {
- listener?.refreshItems()
+ activity.handleLockedFolderOpening(RECYCLE_BIN) { success ->
+ if (success) {
+ activity.showRecycleBinEmptyingDialog {
+ activity.emptyAndDisableTheRecycleBin {
+ listener?.refreshItems()
+ }
+ }
}
}
}
@@ -309,6 +353,48 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ getSelectedPaths().filter { !config.isFolderProtected(it) }.forEach {
+ config.addFolderProtection(it, hash, type)
+ lockedFolderPaths.add(it)
+ }
+
+ listener?.refreshItems()
+ finishActMode()
+ }
+ }
+ }
+
+ private fun unlockFolder() {
+ val paths = getSelectedPaths()
+ val firstPath = paths.first()
+ val tabToShow = config.getFolderProtectionType(firstPath)
+ val hashToCheck = config.getFolderProtectionHash(firstPath)
+ SecurityDialog(activity, hashToCheck, tabToShow) { hash, type, success ->
+ if (success) {
+ paths.filter { config.isFolderProtected(it) && config.getFolderProtectionType(it) == tabToShow && config.getFolderProtectionHash(it) == hashToCheck }.forEach {
+ config.removeFolderProtection(it)
+ lockedFolderPaths.remove(it)
+ }
+
+ listener?.refreshItems()
+ finishActMode()
+ }
+ }
+ }
+
private fun pinFolders(pin: Boolean) {
if (pin) {
config.addPinnedFolders(getSelectedPaths().toHashSet())
@@ -351,6 +437,14 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ createShortcut()
+ }
+ }
+ }
+
@SuppressLint("NewApi")
private fun createShortcut() {
val manager = activity.getSystemService(ShortcutManager::class.java)
@@ -425,16 +519,16 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList(selectedKeys.size)
+ var foldersToDelete = ArrayList(selectedKeys.size)
selectedDirs.forEach {
if (it.areFavorites() || it.isRecycleBin()) {
if (it.isRecycleBin()) {
tryEmptyRecycleBin(false)
} else {
- Thread {
+ ensureBackgroundThread {
activity.galleryDB.MediumDao().clearFavorites()
listener?.refreshItems()
- }.start()
+ }
}
if (selectedKeys.size == 1) {
@@ -445,7 +539,24 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList
+ if (success) {
+ listener?.deleteFolders(foldersToDelete)
+ }
+ }
+ } else {
+ foldersToDelete = foldersToDelete.filter { !activity.config.isFolderProtected(it.absolutePath) }.toMutableList() as ArrayList
+ listener?.deleteFolders(foldersToDelete)
+ }
+ }
+ }
+
+ private fun tryChangeAlbumCover(useDefault: Boolean) {
+ activity.handleLockedFolderOpening(getFirstSelectedItemPath() ?: "") { success ->
+ if (success) {
+ changeAlbumCover(useDefault)
+ }
}
}
@@ -494,11 +605,19 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList) {
val directories = newDirs.clone() as ArrayList
if (directories.hashCode() != currentDirectoriesHash) {
currentDirectoriesHash = directories.hashCode()
dirs = directories
+ fillLockedFolders()
notifyDataSetChanged()
finishActMode()
}
@@ -538,7 +657,15 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList()
foldersToScan.forEach {
val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, getProperFileSize, favoritePaths, getVideoDurations, false)
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ManageExtendedDetailsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ManageExtendedDetailsDialog.kt
index e1d6dbf18..6c52c3408 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ManageExtendedDetailsDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ManageExtendedDetailsDialog.kt
@@ -22,9 +22,7 @@ class ManageExtendedDetailsDialog(val activity: BaseSimpleActivity, val callback
manage_extended_details_date_taken.isChecked = details and EXT_DATE_TAKEN != 0
manage_extended_details_camera.isChecked = details and EXT_CAMERA_MODEL != 0
manage_extended_details_exif.isChecked = details and EXT_EXIF_PROPERTIES != 0
- manage_extended_details_duration.isChecked = details and EXT_DURATION != 0
- manage_extended_details_artist.isChecked = details and EXT_ARTIST != 0
- manage_extended_details_album.isChecked = details and EXT_ALBUM != 0
+ manage_extended_details_gps_coordinates.isChecked = details and EXT_GPS != 0
}
AlertDialog.Builder(activity)
@@ -54,12 +52,8 @@ class ManageExtendedDetailsDialog(val activity: BaseSimpleActivity, val callback
result += EXT_CAMERA_MODEL
if (manage_extended_details_exif.isChecked)
result += EXT_EXIF_PROPERTIES
- if (manage_extended_details_duration.isChecked)
- result += EXT_DURATION
- if (manage_extended_details_artist.isChecked)
- result += EXT_ARTIST
- if (manage_extended_details_album.isChecked)
- result += EXT_ALBUM
+ if (manage_extended_details_gps_coordinates.isChecked)
+ result += EXT_GPS
}
activity.config.extendedDetails = result
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
index 80b9a2f70..c29f1e6b3 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
@@ -76,7 +76,11 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
private fun showOtherFolder() {
FilePickerDialog(activity, sourcePath, false, showHidden, true, true) {
- callback(it)
+ activity.handleLockedFolderOpening(it) { success ->
+ if (success) {
+ callback(it)
+ }
+ }
}
}
@@ -100,7 +104,11 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
activity.toast(R.string.source_and_destination_same)
return@DirectoryAdapter
} else {
- callback(path)
+ activity.handleLockedFolderOpening(path) { success ->
+ if (success) {
+ callback(path)
+ }
+ }
dialog.dismiss()
}
} else {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
index 3e8d8e013..07615227b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
@@ -10,6 +10,7 @@ import android.graphics.Matrix
import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable
import android.media.ExifInterface
+import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.util.DisplayMetrics
@@ -190,9 +191,9 @@ fun BaseSimpleActivity.toggleFileVisibility(oldPath: String, hide: Boolean, call
val newPath = "$path/$filename"
renameFile(oldPath, newPath) {
callback?.invoke(newPath)
- Thread {
+ ensureBackgroundThread {
updateDBMediaPath(oldPath, newPath)
- }.start()
+ }
}
}
@@ -212,12 +213,12 @@ fun BaseSimpleActivity.tryDeleteFileDirItem(fileDirItem: FileDirItem, allowDelet
callback: ((wasSuccess: Boolean) -> Unit)? = null) {
deleteFile(fileDirItem, allowDeleteFolder) {
if (deleteFromDatabase) {
- Thread {
+ ensureBackgroundThread {
deleteDBPath(galleryDB.MediumDao(), fileDirItem.path)
runOnUiThread {
callback?.invoke(it)
}
- }.start()
+ }
} else {
callback?.invoke(it)
}
@@ -225,7 +226,7 @@ fun BaseSimpleActivity.tryDeleteFileDirItem(fileDirItem: FileDirItem, allowDelet
}
fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList, mediumDao: MediumDao = galleryDB.MediumDao(), callback: ((wasSuccess: Boolean) -> Unit)?) {
- Thread {
+ ensureBackgroundThread {
var pathsCnt = paths.size
paths.forEach {
val file = File(it)
@@ -246,7 +247,7 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList, mediumDao
}
}
callback?.invoke(pathsCnt == 0)
- }.start()
+ }
}
fun BaseSimpleActivity.restoreRecycleBinPath(path: String, callback: () -> Unit) {
@@ -254,7 +255,7 @@ fun BaseSimpleActivity.restoreRecycleBinPath(path: String, callback: () -> Unit)
}
fun BaseSimpleActivity.restoreRecycleBinPaths(paths: ArrayList, mediumDao: MediumDao = galleryDB.MediumDao(), callback: () -> Unit) {
- Thread {
+ ensureBackgroundThread {
val newPaths = ArrayList()
paths.forEach {
val source = it
@@ -288,26 +289,30 @@ fun BaseSimpleActivity.restoreRecycleBinPaths(paths: ArrayList, mediumDa
}
fixDateTaken(newPaths, false)
- }.start()
+ }
}
fun BaseSimpleActivity.emptyTheRecycleBin(callback: (() -> Unit)? = null) {
- Thread {
- recycleBin.deleteRecursively()
- galleryDB.MediumDao().clearRecycleBin()
- galleryDB.DirectoryDao().deleteRecycleBin()
- toast(R.string.recycle_bin_emptied)
- callback?.invoke()
- }.start()
+ ensureBackgroundThread {
+ try {
+ recycleBin.deleteRecursively()
+ galleryDB.MediumDao().clearRecycleBin()
+ galleryDB.DirectoryDao().deleteRecycleBin()
+ toast(R.string.recycle_bin_emptied)
+ callback?.invoke()
+ } catch (e: Exception) {
+ toast(R.string.unknown_error_occurred)
+ }
+ }
}
fun BaseSimpleActivity.emptyAndDisableTheRecycleBin(callback: () -> Unit) {
- Thread {
+ ensureBackgroundThread {
emptyTheRecycleBin {
config.useRecycleBin = false
callback()
}
- }.start()
+ }
}
fun BaseSimpleActivity.showRecycleBinEmptyingDialog(callback: () -> Unit) {
@@ -317,12 +322,12 @@ fun BaseSimpleActivity.showRecycleBinEmptyingDialog(callback: () -> Unit) {
}
fun BaseSimpleActivity.updateFavoritePaths(fileDirItems: ArrayList, destination: String) {
- Thread {
+ ensureBackgroundThread {
fileDirItems.forEach {
val newPath = "$destination/${it.name}"
updateDBMediaPath(it.path, newPath)
}
- }.start()
+ }
}
fun Activity.hasNavBar(): Boolean {
@@ -431,10 +436,6 @@ fun BaseSimpleActivity.saveRotatedImageToFile(oldPath: String, newPath: String,
saveFile(tmpPath, bitmap, it as FileOutputStream, newDegrees)
}
- if (File(newPath).exists()) {
- tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
- }
-
copyFile(tmpPath, newPath)
rescanPaths(arrayListOf(newPath))
fileRotatedSuccessfully(newPath, oldLastModified)
@@ -515,7 +516,7 @@ fun saveFile(path: String, bitmap: Bitmap, out: FileOutputStream, degrees: Int)
}
fun Activity.getShortcutImage(tmb: String, drawable: Drawable, callback: () -> Unit) {
- Thread {
+ ensureBackgroundThread {
val options = RequestOptions()
.format(DecodeFormat.PREFER_ARGB_8888)
.skipMemoryCache(true)
@@ -538,5 +539,36 @@ fun Activity.getShortcutImage(tmb: String, drawable: Drawable, callback: () -> U
runOnUiThread {
callback()
}
- }.start()
+ }
+}
+
+@TargetApi(Build.VERSION_CODES.N)
+fun Activity.showFileOnMap(path: String) {
+ val exif = try {
+ if (path.startsWith("content://") && isNougatPlus()) {
+ ExifInterface(contentResolver.openInputStream(Uri.parse(path)))
+ } else {
+ ExifInterface(path)
+ }
+ } catch (e: Exception) {
+ showErrorToast(e)
+ return
+ }
+
+ val latLon = FloatArray(2)
+ if (exif.getLatLong(latLon)) {
+ val uriBegin = "geo:${latLon[0]},${latLon[1]}"
+ val query = "${latLon[0]}, ${latLon[1]}"
+ val encodedQuery = Uri.encode(query)
+ val uriString = "$uriBegin?q=$encodedQuery&z=16"
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uriString))
+ val packageManager = packageManager
+ if (intent.resolveActivity(packageManager) != null) {
+ startActivity(intent)
+ } else {
+ toast(R.string.no_app_found)
+ }
+ } else {
+ toast(R.string.unknown_location)
+ }
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
index 2298bfaaf..a27f32b1e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
@@ -358,7 +358,7 @@ fun Context.updateSubfolderCounts(children: ArrayList, parentDirs: Ar
}
fun Context.getNoMediaFolders(callback: (folders: ArrayList) -> Unit) {
- Thread {
+ ensureBackgroundThread {
val folders = ArrayList()
val uri = MediaStore.Files.getContentUri("external")
@@ -384,20 +384,20 @@ fun Context.getNoMediaFolders(callback: (folders: ArrayList) -> Unit) {
}
callback(folders)
- }.start()
+ }
}
fun Context.rescanFolderMedia(path: String) {
- Thread {
+ ensureBackgroundThread {
rescanFolderMediaSync(path)
- }.start()
+ }
}
fun Context.rescanFolderMediaSync(path: String) {
getCachedMedia(path) {
val cached = it
GetMediaAsynctask(applicationContext, path, false, false, false) {
- Thread {
+ ensureBackgroundThread {
val newMedia = it
val mediumDao = galleryDB.MediumDao()
val media = newMedia.filter { it is Medium } as ArrayList
@@ -411,15 +411,15 @@ fun Context.rescanFolderMediaSync(path: String) {
}
}
}
- }.start()
+ }
}.execute()
}
}
fun Context.storeDirectoryItems(items: ArrayList, directoryDao: DirectoryDao) {
- Thread {
+ ensureBackgroundThread {
directoryDao.insertAll(items)
- }.start()
+ }
}
fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet): String {
@@ -452,20 +452,21 @@ fun Context.loadImage(type: Int, path: String, target: MySquareImageView, horizo
loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths)
}
} else if (type == TYPE_GIFS) {
+ if (!animateGifs) {
+ loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
+ return
+ }
+
try {
val gifDrawable = GifDrawable(path)
target.setImageDrawable(gifDrawable)
- if (animateGifs) {
- gifDrawable.start()
- } else {
- gifDrawable.stop()
- }
+ gifDrawable.start()
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
} catch (e: Exception) {
- loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths)
+ loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
} catch (e: OutOfMemoryError) {
- loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths)
+ loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
}
} else if (type == TYPE_SVGS) {
loadSVG(path, target, cropThumbnails)
@@ -525,6 +526,22 @@ fun Context.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boo
.into(target)
}
+fun Context.loadStaticGIF(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList? = null) {
+ val options = RequestOptions()
+ .signature(path.getFileSignature())
+ .skipMemoryCache(skipMemoryCacheAtPaths?.contains(path) == true)
+ .priority(Priority.LOW)
+ .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
+
+ val builder = Glide.with(applicationContext)
+ .asBitmap() // make sure the GIF wont animate
+ .load(path)
+
+ if (cropThumbnails) options.centerCrop() else options.fitCenter()
+ builder.apply(options)
+ .into(target)
+}
+
fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
@@ -539,7 +556,7 @@ fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boo
}
fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, directoryDao: DirectoryDao = galleryDB.DirectoryDao(), forceShowHidden: Boolean = false, callback: (ArrayList) -> Unit) {
- Thread {
+ ensureBackgroundThread {
val directories = try {
directoryDao.getAll() as ArrayList
} catch (e: Exception) {
@@ -581,12 +598,12 @@ fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly:
callback(clone.distinctBy { it.path.getDistinctPath() } as ArrayList)
removeInvalidDBDirectories(filteredDirectories, directoryDao)
- }.start()
+ }
}
fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, mediumDao: MediumDao = galleryDB.MediumDao(),
callback: (ArrayList) -> Unit) {
- Thread {
+ ensureBackgroundThread {
val mediaFetcher = MediaFetcher(this)
val foldersToScan = if (path.isEmpty()) mediaFetcher.getFoldersToScan() else arrayListOf(path)
var media = ArrayList()
@@ -599,7 +616,7 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag
}
val shouldShowHidden = config.shouldShowHidden
- foldersToScan.forEach {
+ foldersToScan.filter { path.isNotEmpty() || !config.isFolderProtected(it) }.forEach {
try {
val currMedia = mediumDao.getMediaFromPath(it)
media.addAll(currMedia)
@@ -644,13 +661,16 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag
}
} catch (ignored: Exception) {
}
- }.start()
+ }
}
fun Context.removeInvalidDBDirectories(dirs: ArrayList? = null, directoryDao: DirectoryDao = galleryDB.DirectoryDao()) {
val dirsToCheck = dirs ?: directoryDao.getAll()
dirsToCheck.filter { !it.areFavorites() && !it.isRecycleBin() && !File(it.path).exists() && it.path != config.tempFolderPath }.forEach {
- directoryDao.deleteDirPath(it.path)
+ try {
+ directoryDao.deleteDirPath(it.path)
+ } catch (ignored: Exception) {
+ }
}
}
@@ -768,9 +788,9 @@ fun Context.parseFileChannel(path: String, fc: FileChannel, level: Int, start: L
}
fun Context.addPathToDB(path: String) {
- Thread {
+ ensureBackgroundThread {
if (!File(path).exists()) {
- return@Thread
+ return@ensureBackgroundThread
}
val type = when {
@@ -791,7 +811,7 @@ fun Context.addPathToDB(path: String) {
mediumDao.insert(medium)
} catch (ignored: Exception) {
}
- }.start()
+ }
}
fun Context.createDirectoryFromMedia(path: String, curMedia: ArrayList, albumCovers: ArrayList, hiddenString: String,
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
index 71c78ff0c..fc80387e9 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
@@ -36,6 +36,7 @@ import com.davemorrissey.labs.subscaleview.ImageRegionDecoder
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaPhotoActivity
import com.simplemobiletools.gallery.pro.activities.PhotoActivity
@@ -241,10 +242,10 @@ class PhotoFragment : ViewPagerFragment() {
mLoadZoomableViewHandler.removeCallbacksAndMessages(null)
if (mCurrentRotationDegrees != 0) {
- Thread {
+ ensureBackgroundThread {
val path = mMedium.path
(activity as? BaseSimpleActivity)?.saveRotatedImageToFile(path, path, mCurrentRotationDegrees, false) {}
- }.start()
+ }
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
index a7829beea..1f14eef95 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/VideoFragment.kt
@@ -24,6 +24,7 @@ import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.upstream.FileDataSource
import com.simplemobiletools.commons.extensions.*
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity
import com.simplemobiletools.gallery.pro.activities.VideoActivity
@@ -139,12 +140,12 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
initTimeHolder()
checkIfPanorama()
- Thread {
+ ensureBackgroundThread {
activity?.getVideoResolution(mMedium.path)?.apply {
mVideoSize.x = x
mVideoSize.y = y
}
- }.start()
+ }
if (mIsPanorama) {
mView.apply {
@@ -657,10 +658,10 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun releaseExoPlayer() {
mExoPlayer?.stop()
- Thread {
+ ensureBackgroundThread {
mExoPlayer?.release()
mExoPlayer = null
- }.start()
+ }
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {}
@@ -670,9 +671,9 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
- Thread {
+ ensureBackgroundThread {
mExoPlayer?.setVideoSurface(Surface(mTextureView.surfaceTexture))
- }.start()
+ }
}
private fun setVideoSize() {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/ViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/ViewPagerFragment.kt
index d6df0add0..885af7016 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/ViewPagerFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/ViewPagerFragment.kt
@@ -1,5 +1,6 @@
package com.simplemobiletools.gallery.pro.fragments
+import android.media.ExifInterface
import android.provider.MediaStore
import android.view.MotionEvent
import androidx.fragment.app.Fragment
@@ -39,7 +40,7 @@ abstract class ViewPagerFragment : Fragment() {
}
val path = "${file.parent.trimEnd('/')}/"
- val exif = android.media.ExifInterface(medium.path)
+ val exif = ExifInterface(medium.path)
val details = StringBuilder()
val detailsFlag = context!!.config.extendedDetails
if (detailsFlag and EXT_NAME != 0) {
@@ -63,15 +64,19 @@ abstract class ViewPagerFragment : Fragment() {
}
if (detailsFlag and EXT_DATE_TAKEN != 0) {
- path.getExifDateTaken(exif, context!!).let { if (it.isNotEmpty()) details.appendln(it) }
+ exif.getExifDateTaken(context!!).let { if (it.isNotEmpty()) details.appendln(it) }
}
if (detailsFlag and EXT_CAMERA_MODEL != 0) {
- path.getExifCameraModel(exif).let { if (it.isNotEmpty()) details.appendln(it) }
+ exif.getExifCameraModel().let { if (it.isNotEmpty()) details.appendln(it) }
}
if (detailsFlag and EXT_EXIF_PROPERTIES != 0) {
- path.getExifProperties(exif).let { if (it.isNotEmpty()) details.appendln(it) }
+ exif.getExifProperties().let { if (it.isNotEmpty()) details.appendln(it) }
+ }
+
+ if (detailsFlag and EXT_GPS != 0) {
+ getLatLonAltitude(medium.path).let { if (it.isNotEmpty()) details.appendln(it) }
}
return details.toString().trim()
}
@@ -93,6 +98,23 @@ abstract class ViewPagerFragment : Fragment() {
return ""
}
+ private fun getLatLonAltitude(path: String): String {
+ var result = ""
+ val exif = ExifInterface(path)
+ val latLon = FloatArray(2)
+
+ if (exif.getLatLong(latLon)) {
+ result = "${latLon[0]}, ${latLon[1]}"
+ }
+
+ val altitude = exif.getAltitude(0.0)
+ if (altitude != 0.0) {
+ result += ", ${altitude}m"
+ }
+
+ return result.trimStart(',').trim()
+ }
+
protected fun handleEvent(event: MotionEvent) {
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
index 45642f914..f4f514705 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
@@ -380,7 +380,7 @@ class Config(context: Context) : BaseConfig(context) {
}
fun saveLastVideoPosition(path: String, value: Int) {
- if (!path.isEmpty()) {
+ if (path.isNotEmpty()) {
prefs.edit().putInt("$LAST_VIDEO_POSITION_PREFIX${path.toLowerCase()}", value).apply()
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
index 8193e9de8..4b33ffecc 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
@@ -115,6 +115,7 @@ const val DRAG_THRESHOLD = 8
const val MONTH_MILLISECONDS = MONTH_SECONDS * 1000L
const val MIN_SKIP_LENGTH = 2000
const val HIDE_SYSTEM_UI_DELAY = 500L
+const val MAX_PRINT_SIDE_SIZE = 4096
const val DIRECTORY = "directory"
const val MEDIUM = "medium"
@@ -153,6 +154,7 @@ const val EXT_EXIF_PROPERTIES = 128
const val EXT_DURATION = 256
const val EXT_ARTIST = 512
const val EXT_ALBUM = 1024
+const val EXT_GPS = 2048
// media types
const val TYPE_IMAGES = 1
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
index a67a88468..67bc52291 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
@@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.pro.helpers
import android.content.Context
import android.database.Cursor
+import android.os.Environment
import android.provider.MediaStore
import android.text.format.DateFormat
import com.simplemobiletools.commons.extensions.*
@@ -45,7 +46,20 @@ class MediaFetcher(val context: Context) {
return try {
val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
- parseCursor(cursor)
+ val folders = parseCursor(cursor)
+
+ val priorityFolders = arrayListOf(
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString(),
+ "${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)}/Camera",
+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString()
+ ).filter { File(it).exists() }
+
+ folders.sortBy {
+ val folder = it
+ !priorityFolders.any { it.equals(folder, true) }
+ }
+
+ folders
} catch (e: Exception) {
ArrayList()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt
index 3b4ec5090..5ba0e3811 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt
@@ -14,6 +14,7 @@ import com.simplemobiletools.commons.extensions.getFileSignature
import com.simplemobiletools.commons.extensions.setBackgroundColor
import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setVisibleIf
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.MediaActivity
import com.simplemobiletools.gallery.pro.extensions.config
@@ -34,7 +35,7 @@ class MyWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
- Thread {
+ ensureBackgroundThread {
val config = context.config
context.widgetsDB.getWidgets().filter { appWidgetIds.contains(it.widgetId) }.forEach {
val views = RemoteViews(context.packageName, R.layout.widget).apply {
@@ -75,7 +76,7 @@ class MyWidgetProvider : AppWidgetProvider() {
setupAppOpenIntent(context, views, R.id.widget_holder, it)
appWidgetManager.updateAppWidget(it.widgetId, views)
}
- }.start()
+ }
}
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) {
@@ -85,10 +86,10 @@ class MyWidgetProvider : AppWidgetProvider() {
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
- Thread {
+ ensureBackgroundThread {
appWidgetIds.forEach {
context.widgetsDB.deleteWidgetId(it)
}
- }.start()
+ }
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/jobs/NewPhotoFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/jobs/NewPhotoFetcher.kt
index 07d24df9d..e00e2eb4f 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/jobs/NewPhotoFetcher.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/jobs/NewPhotoFetcher.kt
@@ -14,6 +14,7 @@ import android.os.Handler
import android.provider.MediaStore
import com.simplemobiletools.commons.extensions.getParentPath
import com.simplemobiletools.commons.extensions.getStringValue
+import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.extensions.addPathToDB
import com.simplemobiletools.gallery.pro.extensions.updateDirectoryPath
@@ -94,11 +95,11 @@ class NewPhotoFetcher : JobService() {
}
}
- Thread {
+ ensureBackgroundThread {
affectedFolderPaths.forEach {
updateDirectoryPath(it)
}
- }.start()
+ }
mHandler.post(mWorker)
return true
diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml
new file mode 100644
index 000000000..13f9fb57e
--- /dev/null
+++ b/app/src/main/res/layout/activity_search.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_manage_extended_details.xml b/app/src/main/res/layout/dialog_manage_extended_details.xml
index 4b42ab9b2..610b21304 100644
--- a/app/src/main/res/layout/dialog_manage_extended_details.xml
+++ b/app/src/main/res/layout/dialog_manage_extended_details.xml
@@ -78,36 +78,13 @@
android:paddingBottom="@dimen/activity_margin"
android:text="@string/exif"/>
-
-
-
-
-
-
+ android:text="@string/gps_coordinates"/>
diff --git a/app/src/main/res/layout/directory_item_grid.xml b/app/src/main/res/layout/directory_item_grid.xml
index 9f72281c9..75c2c8ba1 100644
--- a/app/src/main/res/layout/directory_item_grid.xml
+++ b/app/src/main/res/layout/directory_item_grid.xml
@@ -13,6 +13,20 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
+
+
+
+
+
+
+ app:showAsAction="always"/>
-
+
diff --git a/app/src/main/res/menu/menu_viewpager.xml b/app/src/main/res/menu/menu_viewpager.xml
index f995fe0f1..ed3dcc8ac 100644
--- a/app/src/main/res/menu/menu_viewpager.xml
+++ b/app/src/main/res/menu/menu_viewpager.xml
@@ -110,6 +110,10 @@
android:icon="@drawable/ic_rename_new"
android:title="@string/rename"
app:showAsAction="ifRoom"/>
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index fec865af6..01bb0576f 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
فلتر الميديا
@@ -64,10 +65,8 @@
المجلدات المضمنة
إدارة المجلدات المضمنة
اضافة مجلد
- إذا كان لديك بعض المجلدات التي تحتوي على الملتيميديا ، ولكن لم يتم التعرف عليها من قبل التطبيق، يمكنك إضافتها يدويا هنا.\n
+ إذا كان لديك بعض المجلدات التي تحتوي على الملتيميديا ، ولكن لم يتم التعرف عليها من قبل التطبيق، يمكنك إضافتها يدويا هنا.\n \n لن تؤدي إضافة بعض العناصر هنا إلى استبعاد أي مجلد آخر.
No media files have been found. You can solve it by adding the folders containing media files manually.
- \n
- لن تؤدي إضافة بعض العناصر هنا إلى استبعاد أي مجلد آخر.
تحجيم
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index d621f25e5..1ac6d0f62 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filter media
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 030f3a19a..bf9787e1d 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -33,6 +33,7 @@
Data fixada correctament
Comparteix una versió redimensionada
Hola,\n\nsembla que heu actualitzat des de l\'antiga aplicació gratuïta. Ara podeu desinstal·lar la versió antiga, que té un botó "Actualitza a Pro" a la part superior de la configuració de l’aplicació.\nNomés s’eliminaran els elements de la paperera, els elements preferits sense marcar i també caldrà restablirla configuració de la vostra aplicació.\n\nGràcies!
+ Switch to file search across all visible folders
Filtre d’arxius
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 1ebb50c7c..b8567bbea 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -33,6 +33,7 @@
Datumy byly úspěšně opraveny
Sdílet verzi se změněnou velikostí
Zdravím,\n\nzdá se, že jse přešli ze staré bezplatné aplikace. Starou aplikaci, která má nahoře v nastavení tlačítko \'Stáhnout Pro verzi\', můžete již odinstalovat.\n\nZtratíte tím pouze soubory v odpadkovém koši, označení oblíbených souborů a také budete muset znovu nastavit položky v nastavení aplikace.\n\nDěkuji!
+ Switch to file search across all visible folders
Filtr médií
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index fdbede921..2682c13f4 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -33,6 +33,7 @@
Datoer fikset med succes
Del en skaleret version
Hej\n\nDet ser ud til at du har opgraderet fra den gamle, gratis app. Du kan afinstallere den gamle version, som har en \"Opgrader til Pro\"-knap i toppen af appens indstillinger.\n\nDu vil blot få papirkurvens elementer slettet, favoritter vil blive umarkeret og du vil også skulle genopsætte din apps indstillinger.\n\nTak!
+ Switch to file search across all visible folders
Filtrer medier
@@ -116,9 +117,9 @@
Kør baglæns
Endeløs kørsel
Animation
- None
- Fade
- Slide
+ Ingen
+ Udton
+ Glid
Slideshowet endte
Der blev ikke funket nogen mediefiler til slideshowet
@@ -133,11 +134,11 @@
Gruppér ikke filer
Mappe
Sidst ændret
- Last modified (daily)
- Last modified (monthly)
+ Sidst ændret (daglig)
+ Sidst ændret (månedlig)
Eksponeringsdato
- Date taken (daily)
- Date taken (monthly)
+ Eksponeringsdato (daglig)
+ Eksponeringsdato (månedlig)
Filtype
Filendelse
Vær opmærksom på at gruppering og sortering er to individuelle felter
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index f2e8d74bf..ee4ff9d73 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -33,6 +33,7 @@
Datum erfolgreich korrigiert.
Teile eine verkleinerte Version
Hey,\n\nes sieht so aus, als hättest du von der alten kostenlosen App geupgraded. Du kannst nun die alte Version deinstallieren, die oben in den App-Einstellungen einen \'Upgrade auf Pro\' Button hat.\n\nEs wird nur der Papierkorb gelöscht, die Markierungen von Favoriten entfernt und die App-Einstellungen zurückgesetzt.\n\nDanke!
+ Switch to file search across all visible folders
Filter
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index cd2a4ef12..edb16f124 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -33,6 +33,7 @@
Η Ημερ. διορθώθηκε με επιτυχία
Διαμοιρασμός έκδοσης με αλλαγμένο μέγεθος
Γειά σας,\n\nΦαίνεται πως αναβαθμίσατε από την παλιά δωρεάν εφαρμογή. Τώρα θα πρέπει να απεγκαταστήσετε την παλιά έκδοση, απο το πλήκτρο \"Αναβάθμιση σε Pro\" στο επάνω των ρυθμίσεων της εφαρμογής.\n\nΘα πρέπει να διαγράψετε μόνο τα αντικείμενα του Κάδου, πρέπει να επαναφέρετε τα αγαπημένα στοιχεία που δεν έχουν επισημανθεί καθώς και τις ρυθμίσεις της εφαρμογής σας.\n\nΣας ευχαριστώ!
+ Switch to file search across all visible folders
Φιλτράρισμα πολυμέσων
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index ee6efe0bc..5497765f9 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -33,6 +33,7 @@
Fecha fijada correctamente
Comparte una versión redimensionada
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtro de medios
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 737c12e5c..1b240e4c0 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Suodata media
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 0e0a9a9ba..6303baf9c 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -17,9 +17,9 @@
Position inconnue
Ajouter une colonne
Supprimer une colonne
- Changer l\'image de vignette
- Sélectionner une image
- Utiliser par défaut
+ Changer l\'image du dossier
+ Choisir une image
+ Image par défaut
Volume
Luminosité
Verrouiller la rotation
@@ -33,6 +33,7 @@
Dates corrigées
Partager une version redimensionnée
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtrer les médias
@@ -133,14 +134,14 @@
Ne pas grouper les fichiers
Dossier
Date de modification
- Last modified (daily)
- Last modified (monthly)
+ Date de modification (par jour)
+ Date de modification (par mois)
Date de prise de vue
- Date taken (daily)
- Date taken (monthly)
+ Date de prise de vue (par jour)
+ Date de prise de vue (par mois)
Type de fichier
Extension
- Notez que grouper et trier sont 2 modes de tri indépendants
+ Notez que \'Grouper par\' et \'Trier par\' sont 2 modes indépendants
Dossier affiché sur le widget :
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index a01d46cc3..dc475d665 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtrar medios
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index cd8831065..4166fa6f2 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -33,6 +33,7 @@
Datumi uspješno popravljeni
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtriranje medija
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 95b0f32cf..07fc40b2b 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -33,6 +33,7 @@
Sikeres dátum javítás
Átméretezett verzió megosztása
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Média szűrő
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
index 34eb6a5af..04851828f 100644
--- a/app/src/main/res/values-id/strings.xml
+++ b/app/src/main/res/values-id/strings.xml
@@ -33,6 +33,7 @@
Tanggal berhasil diperbaiki
Bagikan versi yang diubah ukurannya
Hai,\n\nsepertinya anda memperbarui dari aplikasi gratis versi lama. Anda sekarang bisa mencopot versi yang lama, yang ada tombol \'Tingkatkan ke Pro\' di bagian atas pengaturan aplikasi.\n\nHanya item Keranjang sampah yang akan dihapus, item favorit menjadi tak bertanda dan anda juga harus menyetel ulang pengaturan aplikasi.\n\nThanks!
+ Switch to file search across all visible folders
Filter media
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
new file mode 100644
index 000000000..04851828f
--- /dev/null
+++ b/app/src/main/res/values-in/strings.xml
@@ -0,0 +1,297 @@
+
+
+ Simple Gallery
+ Galeri
+ Sunting
+ Buka kamera
+ (tersembunyi)
+ (dikecualikan)
+ Pin folder
+ Lepas pin folder
+ Pin ke atas
+ Tampilkan semua isi folder
+ Semua folder
+ Beralih ke tampilan folder
+ Folder lain
+ Tampilkan di peta
+ Lokasi tidak diketahui
+ Tambah jumlah kolom
+ Kurangi jumlah kolom
+ Ubah sampul
+ Pilih foto
+ Gunakan default
+ Volume
+ Kecerahan
+ Kunci rotasi
+ Aktifkan rotasi
+ Ubah orientasi
+ Paksa potret
+ Paksa lanskap
+ Gunakan orientasi default
+ Perbaiki Tanggal Diambil
+ Memperbaiki…
+ Tanggal berhasil diperbaiki
+ Bagikan versi yang diubah ukurannya
+ Hai,\n\nsepertinya anda memperbarui dari aplikasi gratis versi lama. Anda sekarang bisa mencopot versi yang lama, yang ada tombol \'Tingkatkan ke Pro\' di bagian atas pengaturan aplikasi.\n\nHanya item Keranjang sampah yang akan dihapus, item favorit menjadi tak bertanda dan anda juga harus menyetel ulang pengaturan aplikasi.\n\nThanks!
+ Switch to file search across all visible folders
+
+
+ Filter media
+ Gambar
+ Video
+ GIF
+ Gambar RAW
+ SVG
+ Tidak ada berkas media ditemukan dari filter ini.
+ Ubah filter
+
+
+ Fungsi ini menyembunyikan folder dengan menambahkan berkas \'.nomedia\' ke dalamnya, juga akan menyembunyikan semua subfolder. Anda bisa melihatnya dari opsi \'Tampilkan berkas tersembunyi\' di Pengaturan. Lanjutkan?
+ Kecualikan
+ Folder yang dikecualikan
+ Atur folder yang dikecualikan
+ Ini hanya akan mengecualikan pilihan bersama dengan subfoldernya di Simple Gallery. Anda bisa mengatur pengecualian di Pengaturan.
+ Kecualikan folder induk?
+ Mengecualikan folder akan membuatnya bersama subfoldernya tersembunyi hanya di Simple Gallery, namun masih bisa dilihat di aplikasi lain.\n\nJika anda ingin menyembunyikannya dari aplikasi lain juga, gunakan fitur Sembunyikan.
+ Bersihkan daftar
+ Hapus semua folder dari daftar pengecualian? Ini tidak akan menghapus folder tersebut.
+ Folder tersembunyi
+ Atur folder tersembunyi
+ Sepertinya tidak ada folder tersembunyi dengan berkas \".nomedia\" didalamnya.
+
+
+ Folder yang disertakan
+ Atur folder yang disertakan
+ Tambah folder
+ Jika ada folder yang berisi berkas media, namun tidak dikenali oleh aplikasi ini, anda bisa menambahkannya disini secara manual.\n\nMenambah beberapa item disini tidak akan mengecualikan folder yang lain.
+ Tidak ada berkas media yang ditemukan. Anda bisa memperbaikinya dengan menambahkan folder yang berisi berkas media secara manual.
+
+
+ Ubah ukuran
+ Ubah ukuran terpilih dan simpan
+ Lebar
+ Tinggi
+ Jaga aspek rasio
+ Harap masukkan resolusi dengan benar
+
+
+ Penyunting
+ Simpan
+ Rotasi
+ Jalur
+ Jalur gambar tidak valid
+ Gagal menyunting gambar
+ Sunting dengan:
+ Tidak ada aplikasi penyunting gambar
+ Lokasi berkas tidak diketahui
+ Tidak bisa mengganti berkas sumber
+ Putar ke kiri
+ Putar ke kanan
+ Putar 180º
+ Balik
+ Balik horizontal
+ Balik vertikal
+ Bebas
+ Lainnya
+
+
+ Simple Wallpaper
+ Setel wallpaper
+ Gagal menyetel sebagai wallpaper
+ Setel wallpaper dengan:
+ Menyetel wallpaper…
+ Wallpaper berhasil disetel
+ Aspek rasio potret
+ Aspek rasio lanskap
+ Layar beranda
+ Layar kunci
+ Beranda dan layar kunci
+
+
+ Slideshow
+ Interval (detik):
+ Sertakan foto
+ Sertakan video
+ Sertakan GIF
+ Urutan acak
+ Mundur
+ Slideshow tanpa henti
+ Animation
+ None
+ Fade
+ Slide
+ Slideshow berakhir
+ Tidak ditemukan media untuk slideshow
+
+
+ Ubah jenis tampilan
+ Kotak
+ Daftar
+ Kelompokkan subfolder langsung
+
+
+ Kelompokkan menurut
+ Jangan kelompokkan berkas
+ Folder
+ Terakhir diubah
+ Last modified (daily)
+ Last modified (monthly)
+ Tanggal diambil
+ Date taken (daily)
+ Date taken (monthly)
+ Jenis berkas
+ Ekstensi
+ Harap dicatat bahwa mengelompokkan dan mengurutkan adalah 2 ruas yang berbeda
+
+
+ Folder yang ditampilkan pada widget:
+ Tampilkan nama folder
+
+
+ Putar video otomatis
+ Ingat posisi pemutaran terakhir
+ Tampil/sembunyikan nama berkas
+ Ulangi video
+ Animasi GIF di thumbnail
+ Kecerahan maksimal saat melihat di layar penuh
+ Pangkas thumbnail menjadi persegi
+ Tampilkan durasi video
+ Rotasi layar penuh dari
+ Pengaturan sistem
+ Rotasi perangkat
+ Aspek rasio
+ Background dan status bar hitam saat layar penuh
+ Gulir thumbnail secara horizontal
+ Otomatis sembunyikan sistem UI saat layar penuh
+ Hapus folder kosong setelah menghapus isinya
+ Izinkan mengontrol kecerahan foto dengan gerakan vertikal
+ Izinkan mengontrol kecerahan dan volume video dengan gerakan vertikal
+ Tampilkan jumlah folder media di tampilan utama
+ Tampilkan detail tambahan saat layar penuh
+ Atur detail tambahan
+ Izinkan zoom satu jari di layar penuh
+ Izinkan mengganti media dengan mengklik sisi layar
+ Izinkan zoom gambar lebih dalam
+ Sembunyikan detail tambahan ketika status bar disembunyikan
+ Tampilkan beberapa tombol tindakan dibawah layar
+ Tampilkan Sampah di layar folder
+ Zoom gambar mendalam
+ Tampilkan gambar dalam kualitas tertinggi
+ Tampilkan Sampah sebagai item terakhir di layar utama
+ Izinkan keluar dari layar penuh dengan menggeser kebawah
+ Izinkan pembesaran 1:1 dengan dua kali ketuk
+ Selalu buka video pada layar terpisah dengan gestur horizontal baru
+ Tampilkan notch jika tersedia
+ Izinkan memutar gambar dengan gestur
+ Prioritas pemuatan berkas
+ Kecepatan
+ Kompromi
+ Hindari menampilkan berkas yang tidak valid
+
+
+ Thumbnail
+ Media layar penuh
+ Detail tambahan
+ Tindakan bawah
+
+
+ Sesuaikan tombol tindakan bawah
+ Favorit
+ Tampil/sembunyikan berkas
+
+
+ Bagaimana cara menjadikan Simple Gallery sebagai aplikasi galeri default?
+ Pertama anda harus menemukan galeri default saat ini di bagian Aplikasi di Pengaturan perangkat, lihatlah tombol yang seperti \"Buka secara default\", klik itu, lalu pilih \"Hapus default\".
+ Lain kali anda mencoba membuka gambar atau video, anda akan disuruh memilih aplikasi, dan anda bisa memilih Simple Gallery dan menjadikannya default.
+ Saya mengunci aplikasi dengan sandi, tapi saya lupa. Apa yang harus dilakukan?
+ Anda bisa menyelesaikannya dengan 2 cara. Anda bisa pasang ulang aplikasi, atau cari aplikasi ini di Pengaturan perangkat dan pilih \"Hapus data\". Ini akan menyetel ulang semua pengaturan anda, dan tidak akan menghapus berkas media apapun.
+ Bagaimana agar sebuah album selalu muncul paling atas di daftar?
+ Anda bisa menekan lama album tersebut dan pilih ikon Pin di menu tindakan, itu akan menaruhnya di atas daftar. Anda juga bisa menyematkan beberapa folder, item yang di-pin akan diurutkan berdasarkan metode urutan default.
+ Bagaimana cara mempercepat laju video?
+ You can either drag your finger horizontally over the video player, or click on the current or max duration texts near the seekbar. That will move the video either backward, or forward.
+ Apa perbedaan antara menyembunyikan dan mengecualikan folder?
+ Mengecualikan tidak akan menampilkan folder di Simple Gallery, sedangkan Sembunyikan bekerja sesuai aturan sistem dan akan menyembunyikan folder juga dari aplikasi galeri yang lain. Cara kerjanya dengan membuat berkas \".nomedia\" kosong pada folder yang diinginkan, yang bisa anda hapus juga dengan aplikasi pengelola berkas.
+ Mengapa folder dengan gambar album musik atau stiker muncul?
+ Kadang anda melihat beberapa album yang tidak biasa muncul. Anda bisa dengan mudah menyembunyikannya dengan menekan lama dan pilih Kecualikan. Pada dialog berikutnya, anda lalu bisa memilih folder induk, yang akan mencegah album terkait muncul kembali.
+ Ada folder berisi gambar namun tidak muncul, apa yang harus dilakukan?
+ Itu bisa disebabkan berbagai alasan, namun solusinya mudah. Pergi ke Pengaturan -> Atur folder yang disertakan, pilih Tambah dan cari folder yang diinginkan.
+ Bagaimana jika saya hanya ingin beberapa folder saja yang terlihat?
+ Menambahkan folder di Folder yang Disertakan tidak otomatis mengecualikan folder yang lain. Yang bisa anda lakukan adalah pergi ke Pengaturan -> Atur Folder yang Dikecualikan, lalu kecualikan folder root \"/\", lalu tambahkan folder yang diinginkan di Pengaturan -> Atur Folder yang Disertakan.
+ Itu akan membuat folder yang dipilih saja yang muncul, dan jika sebuah folder disertakan dan dikecualikan secara bersamaan, folder tersebut akan muncul.
+ Bisakah saya meng-crop gambar dengan aplikasi ini?
+ Ya, anda bisa melakukannya di Penyunting, dengan menyeret sudut gambar. Anda bisa masuk ke penyunting dengan menekan lama thumbnail gambar dan memilih Sunting, atau pilih Sunting dari tampilan layar penuh.
+ Bisakah saya mengelompokkan thumbnail berkas media?
+ Bisa, gunakan menu \"Kelompokkan menurut\" pada tampilan thumbnail. Anda bisa mengelompokkan berkas dengan berbagai kriteria, termasuk Tanggal Diambil. Jika anda menggunakan fungsi \"Tampilkan semua isi folder\", anda juga bisa mengelompokkan berdasarkan foldernya.
+ Tidak bisa mengurutkan berdasarkan Tanggal Diambil, bagaimana cara memperbaikinya?
+ Itu umumnya disebabkan karena berkas yang disalin dari tempat lain. Anda bisa memperbaikinya dengan memilih berkas thumbnail dan pilih \"Perbaiki Tanggal Diambil\".
+ Saya melihat beberapa pita warna pada gambar. Bagaimana saya meningkatkan kualitasnya?
+ Solusi saat ini untuk menampilkan gambar berfungsi dengan baik dalam sebagian besar kasus, namun jika anda ingin kualitas gambar yang lebih baik, anda bisa mengaktifkan \"Tampilkan gambar dalam kualitas tertinggi\" di pengaturan aplikasi, pada bagian \"Zoom gambar mendalam\".
+ Saya punya berkas/folder tersembunyi. Bagaimana cara memunculkannya?
+ Anda bisa memilih menu \"Tampilkan sementara berkas tersembunyi\" di layar utama, atau \"Tampilkan berkas tersembunyi\" di pengaturan aplikasi untuk menampilkannya. Jika anda tidak ingin menyembunyikannya, tekan lama dan pilih \"Jangan sembunyikan\". Folder disembunyikan dengan menambahkan berkas \".nomedia\" di dalamnya, anda bisa menghapus berkas tersebut dengan aplikasi pengelola berkas.
+ Kenapa aplikasi menggunakan sangat banyak ruang kosong?
+ Cache aplikasi bisa mencapai 250MB, ini untuk menjamin pemuatan gambar yang lebih cepat. Jika aplikasi menggunakan lebih banyak lagi ruang kosong, sangat memungkinkan anda memiliki item di dalam Keranjang Sampah. Berkas tersebut akan menambah ukuran aplikasi. Anda bisa mengosongkan Keranjang sampah dengan cara membukanya dan menghapus semua berkas, atau dari pengaturan aplikasi. Semua berkas di dalam keranjang sampah akan otomatis dihapus setelah 30 hari.
+
+
+
+ Simple Gallery Pro: Pengelola & Penyunting Foto
+
+ Galeri luring tanpa iklan. Kelola, sunting, pulihkan dan lindungi foto & video
+
+ Simple Gallery Pro adalah aplikasi galeri luring yang sangat mudah diubahsuai. Mengelola & menyunting foto anda, memulihkan berkas yang terhapus dari keranjang sampah, melindungi & menyembunyikan berkas, dan menampilkan banyak format foto & video, diantaranya RAW, SVG dan masih banyak lainnya.
+
+ Aplikasi sama sekali tidak berisi iklan dan tidak membutuhkan perizinan yang tidak perlu. Dan karena aplikasi juga tidak membutuhkan akses internet, privasi anda terlindungi.
+
+ -------------------------------------------------
+ SIMPLE GALLERY PRO – FEATURES
+ -------------------------------------------------
+
+ • Offline gallery with no ads or popups
+ • Simple gallery photo editor – crop, rotate, resize, draw, filters & more
+ • No internet access needed, giving you more privacy and security
+ • No unnecessary permissions required
+ • Quickly search images, videos & files
+ • Open & view many different photo and video types (RAW, SVG, panoramic etc)
+ • A variety of intuitive gestures to easily edit & organize files
+ • Lots of ways to filter, group & sort files
+ • Customize the appearance of Simple Gallery Pro
+ • Available in 32 languages
+ • Mark files as favorites for quick access
+ • Protect your photos & videos with a pattern, pin or fingerprint
+ • Use pin, pattern & fingerprint to protect the app launch or specific functions too
+ • Recover deleted photos & videos from the recycle bin
+ • Toggle visibility of files to hide photos & videos
+ • Create a customizable slideshow of your files
+ • View detailed information of your files (resolution, EXIF values etc)
+ • Simple Gallery Pro is open source
+ … and much much more!
+
+ PHOTO GALLERY EDITOR
+ Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If you’re feeling a little more creative you can add filters and draw on your pictures!
+
+ SUPPORT FOR MANY FILE TYPES
+ Unlike some other gallery viewers & photo organizers, Simple Gallery Pro supports a huge range of different file types including JPEG, PNG, MP4, MKV, RAW, SVG, Panoramic photos, Panoramic videos and many more.
+
+ HIGHLY CUSTOMIZABLE GALLERY MANAGER
+ From the UI to the function buttons on the bottom toolbar, Simple Gallery Pro is highly customizable and works the way you want it to. No other gallery manager has this kind of flexibility! Thanks to being open source, we’re also available in 32 languages!
+
+ RECOVER DELETED PHOTOS & VIDEOS
+ Accidentally deleted a precious photo or video? Don’t worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos & videos easily.
+
+ PROTECT & HIDE PHOTOS, VIDEOS & FILES
+ Using pin, pattern or your device’s fingerprint scanner you can protect and hide photos, videos & entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you can’t delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
+
+ Check out the full suite of Simple Tools here:
+ https://www.simplemobiletools.com
+
+ Facebook:
+ https://www.facebook.com/simplemobiletools
+
+ Reddit:
+ https://www.reddit.com/r/SimpleMobileTools
+
+
+
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 4ca5ac135..8dc06e8e7 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -33,6 +33,7 @@
Date aggiornate correttamente
Condividi una versione ridimensionata
Hey,\n\nhai aggiornato dalla vecchia versione gratuita. Puoi disinstallare le vecchia versione, che ha un pulsante \'Aggiorna a Pro\' in alto nelle impostazioni.\n\nNon potrai recuperare gli elementi dal cestino, gli elementi marcati come preferiti e dovrai anche reimpostare le impostazioni dell\'app.\n\nGrazie!
+ Switch to file search across all visible folders
Filtra i file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index b21bf6e15..e5b135a5f 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -33,6 +33,7 @@
撮影日が正常に修正されました
リサイズした画像を共有
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
表示する形式
@@ -115,10 +116,10 @@
ランダムな順序
逆方向に進む
スライドショーをリピート再生する
- Animation
- None
- Fade
- Slide
+ アニメーション
+ なし
+ フェード
+ スライド
スライドショーが終了しました
スライドショーに表示するメディアがありません
@@ -133,11 +134,11 @@
何もしない
フォルダ
更新日時
- Last modified (daily)
- Last modified (monthly)
+ 更新日時 (毎日)
+ 更新日時 (毎月)
撮影日時
- Date taken (daily)
- Date taken (monthly)
+ 撮影日時 (毎日)
+ 撮影日時 (毎月)
ファイル形式
拡張子
Please note that grouping and sorting are 2 independent fields
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index d2362a199..a29c3a84b 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
미디어 필터 설정
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 564b12e21..722e243e6 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtruoti mediją
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 6d4737cb1..54bff70f5 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -33,6 +33,7 @@
Datoer er korrigerte
Del versjon med endret størrelse
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtrer media
@@ -63,7 +64,7 @@
Håndter inkluderte mapper
Legg til mappe
Hvis du har noen mapper som inneholder media, men ikke ble gjenkjent av appen, kan du legge dem til manuelt her.\n\nÅ legge til noen elementer her, ekskluderer ikke noen annen mappe.
- No media files have been found. You can solve it by adding the folders containing media files manually.
+ Ingen mediafiler er funnet. Dette kan løses ved å legge til mapper som inneholder mediafiler manuelt.
Endre størrelse
@@ -115,8 +116,8 @@
Tilfeldig rekkefølge
Avspill bakover
Gjenta lysbildeshow
- Animation
- None
+ Animasjon
+ Ingen
Fade
Slide
Lysbildeshowet er slutt
@@ -133,11 +134,11 @@
Ikke grupper filer
Mappe
Sist endret
- Last modified (daily)
- Last modified (monthly)
+ Sist endret (daglig)
+ Sist endret (månedlig)
Dato tatt
- Date taken (daily)
- Date taken (monthly)
+ Dato tatt (daglig)
+ Dato tatt (månedlig)
Filtype
Endelse
Vær oppmerksom på at gruppering og sortering er to uavhengige områder
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index f84455f71..b6c57fe11 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -33,6 +33,7 @@
Datums zijn gecorrigeerd
Verkleinde versie delen
Het lijkt erop dat dit een upgrade is vanaf de oude gratis versie. Deze oude versie, met de knop \"Upgraden naar Pro\" bovenaan de instellingen, kan nu gedeïnstalleerd worden.\n\nDe items in de prullenbak zullen dan wel worden verwijderd, favorieten en instellingen zullen ook opnieuw moeten worden geconfigureerd.
+ Switch to file search across all visible folders
Media filteren
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 721e90ec2..2b7558c3e 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -33,6 +33,7 @@
Daty zostały naprawione
Udostępnij zmienioną wersję
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtruj multimedia
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 032c07b49..54ca44e02 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,13 +1,13 @@
- Simple Gallery
+ Simple Galeria
Galeria
Editar
Abrir câmera
(oculto)
(excluído)
Fixar pasta
- Desfixar pasta
+ Desafixar pasta
Fixar no topo
Mostrar conteúdo de todas as pastas
Todas as pastas
@@ -24,46 +24,47 @@
Brilho
Travar orientação
Destravar orientação
- Mudar orientação
+ Alterar orientação
Forçar modo retrato
Forçar modo paisagem
Usar orientação padrão
- Fix Date Taken value
- Fixing…
- Dates fixed successfully
- Share a resized version
- Hey,\n\nparece que você atualizou o antigo aplicativo gratuito. Agora você poderá desinstalar a velha versão que tem o botão \'Atualize para a versão Pro\' no topo das Configurações.\n\nVocê terá os itens da Lixeira excluídos, itens favoritos desmarcados e também terá que redefinir as configurações do seu aplicativo.\n\nObrigado!
+ Corrigir data da foto
+ Corrigindo…
+ Datas corrigidas com sucesso
+ Compartilhar uma versão redimensionada
+ Olá,\n\nparece que você atualizou o antigo aplicativo gratuito. Agora você poderá desinstalar a velha versão que tem o botão de atualizar para a versão Pro no topo das Configurações.\n\nVocê terá os itens da Lixeira excluídos, itens favoritos desmarcados e também terá que redefinir as configurações do seu aplicativo.\n\nObrigado!
+ Switch to file search across all visible folders
Filtrar mídia
Imagens
Vídeos
GIFs
- RAW images
+ Imagens RAW
SVGs
Nenhum arquivo de mídia encontrado a partir dos filtros selecionados.
- Mudar filtros
+ Alterar filtros
- Esta opção oculta uma pasta com a adição de um arquivo \'.nomedia\' dentro dela, e irá ocultar todas as subpastas que estejam dentro da mesma. Você poderá rever essas pastas com a opção \'Mostrar pastas ocultas\'. Continuar?
- Excluir
- Pastas excluídas
- Gerenciar pastas excluídas
- Esta ação irá excluir as pastas selecionadas apenas dentro deste aplicativo. Você pode gerenciar as pastas excuídas nas Configurações do aplicativo.
- Excluir antes a pasta raiz?
- A exclusão de uma pasta apenas oculta o seu conteúdo da galeria, pois todos os outros aplicativos poderão acessá-las.\\n\\nSe quiser ocultar de todos os aplicativos, utilize a função ocultar.
+ Esta opção oculta a pasta com a adição de um arquivo \".nomedia\" dentro dela, o que também ocultará todas as subpastas que estejam dentro da mesma. Você poderá voltar a exibir estas pastas com a opção \"Mostrar pastas ocultas\". Continuar?
+ Ignorar
+ Pastas ignoradas
+ Gerenciar pastas ignoradas
+ Esta ação deixará de exibir as pastas selecionadas apenas dentro deste aplicativo. Você pode gerenciar as pastas ignoradas nas Configurações do aplicativo.
+ Ignorar a pasta raiz ao invés desta?
+ Ignorar uma pasta apenas deixa de exibi-la nesta galeria. Ela continuará visível para outros aplicativos.\\n\\nSe você quiser ocultar a pasta para todos os aplicativos, utilize a função ocultar.
Remover todas
- Remover todas as pastas da lista de exclusões? Esta ação não apaga as pastas.
+ Remover todas as pastas da lista de pastas ignoradas? Esta ação não exclui as pastas.
Pastas ocultas
Gerenciar pastas ocultas
- Parece que você não tem nenhuma pasta oculta com um arquivo \".nomedia\".
+ Parece que você não tem nenhuma pasta ocultada por um arquivo \".nomedia\".
Pastas incluídas
Gerenciar pastas incluídas
Adicionar pasta
- Se possuir pastas com dados multimídia não reconhecidos pelo aplicativo, aqui você pode adicioná-las manualmente.
- No media files have been found. You can solve it by adding the folders containing media files manually.
+ Se você possuir pastas com dados multimídia não reconhecidos pelo aplicativo, aqui você pode adicioná-las manualmente.
+ Nenhum arquivo de mídia foi encontrado. Como alternativa você pode tentar incluir manualmente as pastas com arquivos de mídia.
Redimensionar
@@ -90,16 +91,16 @@
Inverter
Horizontalmente
Verticalmente
- Gratuito
+ Livre
Outro
- Simple Wallpaper
+ Simple Papel de Parede
Definir como papel de parede
Falha ao definir como papel de parede
Definir papel de parede com:
Definindo como papel de parede
- Papel de parede com sucesso
+ Papel de parede definido com sucesso
Retrato
Paisagem
Tela inicial
@@ -110,15 +111,15 @@
Apresentação
Intervalo (segundos):
Incluir fotos
- Incluir videos
+ Incluir vídeos
Incluir GIFs
Ordem aleatória
Retroceder
Apresentação em ciclo
- Animation
- None
- Fade
- Slide
+ Animação
+ Nenhuma
+ Esmaecer
+ Deslizar
Fim da apresentação
Nenhuma mídia encontrada para a apresentação
@@ -126,24 +127,24 @@
Alterar modo de visualização
Grade
Lista
- Agrupar subpastas do diretório
+ Agrupar subpastas diretas
Agrupar por
Não agrupar arquivos
Pasta
Última modificação
- Last modified (daily)
- Last modified (monthly)
- Data de criação
- Date taken (daily)
- Date taken (monthly)
+ Última modificação (por dia)
+ Última modificação (por mês)
+ Data da foto
+ Data da foto (por dia)
+ Data da foto (por mês)
Tipo de arquivo
Extensão
- Por favor, note que o agrupamento e classificação são 2 campos independentes
+ Por favor, lembre-se que o agrupamento e classificação são configurados por dois campos independentes
- Exibição da Pasta no widget:
+ Pasta exibida no widget:
Exibir nome da pasta
@@ -151,135 +152,132 @@
Lembrar da última posição de reprodução de vídeo
Mostrar/ocultar nome do arquivo
Reproduzir vídeos em ciclo
- Animação de GIFs nas miniaturas
- Brilho máximo ao visualizar mídia
+ Animar GIFs nas miniaturas
+ Maximizar o brilho ao visualizar mídia em tela cheia
Recortar miniaturas em quadrados
- Exibir durações de vídeo
+ Exibir duração dos vídeos
Critério para rotação de tela
Padrão do sistema
Sensor do aparelho
Proporção da mídia
Fundo de tela e barra de status preta quando em visualização de tela cheia
Rolar miniaturas horizontalmente
- Esconder interface do sistema automaticamente quando em tela cheia
- Apagar pastas vazias após deleter seu conteúdo
+ Esconder interface do sistema quando em tela cheia
+ Apagar pastas vazias após excluir o seu conteúdo
Permitir controle do brilho com gestos na vertical
Permitir controle do volume e brilho com gestos na vertical
- Mostrar quantidade de arquivos das pastas
- Exibir detalhes extendidos quando em tela cheia
- Gerenciar detalhes extendidos
+ Mostrar quantidade de arquivos em cada pasta na tela inicial
+ Exibir detalhes adicionais quando em tela cheia
+ Gerenciar detalhes adicionais
Permitir zoom com um dedo quando em exibição de tela cheia
- Permitir alternância instantânia de mídia clicando nas laterais da tela
- Permitir zoom aprofundado em imagens
- Ocultar detalhes extendidos quando a barra de status estiver oculta
+ Tocar na lateral da tela navega para a próxima imagem ou vídeo
+ Permitir zoom aprofundado para imagens
+ Ocultar detalhes adicionais quando a barra de status estiver oculta
Mostrar alguns botões de ação na parte inferior da tela
- Mostar a Lixeira na tela de pastas
- Imagens com zoom aprofundado
- Mostrar imagens com a maior qualidade possível
- Mostrar a Lixeira como o último item na tela principal
- Permitir fechar a exibição em tela cheia com um gesto para baixo
- Permitir zoom 1:1 com dois toques duplos
+ Mostrar a Lixeira na tela inicial
+ Zoom aprofundado para imagens
+ Mostrar imagens na maior qualidade possível
+ Mostrar a Lixeira como o último item na tela inicial
+ Gesto para baixo sai da exibição em tela cheia
+ Dois toques duplos fazem zoom 1:1
Sempre abrir vídeos em uma tela separada com novos gestos horizontais
- Mostrar um encaixe, se disponível
+ Mostrar o notch, se existente
Permitir rotação de imagens com gestos
Prioridade de carregamento de arquivos
Velocidade
- Compromise
- Evite exibit arquivos inválidos
+ Meio termo
+ Evitar a exibição de arquivos inválidos
Miniaturas
Mídia em tela cheia
- Detalhes extendidos
- Bottom actions
+ Detalhes adicionais
+ Botões de ação
- Manage visible bottom actions
- Toggle favorite
- Toggle file visibilityv
+ Gerenciar botões de ação
+ Favoritar/Desfavoritar
+ Exibir/Ocultar arquivov
- Como eu posso tornar o Simple Gallery como galeria padrão do meu aparelho?
- First you have to find the currently default gallery in the Apps section of your device settings, look for a button that says something like \"Open by default\", click on it, then select \"Clear defaults\".
- The next time you will try opening an image or video you should see an app picker, where you can select Simple Gallery and make it the default app.
- I locked the app with a password, but I forgot it. What can I do?
- You can solve it in 2 ways. You can either reinstall the app, or find the app in your device settings and select \"Clear data\". It will reset all your settings, it will not remove any media files.
- How can I make an album always appear at the top?
- You can long press the desired album and select the Pin icon at the actions menu, that will pin it to the top. You can pin multiple folders too, pinned items will be sorted by the default sorting method.
- How can I fast-forward videos?
- You can either drag your finger horizontally over the video player, or click on the current or max duration texts near the seekbar. That will move the video either backward, or forward.
- What is the difference between hiding and excluding a folder?
- Exclude prevents displaying the folder only in Simple Gallery, while Hide works system-wise and it hides the folder from other galleries too. It works by creating an empty \".nomedia\" file in the given folder, which you can then remove with any file manager too.
- Why do folders with music cover art or stickers show up?
- It can happen that you will see some unusual albums show up. You can easily exclude them by long pressing them and selecting Exclude. In the next dialog you can then select the parent folder, chances are it will prevent the other related albums showing up too.
- A folder with images isn\'t showing up, or it doesn\'t show all items. What can I do?
- That can have multiple reasons, but solving it is easy. Just go in Settings -> Manage Included Folders, select Plus and navigate to the required folder.
- What if I want just a few particular folders visible?
- Adding a folder at the Included Folders doesn\'t automatically exclude anything. What you can do is go in Settings -> Manage Excluded Folders, exclude the root folder \"/\", then add the desired folders at Settings -> Manage Included Folders.
- That will make only the selected folders visible, as both excluding and including are recursive and if a folder is both excluded and included, it will show up.
- Can I crop images with this app?
- Yes, you can crop images in the editor, by dragging the image corners. You can get to the editor either by long pressing an image thumbnail and selecting Edit, or selecting Edit from the fullscreen view.
- Can I somehow group media file thumbnails?
- Sure, just use the \"Group by\" menu item while at the thumbnails view. You can group files by multiple criteria, including Date Taken. If you use the \"Show all folders content\" function you can group them by folders too.
- Sorting by Date Taken doesn\'t seem to work properly, how can I fix it?
- It is most likely caused by the files being copied from somewhere. You can fix it by selecting the file thumbnails and selecting \"Fix Date Taken value\".
- I see some color banding on the images. How can I improve the quality?
- The current solution for displaying images works fine in the vast majority of cases, but if you want even better image quality, you can enable the \"Show images in the highest possible quality\" at the app settings, in the \"Deep zoomable images\" section.
- I have hidden a file/folder. How can I unhide it?
- You can either press the \"Temporarily show hidden items\" menu item at the main screen, or toggle \"Show hidden items\" in the app settings to see the hidden item. If you want to unhide it, just long press it and select \"Unhide\". Folders are hidden by adding a hidden \".nomedia\" file into them, you can delete the file with any file manager too.
- Why does the app take up so much space?
- App cache can take up to 250MB, it ensures quicker image loading. If the app is taking up even more space, it is most likely caused by you having items in the Recycle Bin. Those files count to the app size. You can clear the Recycle bin by opening it and deleting all files, or from the app settings. Every file in the Bin is deleted automatically after 30 days.
+ O que devo fazer para que a Simple Galeria seja o aplicativo de galeria padrão do meu aparelho?
+ Primeiro, você deve encontrar o aplicativo padrão atual nas configurações do seu aparelho, e apertar o botão que diz "Limpar Padrões".
+ Na próxima vez que você abrir uma imagem ou vídeo, você deverá ver um seletor do aplicativo, no qual você terá a oportunidade de selecionar a Simple Galeria como o app padrão.
+ Eu protegi o app com senha, mas me esqueci da senha. O que posso fazer?
+ Você pode resolver isto de duas formas. A primeira é reinstalar o aplicativo. A segunda é ir nas configurações do seu dispositivo e selecionar a opção "Restaurar preferências do app".
+ Como posso fazer para que uma pasta sempre apareça no topo da lista?
+ Faça um toque longo na pasta em questão, e depois toque no ícone de alfinete na parte superior da tela para fixar a pasta ao topo. Se você fixar múltiplas pastas, elas serão ordenadas de acordo como seu critério de ordenação padrão.
+ Como faço para avançar rapidamente um vídeo (fast-forward)?
+ Você pode fazer um gesto horizontal como dedo, ou tocar nos números de tempo atual ou tempo total do vídeo, que se encontram próximos à barra de posicionamento.
+ Qual é a diferença entre ocultar e ignorar uma pasta?
+ O opção de ignorar deixa de exibir a pasta apenas na Simple Galeria, enquanto a opção de ocultar afeta todo o sistema, e também irá deixar de exibir a pasta em outros apps de galeria. A função de ocultar cria um arquivo vazio chamado \".nomedia\" na raiz da pasta em questão. Caso você queira fazer a pasta voltar a ser exibida, você pode excluir o arquivo \".nomedia\" usando o gerenciador de arquivos.
+ Porque pastas com capas de CD de música ou figurinhas aparecem na lista?
+ Você pode pedir para a Simple Galeria ignorar estas pastas, adicionando a pasta raiz onde você guarda as suas músicas à lista de pastas ignoradas. Uma maneira de fazer isso é fazer um toque longo em uma destas pastas, e selecionar a opção Ignorar e, em seguida, seleciona a pasta pai.
+ Uma das minhas pastas não aparece, ou nem todos os seus itens são exibidos. O que posso fazer?
+ Isso pode ocorrer por diversos motivos, mas resolver o problema é fácil. Entre em Configurações --> Gerenciar pastas incluídas, toque no botão \"+\", e selecione a pasta em questão.
+ Como posso fazer para exibir apenas certas pastas?
+ Adicionar uma pasta à lista de Pastas Incluídas não remove outras pastas da exibição. O que você pode fazer é ir em Configurações -> Gerenciar pastas ignoradas, excluir a pasta raiz \"/\", e finalmente incluir somente as pastas desejadas através de Configurações -> Gerenciar pastas incluídas.
+ Posso recortar imagens usando este app?
+ Sim, você pode recortar imagens no editor, arrastando os cantos da imagem. Você pode entrar no editor fazendo um toque longo na imagem e selecionando Editar, ou selecionando Editar a partir da visualização de tela cheia.
+ É possível exibir os meus arquivos de mídia em subgrupos ao invés de em uma única grande lista?
+ Você pode usar a opção \"Agrupar por\" para agrupar os seus arquivos de mídia por data, formato ou outros critérios. Se a opção \"Mostrar conteúdo de todas as pastas\" estiver ativada, você também poderá agrupar por subpasta.
+ A ordenação por Data da Foto não funciona corretamente. O que posso fazer?
+ Isto pode ter ocorrer caso as suas fotos tenham sido copiadas de outro local. Para resolver o problema, você pode selecionar a função \"Corrigir data da foto\" no menu deste aplicativo.
+ Algumas imagens exibem artefatos de exibição, como bandas de cor. Como posso melhorar a qualidade da exibição?
+ O nosso método atual para a exibição de imagens funciona bem na grande maioria dos casos, mas caso você queira uma qualidade ainda melhor, ative a opção \"Mostrar imagens na maior qualidade possível\" na seção \"Zoom aprofundado para imagens\" das configurações deste aplicativo.
+ Eu ocultei um arquivo/pasta. Como posso desfazer isso?
+ Você pode pressionar no item do menu \"Mostrar temporariamente itens ocultos\", localizado na tela principal. Você também pode alterar para \"Mostrar itens ocultos\" nas configurações do aplicativo e ver os itens escondidos. Se você quiser reexibir, basta pressionar e selecionar \"Mostrar\". As pastas estão ocultas, adicionando um arquivo oculto \".nomedia\" dentro delas e você pode excluir o arquivo com qualquer gerenciador de arquivos também.
+ Porque este app gasta tanto espaço?
+ O cache deste app, que garante que as imagens sejam carregadas mais rapidamente, pode gastar até 250 MB. Se o app estiver gastando mais espaço que isso, pode ser por que você tem muitos arquivos na sua Lixeira. Arquivos na Lixeira são removidos permanentemente após 30 dias, mas se sua Lixeira estiver usando muito espaço apesar disso você pode esvaziá-la manualmente. Para fazer isso, você pode abrir a Lixeira e excluir os arquivos dentro dela, ou você pode fazer o mesmo na tela de configurações deste app.
- Simple Gallery Pro: Photo Manager & Editor
+ Simple Galeria Pro: Gerenciador de Imagens
- Offline gallery without ads. Organize, edit, recover and protect photos & videos
+ Galeria offline sem anúncios. Organize, edite, e proteja fotos e vídeos.
- Simple Gallery Pro is a highly customizable offline gallery. Organize & edit your photos, recover deleted files with the recycle bin, protect & hide files and view a huge variety of different photo & video formats including RAW, SVG and much more.
-
- The app contains no ads and unnecessary permissions. As the app doesn’t require internet access either, your privacy is protected.
+ A Simple Galeria Pro é uma galeria de imagens e vídeos altamente customizável. Organize e edite suas fotos e vídeos, recupere arquivos movidos para a lixeira, proteja e oculte seus arquivos, e visualize arquivos em uma grande variedade de formatos, incluindo RAW, SVG, e muito mais.
+ Este app não inclui anúncios ou permissões desnecessárias e também não acessa a internet. Sua privacidade está protegida.
-------------------------------------------------
- SIMPLE GALLERY PRO – FEATURES
+ SIMPLE GALERIA PRO – FUNCIONALIDADES
-------------------------------------------------
- • Offline gallery with no ads or popups
- • Simple gallery photo editor – crop, rotate, resize, draw, filters & more
- • No internet access needed, giving you more privacy and security
- • No unnecessary permissions required
- • Quickly search images, videos & files
- • Open & view many different photo and video types (RAW, SVG, panoramic etc)
- • A variety of intuitive gestures to easily edit & organize files
- • Lots of ways to filter, group & sort files
- • Customize the appearance of Simple Gallery Pro
- • Available in 32 languages
- • Mark files as favorites for quick access
- • Protect your photos & videos with a pattern, pin or fingerprint
- • Use pin, pattern & fingerprint to protect the app launch or specific functions too
- • Recover deleted photos & videos from the recycle bin
- • Toggle visibility of files to hide photos & videos
- • Create a customizable slideshow of your files
- • View detailed information of your files (resolution, EXIF values etc)
- • Simple Gallery Pro is open source
- … and much much more!
+ • Galeria offline sem anúncios ou popups
+ • Editor de imagens – recorte, rotacione, redimensione, desenhe, adicione filtros, e muito mais
+ • Não requer acesso à internet. Mais privacidade e segurança.
+ • Não pede permissões desnecessárias
+ • Pesquise por imagens, vídeos e arquivos rapidamente
+ • Visualize diversos formatos de arquivos de imagem ou vídeo (RAW, SVG, imagens panorâmicas, etc)
+ • Use uma variedade de gestos intuitivos para editar e organizar seus arquivos
+ • Varias maneiras de filtrar, agrupar, e ordenar seus arquivos
+ • Customize a aparência da Simple Galeria Pro
+ • Disponível em 32 idiomas
+ • Marque seus arquivos favoritos para acesso mais rápido
+ • Proteja suas imagens e vídeos com um padrão, PIN, ou impressão digital
+ • Recupere imagens e vídeos que foram excluídos para a lixeira
+ • Oculte arquivos para deixar de exibir certas imagens ou vídeos no app.
+ • Crie um slideshow customizado com os seus arquivos
+ • Exiba informações avançadas sobre seus arquivos (resolução, metadados EXIF, etc)
+ • A Simple Galeria Pro tem código aberto!
+ … e muito mais!
- PHOTO GALLERY EDITOR
- Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If you’re feeling a little more creative you can add filters and draw on your pictures!
+ EDITOR DE IMAGENS
+ Com a Simple Galeria Pro é bem fácil editar suas imagens na hora. Recorte, rotacione, e redimensione suas imagens. Se você estiver se sentindo mais criativo, você também pode desenhar ou adicionar filtros!
- SUPPORT FOR MANY FILE TYPES
- Unlike some other gallery viewers & photo organizers, Simple Gallery Pro supports a huge range of different file types including JPEG, PNG, MP4, MKV, RAW, SVG, Panoramic photos, Panoramic videos and many more.
+ SUPORTE A VÁRIOS FORMATOS DE ARQUIVO
+ Ao contrário de alguns outros aplicativos de organização de imagens, a Simple Galeria Pro é capaz de exibir uma grande variedade de formatos de arquivo, incluindo JPEG, PNG, MP4, MKV, RAW, SVG, fotos panorâmicas, vídeos panorâmicos e muito mais.
- HIGHLY CUSTOMIZABLE GALLERY MANAGER
- From the UI to the function buttons on the bottom toolbar, Simple Gallery Pro is highly customizable and works the way you want it to. No other gallery manager has this kind of flexibility! Thanks to being open source, we’re also available in 32 languages!
+ GERENCIADOR DE IMAGENS ALTAMENTE CUSTOMIZÁVEL
+ Desde a interface de usuário, até os botões da barra de ferramentas, a Simple Galeria Pro é altamente customizável, e você pode fazer com que ela funcione exatamente do seu jeito. Nenhum outro app de galeria de imagens é tão flexível! Além disso, por ter o código aberto, a Simple Galeria está disponível em 32 idiomas!
- RECOVER DELETED PHOTOS & VIDEOS
- Accidentally deleted a precious photo or video? Don’t worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos & videos easily.
+ RECUPERE IMAGENS E VÍDEOS EXCLUÍDOS
+ Acidentalmente excluiu uma preciosa imagem ou vídeo? Não se preocupe! A Simple Galeria Pro vem com uma lixeira que permite facilmente recuperar fotos ou vídeos excluídos nos últimos 30 dias.
+
+ PROTEJA E OCULTE FOTOS, VÍDEOS E ARQUIVOS
+ Usando um PIN, padrão, ou sua impressão digital, você pode proteger ou ocultar imagens, vídeos ou até álbuns inteiros. Você também pode proteger o app como um todo por senha, ou apenas funções específicas. Por exemplo, você pode fazer com que a Simple Galeria verifique a impressão digital antes de excluir arquivos, para ajudar a evitar que arquivos sejam excluídos.
- PROTECT & HIDE PHOTOS, VIDEOS & FILES
- Using pin, pattern or your device’s fingerprint scanner you can protect and hide photos, videos & entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you can’t delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
-
- Check out the full suite of Simple Tools here:
+ Dê uma olhada nos nossos outros aplicativos Simple:
https://www.simplemobiletools.com
Facebook:
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 6a44570d5..dcb39385e 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -33,6 +33,7 @@
Dados corrigidos com sucesso
Partilhar foto redimensionada
Olá,\n\nparece que você utilizou a opção de atualização existente na versão antiga. Agora já pode desinstalar essa versão antiga.\n\nApenas perderá os itens existentes na reciclagem e os favoritos não assinalados mas também terá que repor as predefinições da aplicação.\n\nObrigado!
+ Switch to file search across all visible folders
Filtrar multimédia
@@ -115,10 +116,10 @@
Ordem aleatória
Mover para trás
Apresentação em ciclo
- Animation
- None
- Fade
- Slide
+ Animação
+ Nenhuma
+ Desvanecer
+ Deslizar
Apresentação terminada
Não foram encontrados ficheiros para a apresentação
@@ -133,11 +134,11 @@
Não agrupar ficheiros
Pasta
Última modificação
- Last modified (daily)
- Last modified (monthly)
+ Última modificação (diária)
+ Última modificação (mensal)
Data de obtenção
- Date taken (daily)
- Date taken (monthly)
+ Data de obtenção (diária)
+ Data de obtenção (mensal)
Tipo de ficheiro
Extensão
Tenha em atenção de que agrupamento e ordenação são campos independentes
@@ -238,7 +239,7 @@
Simple Gallery Pro é uma aplicação local para gerir fotos e vídeos. Pode organizar e editar as suas fotos, recuperar ficheiros através da reciclagem, proteger e ocultar ficheiros e ver imagens e vídeos disponíveis em vários formatos tais como RAW, SVG e muito mais.
- A aplicação não tem anúncios nem pede permissões desnecessárias. uma vez que também não precisa de aceder à Internet, os seus ficheiros estão protegidos.
+ A aplicação não tem anúncios nem pede permissões desnecessárias. Uma vez que também não precisa de aceder à Internet, os seus ficheiros estão protegidos.
-------------------------------------------------
SIMPLE GALLERY PRO – FUNCIONALIDADES
@@ -279,7 +280,7 @@
PROTECT & HIDE PHOTOS, VIDEOS & FILES
Using pin, pattern or your device’s fingerprint scanner you can protect and hide photos, videos & entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you can’t delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
- Check out the full suite of Simple Tools here:
+ Consulte todas as aplicações Simple Tools aqui:
https://www.simplemobiletools.com
Facebook:
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 06a4f65e0..5c301337c 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -33,6 +33,7 @@
Даты исправлены
Поделиться изменённой версией
Привет,\n\nпохоже, что вы обновились со старого бесплатного приложения. Теперь вы можете удалить старую версию, которая содержит кнопку \"Обновить до Pro\" в верхней части настроек приложения.\n\nБудет очищена корзина, сняты отметки избранного, а также вам придётся сбросить настройки приложения.\n\nСпасибо!
+ Switch to file search across all visible folders
Фильтр медиа
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f5e7965ad..17975dfe2 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -33,6 +33,7 @@
Dátumy boli úspešne opravené
Zdieľať verziu so zmenenou veľkosťou
Zdravím,\n\nvyzerá to tak, že ste zo starej bezplatnej apky prešlie na novú, platenú. Starú apku, ktorá má na vrchu nastavení tlačidlo \'Stiahnuť Pro verziu\', môžete už odinštalovať.\n\nStratíte tým iba súbory v odpadkovom koši, obľúbené položky budú odznačené a tiež si budete musieť opäť nastaviť položky v nastaveniach aplikácie.\n\nVďaka!
+ Prepnúť na vyhľadávanie súborov vo všetkých viditeľných priečinkoch
Filter médií
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 64d29cfe6..d997791c0 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -33,6 +33,7 @@
Datumi uspešno popravljeni
Deli spremenjeno verzijo
Živjo,\n\nkot kaže, ste nadgradili staro brezplačno aplikacijo. Sedaj lahko odstranite staro verzijo, ki ima gumb \'Nadgradi na Pro verzijo\' na vrhu nastavitev.\n\nIzbrisani bodo le elementi v košu, priljubljeni elementi bodo odznačeni, poleg tega pa bo potrebno še ponastaviti nastavitve aplikacije.\n\nHvala!
+ Switch to file search across all visible folders
Filtriranje datotek
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index deaca7956..15eb6934d 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -33,6 +33,7 @@
Датуми успешно исправљени
Подели верзију са промењеним димензијама
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Филтрирај медију
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 6609790bb..146bcc54d 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -33,6 +33,7 @@
Datumen har korrigerats
Dela en version med ändrad storlek
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filtrera media
@@ -116,9 +117,9 @@
Spela upp i omvänd ordning
Spela upp i en slinga
Animation
- None
- Fade
- Slide
+ Ingen
+ Tona
+ Glid
Bildspelet har avslutats
Ingen media hittades för bildspelet
@@ -133,14 +134,14 @@
Gruppera inte filer
Mapp
Senast ändrad
- Last modified (daily)
- Last modified (monthly)
+ Senast ändrad (dag)
+ Senast ändrad (månad)
Fotodatum
- Date taken (daily)
- Date taken (monthly)
+ Fotodatum (dag)
+ Fotodatum (månad)
Filtyp
Filnamnstillägg
- Please note that grouping and sorting are 2 independent fields
+ Observera att gruppering och sortering är två oberoende funktioner
Mapp som visas i widgeten:
diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml
index 7ef1ff093..1f8450696 100644
--- a/app/src/main/res/values-sw600dp/dimens.xml
+++ b/app/src/main/res/values-sw600dp/dimens.xml
@@ -6,4 +6,5 @@
38dp
70dp
100dp
+ 80dp
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index f86062f48..3a67952c4 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -33,6 +33,7 @@
Tarihler başarıyla düzeltildi
Yeniden boyutlandırılmış sürümü paylaş
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Medyayı filtrele
@@ -227,59 +228,59 @@
Görüntüleri görüntülemek için geçerli çözüm, vakaların büyük çoğunluğunda iyi çalışır, ama daha iyi görüntü kalitesi istiyorsanız, \"Derin yakınlaştırılabilir resimler\" bölümündeki uygulama ayarlarında \"Resimleri mümkün olan en yüksek kalitede göster\" seçeneğini etkinleştirebilirsiniz.
Bir dosya/klasör gizledim. Nasıl gösterebilirim?
Ana ekranda \"Geçici olarak gizli öğeleri göster\" menü öğesine veya gizli öğeyi görmek için uygulama ayarlarında \"Gizli öğeleri göster\" seçeneğine tıklayabilirsiniz. Göstermek isterseniz, sadece uzun basın ve \"Göster\"i seçin. Klasörler gizlenmiş bir \".nomedia\" dosyası ekleyerek gizlenir, dosyayı herhangi bir dosya yöneticisi ile de silebilirsiniz.
- Why does the app take up so much space?
- App cache can take up to 250MB, it ensures quicker image loading. If the app is taking up even more space, it is most likely caused by you having items in the Recycle Bin. Those files count to the app size. You can clear the Recycle bin by opening it and deleting all files, or from the app settings. Every file in the Bin is deleted automatically after 30 days.
+ Uygulama neden bu kadar yer kaplıyor?
+ Uygulama önbelleği 250 MB\'a kadar çıkabilir, daha hızlı resim yüklemesini sağlar. Uygulama daha da fazla yer kaplıyorsa, büyük olasılıkla Geri Dönüşüm Kutusu\'nda öğe bulundurmanızdan kaynaklanmaktadır. Bu dosyalar uygulama boyutuna göre sayılır. Geri Dönüşüm Kutusu\'nu açarak ve tüm dosyaları silerek ya da uygulama ayarlarından temizleyebilirsiniz. Geri dönüşümdeki her dosya 30 gün sonra otomatik olarak silinir.
- Simple Gallery Pro: Photo Manager & Editor
+ Basit Galeri Pro: Fotoğraf Yönetici & Düzenleyici
- Offline gallery without ads. Organize, edit, recover and protect photos & videos
+ Reklamsız çevrimdışı galeri. Fotoğraf & videolarınızı yönetin ve düzenleyin
- Simple Gallery Pro is a highly customizable offline gallery. Organize & edit your photos, recover deleted files with the recycle bin, protect & hide files and view a huge variety of different photo & video formats including RAW, SVG and much more.
+ Basit Galeri Pro, özelleştirilebilir bir çevrimdışı galeridir. Fotoğraflarınızı düzenleyin ve organize edin, geri dönüşüm kutusuyla silinen dosyaları kurtarın, dosyaları koruyun ve gizleyin ve RAW, SVG ve çok daha fazlası dahil olmak üzere çok çeşitli fotoğraf ve video formatlarını görüntüleyin.
- The app contains no ads and unnecessary permissions. As the app doesn’t require internet access either, your privacy is protected.
+ Uygulamaya hiçbir reklam ve gereksiz izinler içermez. Uygulama internet erişimi gerektirmediğinden gizliliğiniz de korunur.
-------------------------------------------------
- SIMPLE GALLERY PRO – FEATURES
+ BASİT GALERİ PRO – ÖZELLİKLER
-------------------------------------------------
- • Offline gallery with no ads or popups
- • Simple gallery photo editor – crop, rotate, resize, draw, filters & more
- • No internet access needed, giving you more privacy and security
- • No unnecessary permissions required
- • Quickly search images, videos & files
- • Open & view many different photo and video types (RAW, SVG, panoramic etc)
- • A variety of intuitive gestures to easily edit & organize files
- • Lots of ways to filter, group & sort files
- • Customize the appearance of Simple Gallery Pro
- • Available in 32 languages
- • Mark files as favorites for quick access
- • Protect your photos & videos with a pattern, pin or fingerprint
- • Use pin, pattern & fingerprint to protect the app launch or specific functions too
- • Recover deleted photos & videos from the recycle bin
- • Toggle visibility of files to hide photos & videos
- • Create a customizable slideshow of your files
- • View detailed information of your files (resolution, EXIF values etc)
- • Simple Gallery Pro is open source
- … and much much more!
+ • Reklamsız veya açılır penceresiz, çevrimdışı galeri
+ • Basit galeri fotoğraf editörü - kırpma, döndürme, yeniden boyutlandırma, çizim, filtreler ve daha fazlası
+ • İnternet erişimi gerekmez, size daha fazla gizlilik ve güvenlik sunar
+ • Gereksiz izinler gerekmez
+ • Resimleri, videoları ve dosyaları hızlıca arama
+ • Birçok farklı fotoğraf ve video türünü (RAW, SVG, panoramik vb.) açma ve görüntüleme
+ • Dosyaları kolayca düzenlemek ve organize etmek için çeşitli sezgisel hareketler
+ • Dosyaları filtrelemenin, gruplandırmanın ve sıralamanın birçok yolu
+ • Basit Galeri Pro\'nun görünümünü özelleştirme
+ • 32 dilde mevcut
+ • Hızlı erişim için dosyaları sık kullanılan olarak işaretleme
+ • Fotoğraflarınızı ve videolarınızı desen, pin veya parmak izi ile koruma
+ • Uygulama başlatılmasını veya belirli işlevleri de korumak için pin, desen ve parmak izi kullanma
+ • Silinen fotoğrafları ve videoları geri dönüşüm kutusundan kurtarma
+ • Fotoğrafları ve videoları gizlemek için dosyaların görünürlüğünü değiştirme
+ • Dosyalarınızın özelleştirilebilir bir slayt gösterisini oluşturma
+ • Dosyalarınızın ayrıntılı bilgilerini (çözünürlük, EXIF değerleri vb.) görüntüleme
+ • Basit Galeri Pro açık kaynak kodludur
+ … ve çok daha fazlası!
- PHOTO GALLERY EDITOR
- Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If you’re feeling a little more creative you can add filters and draw on your pictures!
+ FOTOĞRAF GALERİSİ EDİTÖRÜ
+ Basit Galeri Pro, fotoğraflarınızı anında düzenlemenizi kolaylaştırır. Resimlerinizi kırpın, çevirin, döndürün ve yeniden boyutlandırın. Kendinizi biraz daha yaratıcı hissediyorsanız, filtre ekleyebilir ve resimlerinizi çizebilirsiniz!
- SUPPORT FOR MANY FILE TYPES
- Unlike some other gallery viewers & photo organizers, Simple Gallery Pro supports a huge range of different file types including JPEG, PNG, MP4, MKV, RAW, SVG, Panoramic photos, Panoramic videos and many more.
+ BİRÇOK DOSYA TÜRÜ İÇİN DESTEK
+ Diğer galeri görüntüleyicilerinden ve fotoğraf düzenleyicilerinden farklı olarak, Basit Galeri Pro, JPEG, PNG, MP4, MKV, RAW, SVG, Panoramik fotoğraflar, Panoramik videolar ve daha pek çok farklı dosya türünü destekler.
- HIGHLY CUSTOMIZABLE GALLERY MANAGER
- From the UI to the function buttons on the bottom toolbar, Simple Gallery Pro is highly customizable and works the way you want it to. No other gallery manager has this kind of flexibility! Thanks to being open source, we’re also available in 32 languages!
+ SON DERECE ÖZELLEŞTİRİLEBİLİR GALERİ YÖNETİCİSİ
+ Kullanıcı arayüzünden alt araç çubuğundaki işlev düğmelerine kadar, Basit Galeri Pro oldukça özelleştirilebilirdir ve istediğiniz şekilde çalışır. Başka hiçbir galeri yöneticisi bu tür bir esnekliğe sahip değildir! Açık kaynak olması sayesinde 32 dilde de kullanıma hazırız!
- RECOVER DELETED PHOTOS & VIDEOS
- Accidentally deleted a precious photo or video? Don’t worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos & videos easily.
+ SİLİNEN FOTOĞRAFLARI VE VİDEOLARI KURTARIN
+ Yanlışlıkla önemli bir fotoğrafı veya videoyu mu sildiniz? Endişelenmeyin! Basit Galeri Pro, silinmiş fotoğrafları ve videoları kolayca kurtarabileceğiniz kullanışlı bir geri dönüşüm kutusuna sahiptir.
- PROTECT & HIDE PHOTOS, VIDEOS & FILES
- Using pin, pattern or your device’s fingerprint scanner you can protect and hide photos, videos & entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you can’t delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
+ FOTOĞRAFLARI, VİDEOLARI VE DOSYALARI KORUYUN VE GİZLEYİN
+ Pin, desen veya cihazınızın parmak izi tarayıcısını kullanarak fotoğrafları, videoları ve albümün tamamını koruyabilir ve gizleyebilirsiniz. Uygulamanın kendisini koruyabilir veya uygulamanın belirli işlevlerine kilitler yerleştirebilirsiniz. Örneğin, parmak izi taraması olmadan bir dosyayı silemez ve dosyalarınızı yanlışlıkla silmeye karşı korumaya yardımcı olabilirsiniz.
- Check out the full suite of Simple Tools here:
+ Tüm Basit Araçlar paketini buradan inceleyin:
https://www.simplemobiletools.com
Facebook:
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 45f3bfb7e..83bed8198 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -33,6 +33,7 @@
Дати успішно виправлені
Поділитися зображенням іншого розміру
Агов,\n\nздається, ви оновились зі старого безкоштовного додатка. Тепер ви можете видалити стару версію, у якій є кнопка \"Перейти на Pro\" вгорі налаштувань додатка.\n\nВи втратите лише елементи з Кошика, позначки улюблених елементів, а також потрібно буде скинути ваші налаштування додатка.\n\nДякую!
+ Switch to file search across all visible folders
Фільтр мультимедійних файлів
@@ -115,10 +116,10 @@
Випадковий порядок
Рухатися назад
Зациклити показ слайдів
- Animation
- None
- Fade
- Slide
+ Анімація
+ Немає
+ Згасання
+ Зміщення
Слайдшоу закінчено
Не знайдено медіафайлів для показу у слайдшоу
@@ -133,11 +134,11 @@
Не групувати файли
текою
останньою зміною
- Last modified (daily)
- Last modified (monthly)
+ останньою зміною (по днях)
+ останньою зміною (по місяцях)
датою зйомки
- Date taken (daily)
- Date taken (monthly)
+ датою зйомки (по днях)
+ датою зйомки (по місяцях)
типом файлу
розширенням
Зверніть увагу, що групування і сортування - це два окремих поля
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index bfff3f9f3..5734c6824 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -33,6 +33,7 @@
日期修复成功
调整图像尺寸并分享
嘿,\n\n看起来您是从旧的免费版应用程序升级的。您现在可以卸载旧版本,在该版本应用的设置菜单顶部有一个“升级到专业版”按钮。\n\n此操作将会删除回收站项目,并取消收藏已收藏的项目,你的应用设置也将会重置。\n\n谢谢!
+ Switch to file search across all visible folders
要显示的媒体文件
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 5dd4781fe..b270f8d90 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -33,6 +33,7 @@
日期修復成功
分享調整大小的版本
嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了,在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除,我的最愛項目會被解除標記,以及也會重置你的應用程式設定。\n\n感謝!
+ Switch to file search across all visible folders
篩選媒體檔案
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 6646a770e..ec7809e5e 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -28,11 +28,12 @@
強制直向
強制橫向
使用預設方向
- 修復拍照日期數值
+ 修復拍攝日期數值
修復中…
日期修復成功
分享調整大小的版本
嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了,在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除,我的最愛項目會被解除標記,以及也會重置你的應用程式設定。\n\n感謝!
+ Switch to file search across all visible folders
篩選媒體檔案
@@ -115,10 +116,10 @@
隨機順序
反向播放
投影片循環
- Animation
- None
- Fade
- Slide
+ 動畫
+ 無
+ 漸變
+ 滑動
投影片結束
找不到投影片的媒體檔案
@@ -220,9 +221,9 @@
我可以用這程式裁減圖片嗎?
是的,你能夠在編輯器內拉動圖片角落來裁剪圖片。要進入編輯器,你可以長按圖片縮圖然後選擇[編輯],或是在全螢幕檢視下選擇[編輯]。
我可以歸類媒體檔案的縮圖嗎?
- 當然,只要在縮圖瀏覽中使用[歸類]選單項目就可以了。你能依多種條件歸類檔案,包含拍照日期。如果你使用了[資料夾內容全部顯示]功能,你還能以資料夾來歸類。
- 依拍照日期排序似乎沒正確運作,我該如何修復?
- 那很可能是由於檔案從某處複製過來所造成的。你可以選擇檔案縮圖,然後選擇\"修復拍照日期數值\"來進行修復。
+ 當然,只要在縮圖瀏覽中使用[歸類]選單項目就可以了。你能依多種條件歸類檔案,包含拍攝日期。如果你使用了[資料夾內容全部顯示]功能,你還能以資料夾來歸類。
+ 依拍攝日期排序似乎沒正確運作,我該如何修復?
+ 那很可能是由於檔案從某處複製過來所造成的。你可以選擇檔案縮圖,然後選擇\"修復拍攝日期數值\"來進行修復。
我在圖片上看到一些色彩條紋。我如何提升品質?
目前顯示圖片的處理方法,在大部分情況下都能正常運行。但如果你想要更好的圖片品質,你可以在程式設定中[可深度縮放的圖片]部分,啟用[以最高品質顯示圖片]。
我隱藏了一個檔案/資料夾。我如何取消隱藏?
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 4fb4f60fd..db0229a17 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -22,4 +22,5 @@
86dp
110dp
40dp
+ 40dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6b7b65968..8cc54d748 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,6 +33,7 @@
Dates fixed successfully
Share a resized version
Hey,\n\nseems like you upgraded from the old free app. You can now uninstall the old version, which has an \'Upgrade to Pro\' button at the top of the app settings.\n\nYou will only have the Recycle bin items deleted, favorite items unmarked and you will also have to reset your app settings.\n\nThanks!
+ Switch to file search across all visible folders
Filter media
diff --git a/build.gradle b/build.gradle
index bfe902f73..e69b8b26f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.40'
+ ext.kotlin_version = '1.3.41'
repositories {
google()