Merge pull request #55 from SimpleMobileTools/master

upd
This commit is contained in:
solokot 2019-07-09 22:38:18 +03:00 committed by GitHub
commit 751e80eafe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 1651 additions and 629 deletions

View file

@ -1,6 +1,23 @@
Changelog 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)* Version 6.8.0 *(2019-06-21)*
---------------------------- ----------------------------

View file

@ -15,8 +15,8 @@ android {
applicationId "com.simplemobiletools.gallery.pro" applicationId "com.simplemobiletools.gallery.pro"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 28
versionCode 254 versionCode 256
versionName "6.8.0" versionName "6.8.2"
multiDexEnabled true multiDexEnabled true
setProperty("archivesBaseName", "gallery") setProperty("archivesBaseName", "gallery")
} }
@ -61,7 +61,7 @@ android {
} }
dependencies { 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 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'it.sephiroth.android.exif:library:1.0.1' implementation 'it.sephiroth.android.exif:library:1.0.1'

View file

@ -36,14 +36,6 @@
android:name=".activities.MainActivity" android:name=".activities.MainActivity"
android:resizeableActivity="true"> android:resizeableActivity="true">
<meta-data
android:name="android.app.default_searchable"
android:resource="@xml/searchable"/>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.PICK"/> <action android:name="android.intent.action.PICK"/>
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
@ -81,6 +73,21 @@
</activity> </activity>
<activity
android:name=".activities.SearchActivity"
android:label="@string/search"
android:parentActivityName=".activities.MainActivity"
android:resizeableActivity="true">
<meta-data
android:name="android.app.default_searchable"
android:resource="@xml/searchable"/>
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
</activity>
<activity <activity
android:name=".activities.ViewPagerActivity" android:name=".activities.ViewPagerActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"

View file

@ -26,10 +26,7 @@ import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.simplemobiletools.commons.dialogs.ColorPickerDialog import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.helpers.REAL_FILE_PATH
import com.simplemobiletools.commons.helpers.SIDELOADING_TRUE
import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.gallery.pro.BuildConfig import com.simplemobiletools.gallery.pro.BuildConfig
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
@ -259,9 +256,9 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
if (!wasDrawCanvasPositioned) { if (!wasDrawCanvasPositioned) {
wasDrawCanvasPositioned = true wasDrawCanvasPositioned = true
editor_draw_canvas.onGlobalLayout { editor_draw_canvas.onGlobalLayout {
Thread { ensureBackgroundThread {
fillCanvasBackground() fillCanvasBackground()
}.start() }
} }
} }
} }
@ -336,7 +333,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_actions_filter_list.adapter = null bottom_actions_filter_list.adapter = null
bottom_actions_filter_list.beGone() bottom_actions_filter_list.beGone()
Thread { ensureBackgroundThread {
try { try {
val originalBitmap = Glide.with(applicationContext).asBitmap().load(uri).submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get() val originalBitmap = Glide.with(applicationContext).asBitmap().load(uri).submit(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get()
currentFilter.filter.processFilter(originalBitmap) currentFilter.filter.processFilter(originalBitmap)
@ -344,23 +341,23 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error) toast(R.string.out_of_memory_error)
} }
}.start() }
} }
} }
} }
private fun shareImage() { private fun shareImage() {
Thread { ensureBackgroundThread {
when { when {
default_image_view.isVisible() -> { default_image_view.isVisible() -> {
val currentFilter = getFiltersAdapter()?.getCurrentFilter() val currentFilter = getFiltersAdapter()?.getCurrentFilter()
if (currentFilter == null) { if (currentFilter == null) {
toast(R.string.unknown_error_occurred) 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() 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) shareBitmap(originalBitmap)
} }
crop_image_view.isVisible() -> { crop_image_view.isVisible() -> {
@ -371,12 +368,12 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
} }
editor_draw_canvas.isVisible() -> shareBitmap(editor_draw_canvas.getBitmap()) editor_draw_canvas.isVisible() -> shareBitmap(editor_draw_canvas.getBitmap())
} }
}.start() }
} }
private fun getTempImagePath(bitmap: Bitmap, callback: (path: String?) -> Unit) { private fun getTempImagePath(bitmap: Bitmap, callback: (path: String?) -> Unit) {
val bytes = ByteArrayOutputStream() val bytes = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bytes) bitmap.compress(CompressFormat.PNG, 0, bytes)
val folder = File(cacheDir, TEMP_FOLDER_NAME) val folder = File(cacheDir, TEMP_FOLDER_NAME)
if (!folder.exists()) { if (!folder.exists()) {
@ -581,20 +578,27 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_editor_draw_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_DRAW) bottom_editor_draw_actions.beVisibleIf(currPrimaryAction == PRIMARY_ACTION_DRAW)
if (currPrimaryAction == PRIMARY_ACTION_FILTER && bottom_actions_filter_list.adapter == null) { 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 thumbnailSize = resources.getDimension(R.dimen.bottom_filters_thumbnail_size).toInt()
val bitmap = Glide.with(this)
.asBitmap()
.load(uri).listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
showErrorToast(e.toString())
return false
}
override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean) = false val bitmap = try {
}) Glide.with(this)
.submit(thumbnailSize, thumbnailSize) .asBitmap()
.get() .load(uri).listener(object : RequestListener<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
showErrorToast(e.toString())
return false
}
override fun onResourceReady(resource: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean) = false
})
.submit(thumbnailSize, thumbnailSize)
.get()
} catch (e: GlideException) {
showErrorToast(e)
finish()
return@ensureBackgroundThread
}
runOnUiThread { runOnUiThread {
val filterThumbnailsManager = FilterThumbnailsManager() val filterThumbnailsManager = FilterThumbnailsManager()
@ -623,7 +627,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
bottom_actions_filter_list.adapter = adapter bottom_actions_filter_list.adapter = adapter
adapter.notifyDataSetChanged() adapter.notifyDataSetChanged()
} }
}.start() }
} }
if (currPrimaryAction != PRIMARY_ACTION_CROP_ROTATE) { if (currPrimaryAction != PRIMARY_ACTION_CROP_ROTATE) {
@ -804,7 +808,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
private fun saveBitmapToFile(bitmap: Bitmap, path: String, showSavingToast: Boolean) { private fun saveBitmapToFile(bitmap: Bitmap, path: String, showSavingToast: Boolean) {
try { try {
Thread { ensureBackgroundThread {
val file = File(path) val file = File(path)
val fileDirItem = FileDirItem(path, path.getFilenameFromPath()) val fileDirItem = FileDirItem(path, path.getFilenameFromPath())
getFileOutputStream(fileDirItem, true) { getFileOutputStream(fileDirItem, true) {
@ -814,7 +818,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
toast(R.string.image_editing_failed) toast(R.string.image_editing_failed)
} }
} }
}.start() }
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {

View file

@ -5,6 +5,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.beVisibleIf import com.simplemobiletools.commons.extensions.beVisibleIf
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.ManageHiddenFoldersAdapter import com.simplemobiletools.gallery.pro.adapters.ManageHiddenFoldersAdapter
@ -55,11 +56,11 @@ class HiddenFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
private fun addFolder() { private fun addFolder() {
FilePickerDialog(this, config.lastFilepickerPath, false, config.shouldShowHidden, false, true) { FilePickerDialog(this, config.lastFilepickerPath, false, config.shouldShowHidden, false, true) {
config.lastFilepickerPath = it config.lastFilepickerPath = it
Thread { ensureBackgroundThread {
addNoMedia(it) { addNoMedia(it) {
updateFolders() updateFolders()
} }
}.start() }
} }
} }
} }

View file

@ -1,9 +1,7 @@
package com.simplemobiletools.gallery.pro.activities package com.simplemobiletools.gallery.pro.activities
import android.app.Activity import android.app.Activity
import android.app.SearchManager
import android.content.ClipData import android.content.ClipData
import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -14,8 +12,6 @@ import android.view.MenuItem
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuItemCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.CreateNewFolderDialog import com.simplemobiletools.commons.dialogs.CreateNewFolderDialog
@ -65,7 +61,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mIsPasswordProtectionPending = false private var mIsPasswordProtectionPending = false
private var mWasProtectionHandled = false private var mWasProtectionHandled = false
private var mShouldStopFetching = false private var mShouldStopFetching = false
private var mIsSearchOpen = false
private var mLatestMediaId = 0L private var mLatestMediaId = 0L
private var mLatestMediaDateId = 0L private var mLatestMediaDateId = 0L
private var mCurrentPathPrefix = "" // used at "Group direct subfolders" for navigation private var mCurrentPathPrefix = "" // used at "Group direct subfolders" for navigation
@ -73,7 +68,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mLastMediaHandler = Handler() private var mLastMediaHandler = Handler()
private var mTempShowHiddenHandler = Handler() private var mTempShowHiddenHandler = Handler()
private var mZoomListener: MyRecyclerView.MyZoomListener? = null private var mZoomListener: MyRecyclerView.MyZoomListener? = null
private var mSearchMenuItem: MenuItem? = null
private var mDirs = ArrayList<Directory>() private var mDirs = ArrayList<Directory>()
private var mStoredAnimateGifs = true private var mStoredAnimateGifs = true
@ -224,8 +218,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
override fun onStop() { override fun onStop() {
super.onStop() super.onStop()
mSearchMenuItem?.collapseActionView()
if (config.temporarilyShowHidden || config.tempSkipDeleteConfirmation) { if (config.temporarilyShowHidden || config.tempSkipDeleteConfirmation) {
mTempShowHiddenHandler.postDelayed({ mTempShowHiddenHandler.postDelayed({
config.temporarilyShowHidden = false 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.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.hide_the_recycle_bin).isVisible = useBin && config.showRecycleBinAtFolders
findItem(R.id.show_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 { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.search -> launchSearchActivity()
R.id.sort -> showSortingDialog() R.id.sort -> showSortingDialog()
R.id.filter -> showFilterMediaDialog() R.id.filter -> showFilterMediaDialog()
R.id.open_camera -> launchCamera() 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() { private fun startNewPhotoFetcher() {
if (isNougatPlus()) { if (isNougatPlus()) {
val photoFetcher = NewPhotoFetcher() val photoFetcher = NewPhotoFetcher()
@ -391,7 +346,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
private fun checkOTGPath() { private fun checkOTGPath() {
Thread { ensureBackgroundThread {
if (!config.wasOTGHandled && hasPermission(PERMISSION_WRITE_STORAGE) && hasOTGConnected() && config.OTGPath.isEmpty()) { if (!config.wasOTGHandled && hasPermission(PERMISSION_WRITE_STORAGE) && hasOTGConnected() && config.OTGPath.isEmpty()) {
getStorageDirectories().firstOrNull { it.trimEnd('/') != internalStoragePath && it.trimEnd('/') != sdCardPath }?.apply { getStorageDirectories().firstOrNull { it.trimEnd('/') != internalStoragePath && it.trimEnd('/') != sdCardPath }?.apply {
config.wasOTGHandled = true config.wasOTGHandled = true
@ -409,7 +364,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
} }
} }
}.start() }
} }
private fun checkDefaultSpamFolders() { 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() { private fun showSortingDialog() {
ChangeSortingDialog(this, true, false) { ChangeSortingDialog(this, true, false) {
directories_grid.adapter = null directories_grid.adapter = null
if (config.directorySorting and SORT_BY_DATE_MODIFIED > 0 || config.directorySorting and SORT_BY_DATE_TAKEN > 0) { if (config.directorySorting and SORT_BY_DATE_MODIFIED > 0 || config.directorySorting and SORT_BY_DATE_TAKEN > 0) {
getDirectories() getDirectories()
} else { } else {
Thread { ensureBackgroundThread {
gotDirectories(getCurrentlyDisplayedDirs()) gotDirectories(getCurrentlyDisplayedDirs())
}.start() }
} }
} }
} }
@ -579,11 +540,11 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
refreshItems() refreshItems()
} }
Thread { ensureBackgroundThread {
folders.filter { !it.exists() }.forEach { folders.filter { !it.exists() }.forEach {
mDirectoryDao.deleteDirPath(it.absolutePath) mDirectoryDao.deleteDirPath(it.absolutePath)
} }
}.start() }
} }
} }
@ -668,22 +629,22 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private fun toggleRecycleBin(show: Boolean) { private fun toggleRecycleBin(show: Boolean) {
config.showRecycleBinAtFolders = show config.showRecycleBinAtFolders = show
invalidateOptionsMenu() invalidateOptionsMenu()
Thread { ensureBackgroundThread {
var dirs = getCurrentlyDisplayedDirs() var dirs = getCurrentlyDisplayedDirs()
if (!show) { if (!show) {
dirs = dirs.filter { it.path != RECYCLE_BIN } as ArrayList<Directory> dirs = dirs.filter { it.path != RECYCLE_BIN } as ArrayList<Directory>
} }
gotDirectories(dirs) gotDirectories(dirs)
}.start() }
} }
private fun createNewFolder() { private fun createNewFolder() {
FilePickerDialog(this, internalStoragePath, false, config.shouldShowHidden, false, true) { FilePickerDialog(this, internalStoragePath, false, config.shouldShowHidden, false, true) {
CreateNewFolderDialog(this, it) { CreateNewFolderDialog(this, it) {
config.tempFolderPath = it config.tempFolderPath = it
Thread { ensureBackgroundThread {
gotDirectories(addTempFolderIfNeeded(getCurrentlyDisplayedDirs())) gotDirectories(addTempFolderIfNeeded(getCurrentlyDisplayedDirs()))
}.start() }
} }
} }
} }
@ -808,9 +769,13 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
private fun itemClicked(path: String) { private fun itemClicked(path: String) {
Intent(this, MediaActivity::class.java).apply { handleLockedFolderOpening(path) { success ->
putExtra(DIRECTORY, path) if (success) {
handleMediaIntent(this) 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) { if (dirs.isEmpty() && config.filterMedia == TYPE_DEFAULT_FILTER) {
directories_empty_text_label.text = getString(R.string.no_media_add_included) directories_empty_text_label.text = getString(R.string.no_media_add_included)
directories_empty_text.text = getString(R.string.add_folder) directories_empty_text.text = getString(R.string.add_folder)
directories_empty_text.underlineText()
directories_empty_text.setOnClickListener { directories_empty_text.setOnClickListener {
showAddIncludedFolderDialog { showAddIncludedFolderDialog {
@ -1013,11 +977,13 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} else { } else {
directories_empty_text_label.text = getString(R.string.no_media_with_filters) 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.text = getString(R.string.change_filters_underlined)
directories_empty_text.setOnClickListener { directories_empty_text.setOnClickListener {
showFilterMediaDialog() showFilterMediaDialog()
} }
} }
directories_empty_text.underlineText()
directories_grid.beVisibleIf(directories_empty_text_label.isGone()) directories_grid.beVisibleIf(directories_empty_text_label.isGone())
} }
@ -1136,12 +1102,12 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
?: "" ?: ""
private fun setupLatestMediaId() { private fun setupLatestMediaId() {
Thread { ensureBackgroundThread {
if (hasPermission(PERMISSION_READ_STORAGE)) { if (hasPermission(PERMISSION_READ_STORAGE)) {
mLatestMediaId = getLatestMediaId() mLatestMediaId = getLatestMediaId()
mLatestMediaDateId = getLatestMediaByDateId() mLatestMediaDateId = getLatestMediaByDateId()
} }
}.start() }
} }
private fun checkLastMediaChanged() { private fun checkLastMediaChanged() {
@ -1150,7 +1116,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
mLastMediaHandler.postDelayed({ mLastMediaHandler.postDelayed({
Thread { ensureBackgroundThread {
val mediaId = getLatestMediaId() val mediaId = getLatestMediaId()
val mediaDateId = getLatestMediaByDateId() val mediaDateId = getLatestMediaByDateId()
if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) { if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) {
@ -1163,7 +1129,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
mLastMediaHandler.removeCallbacksAndMessages(null) mLastMediaHandler.removeCallbacksAndMessages(null)
checkLastMediaChanged() checkLastMediaChanged()
} }
}.start() }
}, LAST_MEDIA_CHECK_PERIOD) }, LAST_MEDIA_CHECK_PERIOD)
} }
@ -1171,12 +1137,12 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (config.useRecycleBin && config.lastBinCheck < System.currentTimeMillis() - DAY_SECONDS * 1000) { if (config.useRecycleBin && config.lastBinCheck < System.currentTimeMillis() - DAY_SECONDS * 1000) {
config.lastBinCheck = System.currentTimeMillis() config.lastBinCheck = System.currentTimeMillis()
Handler().postDelayed({ Handler().postDelayed({
Thread { ensureBackgroundThread {
try { try {
mMediumDao.deleteOldRecycleBinItems(System.currentTimeMillis() - MONTH_MILLISECONDS) mMediumDao.deleteOldRecycleBinItems(System.currentTimeMillis() - MONTH_MILLISECONDS)
} catch (e: Exception) { } catch (e: Exception) {
} }
}.start() }
}, 3000L) }, 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/175139712676531/209575122566323
// /storage/emulated/0/Android/data/com.facebook.orca/files/stickers/497837993632037/499671223448714 // /storage/emulated/0/Android/data/com.facebook.orca/files/stickers/497837993632037/499671223448714
private fun excludeSpamFolders() { private fun excludeSpamFolders() {
Thread { ensureBackgroundThread {
try { try {
val internalPath = internalStoragePath val internalPath = internalStoragePath
val checkedPaths = ArrayList<String>() val checkedPaths = ArrayList<String>()
@ -1222,7 +1188,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
} catch (e: Exception) { } catch (e: Exception) {
} }
}.start() }
} }
override fun refreshItems() { override fun refreshItems() {
@ -1230,16 +1196,16 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
override fun recheckPinnedFolders() { override fun recheckPinnedFolders() {
Thread { ensureBackgroundThread {
gotDirectories(movePinnedDirectoriesToFront(getCurrentlyDisplayedDirs())) gotDirectories(movePinnedDirectoriesToFront(getCurrentlyDisplayedDirs()))
}.start() }
} }
override fun updateDirectories(directories: ArrayList<Directory>) { override fun updateDirectories(directories: ArrayList<Directory>) {
Thread { ensureBackgroundThread {
storeDirectoryItems(directories, mDirectoryDao) storeDirectoryItems(directories, mDirectoryDao)
removeInvalidDBDirectories() removeInvalidDBDirectories()
}.start() }
} }
private fun checkWhatsNewDialog() { private fun checkWhatsNewDialog() {

View file

@ -27,6 +27,7 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE import com.simplemobiletools.commons.helpers.REQUEST_EDIT_IMAGE
import com.simplemobiletools.commons.helpers.SORT_BY_RANDOM import com.simplemobiletools.commons.helpers.SORT_BY_RANDOM
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.commons.views.MyRecyclerView
@ -327,18 +328,25 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} }
private fun searchQueryChanged(text: String) { private fun searchQueryChanged(text: String) {
Thread { ensureBackgroundThread {
try { try {
val filtered = mMedia.filter { it is Medium && it.name.contains(text, true) } as ArrayList val filtered = mMedia.filter { it is Medium && it.name.contains(text, true) } as ArrayList
filtered.sortBy { it is Medium && !it.name.startsWith(text, true) } filtered.sortBy { it is Medium && !it.name.startsWith(text, true) }
val grouped = MediaFetcher(applicationContext).groupMedia(filtered as ArrayList<Medium>, mPath) val grouped = MediaFetcher(applicationContext).groupMedia(filtered as ArrayList<Medium>, mPath)
runOnUiThread { 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) getMediaAdapter()?.updateMedia(grouped)
measureRecyclerViewContent(grouped) measureRecyclerViewContent(grouped)
} }
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
}.start() }
} }
private fun tryLoadGallery() { private fun tryLoadGallery() {
@ -428,7 +436,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
mLastMediaHandler.removeCallbacksAndMessages(null) mLastMediaHandler.removeCallbacksAndMessages(null)
mLastMediaHandler.postDelayed({ mLastMediaHandler.postDelayed({
Thread { ensureBackgroundThread {
val mediaId = getLatestMediaId() val mediaId = getLatestMediaId()
val mediaDateId = getLatestMediaByDateId() val mediaDateId = getLatestMediaByDateId()
if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) { if (mLatestMediaId != mediaId || mLatestMediaDateId != mediaDateId) {
@ -440,7 +448,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} else { } else {
checkLastMediaChanged() checkLastMediaChanged()
} }
}.start() }
}, LAST_MEDIA_CHECK_PERIOD) }, LAST_MEDIA_CHECK_PERIOD)
} }
@ -480,9 +488,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
private fun restoreAllFiles() { private fun restoreAllFiles() {
val paths = mMedia.filter { it is Medium }.map { (it as Medium).path } as ArrayList<String> val paths = mMedia.filter { it is Medium }.map { (it as Medium).path } as ArrayList<String>
restoreRecycleBinPaths(paths, mMediumDao) { restoreRecycleBinPaths(paths, mMediumDao) {
Thread { ensureBackgroundThread {
mDirectoryDao.deleteDirPath(RECYCLE_BIN) mDirectoryDao.deleteDirPath(RECYCLE_BIN)
}.start() }
finish() finish()
} }
} }
@ -586,7 +594,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
private fun startAsyncTask() { private fun startAsyncTask() {
mCurrAsyncTask?.stopFetching() mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) { mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
Thread { ensureBackgroundThread {
val oldMedia = mMedia.clone() as ArrayList<ThumbnailItem> val oldMedia = mMedia.clone() as ArrayList<ThumbnailItem>
val newMedia = it val newMedia = it
gotMedia(newMedia, false) gotMedia(newMedia, false)
@ -596,7 +604,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} }
} catch (e: Exception) { } catch (e: Exception) {
} }
}.start() }
} }
mCurrAsyncTask!!.execute() mCurrAsyncTask!!.execute()
@ -610,9 +618,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} }
if (mPath == FAVORITES) { if (mPath == FAVORITES) {
Thread { ensureBackgroundThread {
mDirectoryDao.deleteDirPath(FAVORITES) mDirectoryDao.deleteDirPath(FAVORITES)
}.start() }
} }
finish() finish()
@ -623,9 +631,9 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} }
private fun deleteDBDirectory() { private fun deleteDBDirectory() {
Thread { ensureBackgroundThread {
mDirectoryDao.deleteDirPath(mPath) mDirectoryDao.deleteDirPath(mPath)
}.start() }
} }
private fun createNewFolder() { private fun createNewFolder() {
@ -846,6 +854,10 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
media_refresh_layout.isRefreshing = false media_refresh_layout.isRefreshing = false
media_empty_text_label.beVisibleIf(media.isEmpty() && !isFromCache) media_empty_text_label.beVisibleIf(media.isEmpty() && !isFromCache)
media_empty_text.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()) media_grid.beVisibleIf(media_empty_text_label.isGone())
val viewType = config.getFolderViewType(if (mShowAll) SHOW_ALL else mPath) 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) } mMedia.removeAll { filtered.map { it.path }.contains((it as? Medium)?.path) }
Thread { ensureBackgroundThread {
val useRecycleBin = config.useRecycleBin val useRecycleBin = config.useRecycleBin
filtered.forEach { filtered.forEach {
if (it.path.startsWith(recycleBinPath) || !useRecycleBin) { if (it.path.startsWith(recycleBinPath) || !useRecycleBin) {
deleteDBPath(mMediumDao, it.path) deleteDBPath(mMediumDao, it.path)
} }
} }
}.start() }
if (mMedia.isEmpty()) { if (mMedia.isEmpty()) {
deleteDirectoryIfEmpty() deleteDirectoryIfEmpty()

View file

@ -15,6 +15,7 @@ import com.simplemobiletools.commons.extensions.onGlobalLayout
import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE 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.R
import com.simplemobiletools.gallery.pro.extensions.* import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.PATH import com.simplemobiletools.gallery.pro.helpers.PATH
@ -94,7 +95,7 @@ open class PanoramaPhotoActivity : SimpleActivity() {
try { try {
val options = VrPanoramaView.Options() val options = VrPanoramaView.Options()
options.inputType = VrPanoramaView.Options.TYPE_MONO options.inputType = VrPanoramaView.Options.TYPE_MONO
Thread { ensureBackgroundThread {
val bitmap = getBitmapToLoad(path) val bitmap = getBitmapToLoad(path)
runOnUiThread { runOnUiThread {
panorama_view.apply { panorama_view.apply {
@ -120,7 +121,7 @@ open class PanoramaPhotoActivity : SimpleActivity() {
}) })
} }
} }
}.start() }
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} }

View file

@ -97,9 +97,16 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
val realPath = intent.extras!!.getString(REAL_FILE_PATH) val realPath = intent.extras!!.getString(REAL_FILE_PATH)
if (realPath != null && File(realPath).exists()) { if (realPath != null && File(realPath).exists()) {
if (realPath.getFilenameFromPath().contains('.') || filename.contains('.')) { if (realPath.getFilenameFromPath().contains('.') || filename.contains('.')) {
sendViewPagerIntent(realPath) if (isFileTypeVisible(realPath)) {
finish() bottom_actions.beGone()
return handleLockedFolderOpening(realPath.getParentPath()) { success ->
if (success) {
sendViewPagerIntent(realPath)
}
finish()
}
return
}
} else { } else {
filename = realPath.getFilenameFromPath() filename = realPath.getFilenameFromPath()
} }
@ -108,18 +115,30 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
if (mUri!!.scheme == "file") { if (mUri!!.scheme == "file") {
if (filename.contains('.')) { if (filename.contains('.')) {
rescanPaths(arrayListOf(mUri!!.path)) bottom_actions.beGone()
sendViewPagerIntent(mUri!!.path) handleLockedFolderOpening(mUri!!.path.getParentPath()) { success ->
finish() if (success) {
return rescanPaths(arrayListOf(mUri!!.path))
sendViewPagerIntent(mUri!!.path)
}
finish()
}
} }
return
} else { } else {
val path = applicationContext.getRealPathFromURI(mUri!!) ?: "" val path = applicationContext.getRealPathFromURI(mUri!!) ?: ""
if (path != mUri.toString() && path.isNotEmpty() && mUri!!.authority != "mms" && filename.contains('.') && File(path).exists()) { if (path != mUri.toString() && path.isNotEmpty() && mUri!!.authority != "mms" && filename.contains('.') && File(path).exists()) {
rescanPaths(arrayListOf(mUri!!.path)) if (isFileTypeVisible(path)) {
sendViewPagerIntent(path) bottom_actions.beGone()
finish() handleLockedFolderOpening(path.getParentPath()) { success ->
return 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_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_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_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 return true
@ -244,6 +264,7 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
R.id.menu_share -> sharePath(mUri!!.toString()) R.id.menu_share -> sharePath(mUri!!.toString())
R.id.menu_edit -> openEditor(mUri!!.toString()) R.id.menu_edit -> openEditor(mUri!!.toString())
R.id.menu_properties -> showProperties() R.id.menu_properties -> showProperties()
R.id.menu_show_on_map -> showFileOnMap(mUri!!.toString())
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
return true return true
@ -253,6 +274,15 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
PropertiesDialog(this, mUri!!.path) 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() { private fun initBottomActions() {
initBottomActionsLayout() initBottomActionsLayout()
initBottomActionButtons() initBottomActionButtons()
@ -292,6 +322,11 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
bottom_set_as.setOnClickListener { bottom_set_as.setOnClickListener {
setAs(mUri!!.toString()) 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() { override fun fragmentClicked() {

View file

@ -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<ThumbnailItem>()
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<Medium>, "")
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<ThumbnailItem>) {
media_grid.onGlobalLayout {
if (config.scrollHorizontally) {
calculateContentWidth(media)
} else {
calculateContentHeight(media)
}
}
}
private fun calculateContentWidth(media: ArrayList<ThumbnailItem>) {
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<ThumbnailItem>) {
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<ThumbnailItem>
}
runOnUiThread {
setupAdapter()
}
startAsyncTask(false)
}
}
private fun startAsyncTask(updateItems: Boolean) {
mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetMediaAsynctask(applicationContext, "", showAll = true) {
mAllMedia = it.clone() as ArrayList<ThumbnailItem>
if (updateItems) {
textChanged(mLastSearchedText)
}
}
mCurrAsyncTask!!.execute()
}
override fun refreshItems() {
startAsyncTask(true)
}
override fun tryDeleteFiles(fileDirItems: ArrayList<FileDirItem>) {
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<String>, 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<FileDirItem>) {
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<String>) {
}
}

View file

@ -11,6 +11,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.toast import com.simplemobiletools.commons.extensions.toast
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isNougatPlus import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
@ -117,7 +118,7 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
if (result.error == null) { if (result.error == null) {
toast(R.string.setting_wallpaper) toast(R.string.setting_wallpaper)
Thread { ensureBackgroundThread {
val bitmap = result.bitmap val bitmap = result.bitmap
val wantedHeight = wallpaperManager.desiredMinimumHeight val wantedHeight = wallpaperManager.desiredMinimumHeight
val ratio = wantedHeight / bitmap.height.toFloat() val ratio = wantedHeight / bitmap.height.toFloat()
@ -135,7 +136,7 @@ class SetWallpaperActivity : SimpleActivity(), CropImageView.OnCropImageComplete
setResult(Activity.RESULT_CANCELED) setResult(Activity.RESULT_CANCELED)
} }
finish() finish()
}.start() }
} else { } else {
toast("${getString(R.string.image_editing_failed)}: ${result.error.message}") toast("${getString(R.string.image_editing_failed)}: ${result.error.message}")
} }

View file

@ -572,7 +572,7 @@ class SettingsActivity : SimpleActivity() {
} }
private fun setupEmptyRecycleBin() { private fun setupEmptyRecycleBin() {
Thread { ensureBackgroundThread {
try { try {
mRecycleBinContentSize = galleryDB.MediumDao().getDeletedMedia().sumByLong { it.size } mRecycleBinContentSize = galleryDB.MediumDao().getDeletedMedia().sumByLong { it.size }
} catch (ignored: Exception) { } catch (ignored: Exception) {
@ -580,7 +580,7 @@ class SettingsActivity : SimpleActivity() {
runOnUiThread { runOnUiThread {
settings_empty_recycle_bin_size.text = mRecycleBinContentSize.formatSize() settings_empty_recycle_bin_size.text = mRecycleBinContentSize.formatSize()
} }
}.start() }
settings_empty_recycle_bin_holder.setOnClickListener { settings_empty_recycle_bin_holder.setOnClickListener {
if (mRecycleBinContentSize == 0L) { if (mRecycleBinContentSize == 0L) {
@ -686,13 +686,13 @@ class SettingsActivity : SimpleActivity() {
private fun setupImportSettings() { private fun setupImportSettings() {
settings_import_holder.setOnClickListener { settings_import_holder.setOnClickListener {
FilePickerDialog(this) { FilePickerDialog(this) {
Thread { ensureBackgroundThread {
try { try {
parseFile(it) parseFile(it)
} catch (e: Exception) { } catch (e: Exception) {
showErrorToast(e) showErrorToast(e)
} }
}.start() }
} }
} }
} }

View file

@ -10,6 +10,7 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.extensions.getParentPath import com.simplemobiletools.commons.extensions.getParentPath
import com.simplemobiletools.commons.extensions.getRealPathFromURI import com.simplemobiletools.commons.extensions.getRealPathFromURI
import com.simplemobiletools.commons.extensions.scanPathRecursively import com.simplemobiletools.commons.extensions.scanPathRecursively
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isPiePlus import com.simplemobiletools.commons.helpers.isPiePlus
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.addPathToDB import com.simplemobiletools.gallery.pro.extensions.addPathToDB
@ -87,9 +88,9 @@ open class SimpleActivity : BaseSimpleActivity() {
config.lastFilepickerPath = it config.lastFilepickerPath = it
config.addIncludedFolder(it) config.addIncludedFolder(it)
callback() callback()
Thread { ensureBackgroundThread {
scanPathRecursively(it) scanPathRecursively(it)
}.start() }
} }
} }
} }

View file

@ -25,6 +25,7 @@ import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.video.VideoListener import com.google.android.exoplayer2.video.VideoListener
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE 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.R
import com.simplemobiletools.gallery.pro.extensions.* import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.* import com.simplemobiletools.gallery.pro.helpers.*
@ -566,10 +567,10 @@ open class VideoPlayerActivity : SimpleActivity(), SeekBar.OnSeekBarChangeListen
private fun releaseExoPlayer() { private fun releaseExoPlayer() {
mExoPlayer?.stop() mExoPlayer?.stop()
Thread { ensureBackgroundThread {
mExoPlayer?.release() mExoPlayer?.release()
mExoPlayer = null mExoPlayer = null
}.start() }
} }
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 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 onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) { override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
Thread { ensureBackgroundThread {
mExoPlayer?.setVideoSurface(Surface(video_surface!!.surfaceTexture)) mExoPlayer?.setVideoSurface(Surface(video_surface!!.surfaceTexture))
}.start() }
} }
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {} override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {}

View file

@ -10,6 +10,7 @@ import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.content.res.Configuration import android.content.res.Configuration
import android.database.Cursor import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
@ -24,7 +25,15 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.widget.Toast import android.widget.Toast
import androidx.print.PrintHelper
import androidx.viewpager.widget.ViewPager 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.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.* 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_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_move_to).isVisible = visibleBottomActions and BOTTOM_ACTION_MOVE == 0
findItem(R.id.menu_save_as).isVisible = rotationDegrees != 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_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_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() 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_share -> shareMediumPath(getCurrentPath())
R.id.menu_delete -> checkDeleteConfirmation() R.id.menu_delete -> checkDeleteConfirmation()
R.id.menu_rename -> renameFile() R.id.menu_rename -> renameFile()
R.id.menu_print -> printFile()
R.id.menu_edit -> openEditor(getCurrentPath()) R.id.menu_edit -> openEditor(getCurrentPath())
R.id.menu_properties -> showProperties() 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_right -> rotateImage(90)
R.id.menu_rotate_left -> rotateImage(-90) R.id.menu_rotate_left -> rotateImage(-90)
R.id.menu_rotate_one_eighty -> rotateImage(180) 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") { if (intent.action == "com.android.camera.action.REVIEW") {
Thread { ensureBackgroundThread {
val mediumDao = galleryDB.MediumDao() val mediumDao = galleryDB.MediumDao()
if (mediumDao.getMediaFromPath(mPath).isEmpty()) { if (mediumDao.getMediaFromPath(mPath).isEmpty()) {
val type = when { 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) val medium = Medium(null, mPath.getFilenameFromPath(), mPath, mPath.getParentPath(), ts, ts, File(mPath).length(), type, duration, isFavorite, 0)
mediumDao.insert(medium) mediumDao.insert(medium)
} }
}.start() }
} }
} }
@ -351,9 +362,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
private fun initFavorites() { private fun initFavorites() {
Thread { ensureBackgroundThread {
mFavoritePaths = getFavoritePaths() mFavoritePaths = getFavoritePaths()
}.start() }
} }
private fun setupOrientation() { private fun setupOrientation() {
@ -624,14 +635,14 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
val newPath = it val newPath = it
handleSAFDialog(it) { handleSAFDialog(it) {
toast(R.string.saving) toast(R.string.saving)
Thread { ensureBackgroundThread {
val photoFragment = getCurrentPhotoFragment() ?: return@Thread val photoFragment = getCurrentPhotoFragment() ?: return@ensureBackgroundThread
saveRotatedImageToFile(currPath, newPath, photoFragment.mCurrentRotationDegrees, true) { saveRotatedImageToFile(currPath, newPath, photoFragment.mCurrentRotationDegrees, true) {
toast(R.string.file_saved) toast(R.string.file_saved)
getCurrentPhotoFragment()?.mCurrentRotationDegrees = 0 getCurrentPhotoFragment()?.mCurrentRotationDegrees = 0
invalidateOptionsMenu() 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() { private fun initBottomActionsLayout() {
bottom_actions.layoutParams.height = resources.getDimension(R.dimen.bottom_actions_height).toInt() + navigationBarHeight bottom_actions.layoutParams.height = resources.getDimension(R.dimen.bottom_actions_height).toInt() + navigationBarHeight
if (config.bottomActions) { 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.beVisibleIf(visibleBottomActions and BOTTOM_ACTION_SHOW_ON_MAP != 0)
bottom_show_on_map.setOnClickListener { bottom_show_on_map.setOnClickListener {
showOnMap() showFileOnMap(getCurrentPath())
} }
bottom_toggle_file_visibility.beVisibleIf(visibleBottomActions and BOTTOM_ACTION_TOGGLE_VISIBILITY != 0) 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() { private fun toggleFavorite() {
val medium = getCurrentMedium() ?: return val medium = getCurrentMedium() ?: return
medium.isFavorite = !medium.isFavorite medium.isFavorite = !medium.isFavorite
Thread { ensureBackgroundThread {
galleryDB.MediumDao().updateFavorite(medium.path, medium.isFavorite) galleryDB.MediumDao().updateFavorite(medium.path, medium.isFavorite)
if (medium.isFavorite) { if (medium.isFavorite) {
mFavoritePaths.add(medium.path) mFavoritePaths.add(medium.path)
@ -871,7 +819,60 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
mFavoritePaths.remove(medium.path) mFavoritePaths.remove(medium.path)
} }
invalidateOptionsMenu() 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<Bitmap> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
showErrorToast(e?.localizedMessage ?: "")
return false
}
override fun onResourceReady(bitmap: Bitmap?, model: Any?, target: Target<Bitmap>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
if (bitmap != null) {
printHelper.printBitmap(path.getFilenameFromPath(), bitmap)
}
return false
}
}).submit(requestedWidth, requestedHeight)
} catch (e: Exception) {
}
} }
private fun restoreFile() { private fun restoreFile() {
@ -989,9 +990,9 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
name = it.getFilenameFromPath() name = it.getFilenameFromPath()
} }
Thread { ensureBackgroundThread {
updateDBMediaPath(oldPath, it) updateDBMediaPath(oldPath, it)
}.start() }
updateActionbarTitle() updateActionbarTitle()
} }
} }
@ -1092,8 +1093,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
override fun launchViewVideoIntent(path: String) { override fun launchViewVideoIntent(path: String) {
Thread { ensureBackgroundThread {
val newUri = getFinalUriFromPath(path, BuildConfig.APPLICATION_ID) ?: return@Thread val newUri = getFinalUriFromPath(path, BuildConfig.APPLICATION_ID) ?: return@ensureBackgroundThread
val mimeType = getUriMimeType(path, newUri) val mimeType = getUriMimeType(path, newUri)
Intent().apply { Intent().apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -1116,7 +1117,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
} }
} }
}.start() }
} }
private fun checkSystemUI() { private fun checkSystemUI() {

View file

@ -10,6 +10,7 @@ import android.widget.RelativeLayout
import android.widget.RemoteViews import android.widget.RemoteViews
import com.simplemobiletools.commons.dialogs.ColorPickerDialog import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.dialogs.PickDirectoryDialog import com.simplemobiletools.gallery.pro.dialogs.PickDirectoryDialog
import com.simplemobiletools.gallery.pro.extensions.* import com.simplemobiletools.gallery.pro.extensions.*
@ -89,9 +90,9 @@ class WidgetConfigureActivity : SimpleActivity() {
AppWidgetManager.getInstance(this).updateAppWidget(mWidgetId, views) AppWidgetManager.getInstance(this).updateAppWidget(mWidgetId, views)
config.showWidgetFolderName = folder_picker_show_folder_name.isChecked config.showWidgetFolderName = folder_picker_show_folder_name.isChecked
val widget = Widget(null, mWidgetId, mFolderPath) val widget = Widget(null, mWidgetId, mFolderPath)
Thread { ensureBackgroundThread {
widgetsDB.insertOrUpdate(widget) widgetsDB.insertOrUpdate(widget)
}.start() }
storeWidgetColors() storeWidgetColors()
requestWidgetUpdate() requestWidgetUpdate()
@ -161,14 +162,14 @@ class WidgetConfigureActivity : SimpleActivity() {
config_folder_name.text = getFolderNameFromPath(folderPath) config_folder_name.text = getFolderNameFromPath(folderPath)
} }
Thread { ensureBackgroundThread {
val path = directoryDB.getDirectoryThumbnail(folderPath) val path = directoryDB.getDirectoryThumbnail(folderPath)
if (path != null) { if (path != null) {
runOnUiThread { runOnUiThread {
loadJpg(path, config_image, config.cropThumbnails) loadJpg(path, config_image, config.cropThumbnails)
} }
} }
}.start() }
} }
private fun handleFolderNameDisplay() { private fun handleFolderNameDisplay() {

View file

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.view.Menu import android.view.Menu
import android.view.View import android.view.View
@ -12,11 +13,10 @@ import com.bumptech.glide.Glide
import com.google.gson.Gson import com.google.gson.Gson
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.*
import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.dialogs.RenameItemsDialog
import com.simplemobiletools.commons.extensions.* 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.helpers.isOreoPlus
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.views.FastScroller 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.interfaces.DirectoryOperationsListener
import com.simplemobiletools.gallery.pro.models.AlbumCover import com.simplemobiletools.gallery.pro.models.AlbumCover
import com.simplemobiletools.gallery.pro.models.Directory 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 kotlinx.android.synthetic.main.directory_item_list.view.*
import java.io.File import java.io.File
@ -47,9 +54,11 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
private var cropThumbnails = config.cropThumbnails private var cropThumbnails = config.cropThumbnails
private var groupDirectSubfolders = config.groupDirectSubfolders private var groupDirectSubfolders = config.groupDirectSubfolders
private var currentDirectoriesHash = dirs.hashCode() private var currentDirectoriesHash = dirs.hashCode()
private var lockedFolderPaths = ArrayList<String>()
init { init {
setupDragListener(true) setupDragListener(true)
fillLockedFolders()
} }
override fun getActionMenuId() = R.menu.cab_directories override fun getActionMenuId() = R.menu.cab_directories
@ -80,6 +89,9 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
findItem(R.id.cab_rename).isVisible = !selectedPaths.contains(FAVORITES) && !selectedPaths.contains(RECYCLE_BIN) findItem(R.id.cab_rename).isVisible = !selectedPaths.contains(FAVORITES) && !selectedPaths.contains(RECYCLE_BIN)
findItem(R.id.cab_change_cover_image).isVisible = isOneItemSelected findItem(R.id.cab_change_cover_image).isVisible = isOneItemSelected
findItem(R.id.cab_lock).isVisible = selectedPaths.any { !config.isFolderProtected(it) }
findItem(R.id.cab_unlock).isVisible = selectedPaths.any { config.isFolderProtected(it) }
findItem(R.id.cab_empty_recycle_bin).isVisible = isOneItemSelected && selectedPaths.first() == RECYCLE_BIN findItem(R.id.cab_empty_recycle_bin).isVisible = isOneItemSelected && selectedPaths.first() == RECYCLE_BIN
findItem(R.id.cab_empty_disable_recycle_bin).isVisible = isOneItemSelected && selectedPaths.first() == RECYCLE_BIN findItem(R.id.cab_empty_disable_recycle_bin).isVisible = isOneItemSelected && selectedPaths.first() == RECYCLE_BIN
@ -105,13 +117,15 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
R.id.cab_hide -> toggleFoldersVisibility(true) R.id.cab_hide -> toggleFoldersVisibility(true)
R.id.cab_unhide -> toggleFoldersVisibility(false) R.id.cab_unhide -> toggleFoldersVisibility(false)
R.id.cab_exclude -> tryExcludeFolder() 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_copy_to -> copyMoveTo(true)
R.id.cab_move_to -> moveFilesTo() R.id.cab_move_to -> moveFilesTo()
R.id.cab_select_all -> selectAll() 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_delete -> askConfirmDelete()
R.id.cab_select_photo -> changeAlbumCover(false) R.id.cab_select_photo -> tryChangeAlbumCover(false)
R.id.cab_use_default -> changeAlbumCover(true) R.id.cab_use_default -> tryChangeAlbumCover(true)
} }
} }
@ -145,10 +159,16 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
if (selectedKeys.size <= 1) { if (selectedKeys.size <= 1) {
val path = getFirstSelectedItemPath() ?: return val path = getFirstSelectedItemPath() ?: return
if (path != FAVORITES && path != RECYCLE_BIN) { if (path != FAVORITES && path != RECYCLE_BIN) {
PropertiesDialog(activity, path, config.shouldShowHidden) activity.handleLockedFolderOpening(path) { success ->
if (success) {
PropertiesDialog(activity, path, config.shouldShowHidden)
}
}
} }
} else { } 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<Directo
return return
} }
RenameItemDialog(activity, dir.absolutePath) { activity.handleLockedFolderOpening(sourcePath) { success ->
activity.runOnUiThread { if (success) {
firstDir.apply { RenameItemDialog(activity, dir.absolutePath) {
path = it activity.runOnUiThread {
name = it.getFilenameFromPath() firstDir.apply {
tmb = File(it, tmb.getFilenameFromPath()).absolutePath 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 { } else {
val paths = getSelectedPaths().filter { !activity.isAStorageRootFolder(it) } as ArrayList<String> val paths = getSelectedPaths().filter { !activity.isAStorageRootFolder(it) && !activity.config.isFolderProtected(it) } as ArrayList<String>
RenameItemsDialog(activity, paths) { RenameItemsDialog(activity, paths) {
listener?.refreshItems() listener?.refreshItems()
} }
@ -194,25 +218,37 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
} }
selectedPaths.filter { it != FAVORITES && it != RECYCLE_BIN }.forEach { selectedPaths.filter { it != FAVORITES && it != RECYCLE_BIN && (selectedPaths.size == 1 || !activity.config.isFolderProtected(it)) }.forEach {
val path = it val path = it
if (hide) { if (hide) {
if (config.wasHideFolderTooltipShown) { if (config.wasHideFolderTooltipShown) {
hideFolder(path) activity.handleLockedFolderOpening(path) { success ->
if (success) {
hideFolder(path)
}
}
} else { } else {
config.wasHideFolderTooltipShown = true config.wasHideFolderTooltipShown = true
ConfirmationDialog(activity, activity.getString(R.string.hide_folder_description)) { ConfirmationDialog(activity, activity.getString(R.string.hide_folder_description)) {
hideFolder(path) activity.handleLockedFolderOpening(path) { success ->
if (success) {
hideFolder(path)
}
}
} }
} }
} else { } else {
activity.removeNoMedia(path) { activity.handleLockedFolderOpening(path) { success ->
if (activity.config.shouldShowHidden) { if (success) {
updateFolderNames() activity.removeNoMedia(path) {
} else { if (activity.config.shouldShowHidden) {
activity.runOnUiThread { updateFolderNames()
listener?.refreshItems() } else {
finishActMode() activity.runOnUiThread {
listener?.refreshItems()
finishActMode()
}
}
} }
} }
} }
@ -231,15 +267,23 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
private fun emptyRecycleBin() { private fun emptyRecycleBin() {
activity.emptyTheRecycleBin { activity.handleLockedFolderOpening(RECYCLE_BIN) { success ->
listener?.refreshItems() if (success) {
activity.emptyTheRecycleBin {
listener?.refreshItems()
}
}
} }
} }
private fun emptyAndDisableRecycleBin() { private fun emptyAndDisableRecycleBin() {
activity.showRecycleBinEmptyingDialog { activity.handleLockedFolderOpening(RECYCLE_BIN) { success ->
activity.emptyAndDisableTheRecycleBin { if (success) {
listener?.refreshItems() activity.showRecycleBinEmptyingDialog {
activity.emptyAndDisableTheRecycleBin {
listener?.refreshItems()
}
}
} }
} }
} }
@ -309,6 +353,48 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
} }
private fun tryLockFolder() {
if (config.wasFolderLockingNoticeShown) {
lockFolder()
} else {
FolderLockingNoticeDialog(activity) {
lockFolder()
}
}
}
private fun lockFolder() {
SecurityDialog(activity, "", SHOW_ALL_TABS) { hash, type, success ->
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) { private fun pinFolders(pin: Boolean) {
if (pin) { if (pin) {
config.addPinnedFolders(getSelectedPaths().toHashSet()) config.addPinnedFolders(getSelectedPaths().toHashSet())
@ -351,6 +437,14 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
} }
private fun tryCreateShortcut() {
activity.handleLockedFolderOpening(getFirstSelectedItemPath() ?: "") { success ->
if (success) {
createShortcut()
}
}
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
private fun createShortcut() { private fun createShortcut() {
val manager = activity.getSystemService(ShortcutManager::class.java) val manager = activity.getSystemService(ShortcutManager::class.java)
@ -425,16 +519,16 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
activity.handleSAFDialog(SAFPath) { activity.handleSAFDialog(SAFPath) {
val foldersToDelete = ArrayList<File>(selectedKeys.size) var foldersToDelete = ArrayList<File>(selectedKeys.size)
selectedDirs.forEach { selectedDirs.forEach {
if (it.areFavorites() || it.isRecycleBin()) { if (it.areFavorites() || it.isRecycleBin()) {
if (it.isRecycleBin()) { if (it.isRecycleBin()) {
tryEmptyRecycleBin(false) tryEmptyRecycleBin(false)
} else { } else {
Thread { ensureBackgroundThread {
activity.galleryDB.MediumDao().clearFavorites() activity.galleryDB.MediumDao().clearFavorites()
listener?.refreshItems() listener?.refreshItems()
}.start() }
} }
if (selectedKeys.size == 1) { if (selectedKeys.size == 1) {
@ -445,7 +539,24 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
} }
} }
listener?.deleteFolders(foldersToDelete) if (foldersToDelete.size == 1) {
activity.handleLockedFolderOpening(foldersToDelete.first().absolutePath) { success ->
if (success) {
listener?.deleteFolders(foldersToDelete)
}
}
} else {
foldersToDelete = foldersToDelete.filter { !activity.config.isFolderProtected(it.absolutePath) }.toMutableList() as ArrayList<File>
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<Directo
private fun getItemWithKey(key: Int): Directory? = dirs.firstOrNull { it.path.hashCode() == key } private fun getItemWithKey(key: Int): Directory? = dirs.firstOrNull { it.path.hashCode() == key }
private fun fillLockedFolders() {
lockedFolderPaths.clear()
dirs.map { it.path }.filter { config.isFolderProtected(it) }.forEach {
lockedFolderPaths.add(it)
}
}
fun updateDirs(newDirs: ArrayList<Directory>) { fun updateDirs(newDirs: ArrayList<Directory>) {
val directories = newDirs.clone() as ArrayList<Directory> val directories = newDirs.clone() as ArrayList<Directory>
if (directories.hashCode() != currentDirectoriesHash) { if (directories.hashCode() != currentDirectoriesHash) {
currentDirectoriesHash = directories.hashCode() currentDirectoriesHash = directories.hashCode()
dirs = directories dirs = directories
fillLockedFolders()
notifyDataSetChanged() notifyDataSetChanged()
finishActMode() finishActMode()
} }
@ -538,7 +657,15 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
dir_check.background?.applyColorFilter(primaryColor) dir_check.background?.applyColorFilter(primaryColor)
} }
activity.loadImage(thumbnailType, directory.tmb, dir_thumbnail, scrollHorizontally, animateGifs, cropThumbnails) if (lockedFolderPaths.contains(directory.path)) {
dir_lock.beVisible()
dir_lock.background = ColorDrawable(config.backgroundColor)
dir_lock.applyColorFilter(config.backgroundColor.getContrastColor())
} else {
dir_lock.beGone()
activity.loadImage(thumbnailType, directory.tmb, dir_thumbnail, scrollHorizontally, animateGifs, cropThumbnails)
}
dir_pin.beVisibleIf(pinnedFolders.contains(directory.path)) dir_pin.beVisibleIf(pinnedFolders.contains(directory.path))
dir_location.beVisibleIf(directory.location != LOCATION_INTERNAL) dir_location.beVisibleIf(directory.location != LOCATION_INTERNAL)
if (dir_location.isVisible()) { if (dir_location.isVisible()) {

View file

@ -13,6 +13,7 @@ import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.dialogs.RenameItemsPatternDialog import com.simplemobiletools.commons.dialogs.RenameItemsPatternDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.views.FastScroller import com.simplemobiletools.commons.views.FastScroller
import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.commons.views.MyRecyclerView
@ -46,7 +47,6 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
private var loadImageInstantly = false private var loadImageInstantly = false
private var delayHandler = Handler(Looper.getMainLooper()) private var delayHandler = Handler(Looper.getMainLooper())
private var currentMediaHash = media.hashCode() private var currentMediaHash = media.hashCode()
private val hasOTGConnected = activity.hasOTGConnected()
private var scrollHorizontally = config.scrollHorizontally private var scrollHorizontally = config.scrollHorizontally
private var animateGifs = config.animateGifs private var animateGifs = config.animateGifs
@ -204,7 +204,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
if (selectedKeys.size == 1) { if (selectedKeys.size == 1) {
val oldPath = getFirstSelectedItemPath() ?: return val oldPath = getFirstSelectedItemPath() ?: return
RenameItemDialog(activity, oldPath) { RenameItemDialog(activity, oldPath) {
Thread { ensureBackgroundThread {
activity.updateDBMediaPath(oldPath, it) activity.updateDBMediaPath(oldPath, it)
activity.runOnUiThread { activity.runOnUiThread {
@ -212,7 +212,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
listener?.refreshItems() listener?.refreshItems()
finishActMode() finishActMode()
} }
}.start() }
} }
} else { } else {
RenameItemsPatternDialog(activity, getSelectedPaths()) { RenameItemsPatternDialog(activity, getSelectedPaths()) {
@ -239,7 +239,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
} }
private fun toggleFileVisibility(hide: Boolean) { private fun toggleFileVisibility(hide: Boolean) {
Thread { ensureBackgroundThread {
getSelectedItems().forEach { getSelectedItems().forEach {
activity.toggleFileVisibility(it.path, hide) activity.toggleFileVisibility(it.path, hide)
} }
@ -247,11 +247,11 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
listener?.refreshItems() listener?.refreshItems()
finishActMode() finishActMode()
} }
}.start() }
} }
private fun toggleFavorites(add: Boolean) { private fun toggleFavorites(add: Boolean) {
Thread { ensureBackgroundThread {
val mediumDao = activity.galleryDB.MediumDao() val mediumDao = activity.galleryDB.MediumDao()
getSelectedItems().forEach { getSelectedItems().forEach {
it.isFavorite = add it.isFavorite = add
@ -261,7 +261,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
listener?.refreshItems() listener?.refreshItems()
finishActMode() finishActMode()
} }
}.start() }
} }
private fun restoreFiles() { private fun restoreFiles() {
@ -281,7 +281,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
private fun rotateSelection(degrees: Int) { private fun rotateSelection(degrees: Int) {
activity.toast(R.string.saving) activity.toast(R.string.saving)
Thread { ensureBackgroundThread {
val paths = getSelectedPaths().filter { it.isImageFast() } val paths = getSelectedPaths().filter { it.isImageFast() }
var fileCnt = paths.size var fileCnt = paths.size
rotatedImagePaths.clear() rotatedImagePaths.clear()
@ -297,7 +297,7 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
} }
} }
} }
}.start() }
} }
private fun moveFilesTo() { private fun moveFilesTo() {
@ -334,12 +334,12 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
} }
private fun fixDateTaken() { private fun fixDateTaken() {
Thread { ensureBackgroundThread {
activity.fixDateTaken(getSelectedPaths(), true) { activity.fixDateTaken(getSelectedPaths(), true) {
listener?.refreshItems() listener?.refreshItems()
finishActMode() finishActMode()
} }
}.start() }
} }
private fun checkDeleteConfirmation() { private fun checkDeleteConfirmation() {

View file

@ -23,7 +23,7 @@ class GetMediaAsynctask(val context: Context, val mPath: String, val isPickImage
val favoritePaths = context.getFavoritePaths() val favoritePaths = context.getFavoritePaths()
val getVideoDurations = context.config.showThumbnailVideoDuration val getVideoDurations = context.config.showThumbnailVideoDuration
val media = if (showAll) { val media = if (showAll) {
val foldersToScan = mediaFetcher.getFoldersToScan().filter { it != RECYCLE_BIN && it != FAVORITES } val foldersToScan = mediaFetcher.getFoldersToScan().filter { it != RECYCLE_BIN && it != FAVORITES && !context.config.isFolderProtected(it) }
val media = ArrayList<Medium>() val media = ArrayList<Medium>()
foldersToScan.forEach { foldersToScan.forEach {
val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, getProperFileSize, favoritePaths, getVideoDurations, false) val newMedia = mediaFetcher.getFilesFrom(it, isPickImage, isPickVideo, getProperDateTaken, getProperFileSize, favoritePaths, getVideoDurations, false)

View file

@ -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_date_taken.isChecked = details and EXT_DATE_TAKEN != 0
manage_extended_details_camera.isChecked = details and EXT_CAMERA_MODEL != 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_exif.isChecked = details and EXT_EXIF_PROPERTIES != 0
manage_extended_details_duration.isChecked = details and EXT_DURATION != 0 manage_extended_details_gps_coordinates.isChecked = details and EXT_GPS != 0
manage_extended_details_artist.isChecked = details and EXT_ARTIST != 0
manage_extended_details_album.isChecked = details and EXT_ALBUM != 0
} }
AlertDialog.Builder(activity) AlertDialog.Builder(activity)
@ -54,12 +52,8 @@ class ManageExtendedDetailsDialog(val activity: BaseSimpleActivity, val callback
result += EXT_CAMERA_MODEL result += EXT_CAMERA_MODEL
if (manage_extended_details_exif.isChecked) if (manage_extended_details_exif.isChecked)
result += EXT_EXIF_PROPERTIES result += EXT_EXIF_PROPERTIES
if (manage_extended_details_duration.isChecked) if (manage_extended_details_gps_coordinates.isChecked)
result += EXT_DURATION result += EXT_GPS
if (manage_extended_details_artist.isChecked)
result += EXT_ARTIST
if (manage_extended_details_album.isChecked)
result += EXT_ALBUM
} }
activity.config.extendedDetails = result activity.config.extendedDetails = result

View file

@ -76,7 +76,11 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
private fun showOtherFolder() { private fun showOtherFolder() {
FilePickerDialog(activity, sourcePath, false, showHidden, true, true) { 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) activity.toast(R.string.source_and_destination_same)
return@DirectoryAdapter return@DirectoryAdapter
} else { } else {
callback(path) activity.handleLockedFolderOpening(path) { success ->
if (success) {
callback(path)
}
}
dialog.dismiss() dialog.dismiss()
} }
} else { } else {

View file

@ -10,6 +10,7 @@ import android.graphics.Matrix
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.media.ExifInterface import android.media.ExifInterface
import android.net.Uri
import android.os.Build import android.os.Build
import android.provider.MediaStore import android.provider.MediaStore
import android.util.DisplayMetrics import android.util.DisplayMetrics
@ -190,9 +191,9 @@ fun BaseSimpleActivity.toggleFileVisibility(oldPath: String, hide: Boolean, call
val newPath = "$path/$filename" val newPath = "$path/$filename"
renameFile(oldPath, newPath) { renameFile(oldPath, newPath) {
callback?.invoke(newPath) callback?.invoke(newPath)
Thread { ensureBackgroundThread {
updateDBMediaPath(oldPath, newPath) updateDBMediaPath(oldPath, newPath)
}.start() }
} }
} }
@ -212,12 +213,12 @@ fun BaseSimpleActivity.tryDeleteFileDirItem(fileDirItem: FileDirItem, allowDelet
callback: ((wasSuccess: Boolean) -> Unit)? = null) { callback: ((wasSuccess: Boolean) -> Unit)? = null) {
deleteFile(fileDirItem, allowDeleteFolder) { deleteFile(fileDirItem, allowDeleteFolder) {
if (deleteFromDatabase) { if (deleteFromDatabase) {
Thread { ensureBackgroundThread {
deleteDBPath(galleryDB.MediumDao(), fileDirItem.path) deleteDBPath(galleryDB.MediumDao(), fileDirItem.path)
runOnUiThread { runOnUiThread {
callback?.invoke(it) callback?.invoke(it)
} }
}.start() }
} else { } else {
callback?.invoke(it) callback?.invoke(it)
} }
@ -225,7 +226,7 @@ fun BaseSimpleActivity.tryDeleteFileDirItem(fileDirItem: FileDirItem, allowDelet
} }
fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, mediumDao: MediumDao = galleryDB.MediumDao(), callback: ((wasSuccess: Boolean) -> Unit)?) { fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, mediumDao: MediumDao = galleryDB.MediumDao(), callback: ((wasSuccess: Boolean) -> Unit)?) {
Thread { ensureBackgroundThread {
var pathsCnt = paths.size var pathsCnt = paths.size
paths.forEach { paths.forEach {
val file = File(it) val file = File(it)
@ -246,7 +247,7 @@ fun BaseSimpleActivity.movePathsInRecycleBin(paths: ArrayList<String>, mediumDao
} }
} }
callback?.invoke(pathsCnt == 0) callback?.invoke(pathsCnt == 0)
}.start() }
} }
fun BaseSimpleActivity.restoreRecycleBinPath(path: String, callback: () -> Unit) { fun BaseSimpleActivity.restoreRecycleBinPath(path: String, callback: () -> Unit) {
@ -254,7 +255,7 @@ fun BaseSimpleActivity.restoreRecycleBinPath(path: String, callback: () -> Unit)
} }
fun BaseSimpleActivity.restoreRecycleBinPaths(paths: ArrayList<String>, mediumDao: MediumDao = galleryDB.MediumDao(), callback: () -> Unit) { fun BaseSimpleActivity.restoreRecycleBinPaths(paths: ArrayList<String>, mediumDao: MediumDao = galleryDB.MediumDao(), callback: () -> Unit) {
Thread { ensureBackgroundThread {
val newPaths = ArrayList<String>() val newPaths = ArrayList<String>()
paths.forEach { paths.forEach {
val source = it val source = it
@ -288,26 +289,30 @@ fun BaseSimpleActivity.restoreRecycleBinPaths(paths: ArrayList<String>, mediumDa
} }
fixDateTaken(newPaths, false) fixDateTaken(newPaths, false)
}.start() }
} }
fun BaseSimpleActivity.emptyTheRecycleBin(callback: (() -> Unit)? = null) { fun BaseSimpleActivity.emptyTheRecycleBin(callback: (() -> Unit)? = null) {
Thread { ensureBackgroundThread {
recycleBin.deleteRecursively() try {
galleryDB.MediumDao().clearRecycleBin() recycleBin.deleteRecursively()
galleryDB.DirectoryDao().deleteRecycleBin() galleryDB.MediumDao().clearRecycleBin()
toast(R.string.recycle_bin_emptied) galleryDB.DirectoryDao().deleteRecycleBin()
callback?.invoke() toast(R.string.recycle_bin_emptied)
}.start() callback?.invoke()
} catch (e: Exception) {
toast(R.string.unknown_error_occurred)
}
}
} }
fun BaseSimpleActivity.emptyAndDisableTheRecycleBin(callback: () -> Unit) { fun BaseSimpleActivity.emptyAndDisableTheRecycleBin(callback: () -> Unit) {
Thread { ensureBackgroundThread {
emptyTheRecycleBin { emptyTheRecycleBin {
config.useRecycleBin = false config.useRecycleBin = false
callback() callback()
} }
}.start() }
} }
fun BaseSimpleActivity.showRecycleBinEmptyingDialog(callback: () -> Unit) { fun BaseSimpleActivity.showRecycleBinEmptyingDialog(callback: () -> Unit) {
@ -317,12 +322,12 @@ fun BaseSimpleActivity.showRecycleBinEmptyingDialog(callback: () -> Unit) {
} }
fun BaseSimpleActivity.updateFavoritePaths(fileDirItems: ArrayList<FileDirItem>, destination: String) { fun BaseSimpleActivity.updateFavoritePaths(fileDirItems: ArrayList<FileDirItem>, destination: String) {
Thread { ensureBackgroundThread {
fileDirItems.forEach { fileDirItems.forEach {
val newPath = "$destination/${it.name}" val newPath = "$destination/${it.name}"
updateDBMediaPath(it.path, newPath) updateDBMediaPath(it.path, newPath)
} }
}.start() }
} }
fun Activity.hasNavBar(): Boolean { fun Activity.hasNavBar(): Boolean {
@ -431,10 +436,6 @@ fun BaseSimpleActivity.saveRotatedImageToFile(oldPath: String, newPath: String,
saveFile(tmpPath, bitmap, it as FileOutputStream, newDegrees) saveFile(tmpPath, bitmap, it as FileOutputStream, newDegrees)
} }
if (File(newPath).exists()) {
tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
}
copyFile(tmpPath, newPath) copyFile(tmpPath, newPath)
rescanPaths(arrayListOf(newPath)) rescanPaths(arrayListOf(newPath))
fileRotatedSuccessfully(newPath, oldLastModified) 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) { fun Activity.getShortcutImage(tmb: String, drawable: Drawable, callback: () -> Unit) {
Thread { ensureBackgroundThread {
val options = RequestOptions() val options = RequestOptions()
.format(DecodeFormat.PREFER_ARGB_8888) .format(DecodeFormat.PREFER_ARGB_8888)
.skipMemoryCache(true) .skipMemoryCache(true)
@ -538,5 +539,36 @@ fun Activity.getShortcutImage(tmb: String, drawable: Drawable, callback: () -> U
runOnUiThread { runOnUiThread {
callback() 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)
}
} }

View file

@ -358,7 +358,7 @@ fun Context.updateSubfolderCounts(children: ArrayList<Directory>, parentDirs: Ar
} }
fun Context.getNoMediaFolders(callback: (folders: ArrayList<String>) -> Unit) { fun Context.getNoMediaFolders(callback: (folders: ArrayList<String>) -> Unit) {
Thread { ensureBackgroundThread {
val folders = ArrayList<String>() val folders = ArrayList<String>()
val uri = MediaStore.Files.getContentUri("external") val uri = MediaStore.Files.getContentUri("external")
@ -384,20 +384,20 @@ fun Context.getNoMediaFolders(callback: (folders: ArrayList<String>) -> Unit) {
} }
callback(folders) callback(folders)
}.start() }
} }
fun Context.rescanFolderMedia(path: String) { fun Context.rescanFolderMedia(path: String) {
Thread { ensureBackgroundThread {
rescanFolderMediaSync(path) rescanFolderMediaSync(path)
}.start() }
} }
fun Context.rescanFolderMediaSync(path: String) { fun Context.rescanFolderMediaSync(path: String) {
getCachedMedia(path) { getCachedMedia(path) {
val cached = it val cached = it
GetMediaAsynctask(applicationContext, path, false, false, false) { GetMediaAsynctask(applicationContext, path, false, false, false) {
Thread { ensureBackgroundThread {
val newMedia = it val newMedia = it
val mediumDao = galleryDB.MediumDao() val mediumDao = galleryDB.MediumDao()
val media = newMedia.filter { it is Medium } as ArrayList<Medium> val media = newMedia.filter { it is Medium } as ArrayList<Medium>
@ -411,15 +411,15 @@ fun Context.rescanFolderMediaSync(path: String) {
} }
} }
} }
}.start() }
}.execute() }.execute()
} }
} }
fun Context.storeDirectoryItems(items: ArrayList<Directory>, directoryDao: DirectoryDao) { fun Context.storeDirectoryItems(items: ArrayList<Directory>, directoryDao: DirectoryDao) {
Thread { ensureBackgroundThread {
directoryDao.insertAll(items) directoryDao.insertAll(items)
}.start() }
} }
fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet<String>): String { fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet<String>): String {
@ -452,20 +452,21 @@ fun Context.loadImage(type: Int, path: String, target: MySquareImageView, horizo
loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths) loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths)
} }
} else if (type == TYPE_GIFS) { } else if (type == TYPE_GIFS) {
if (!animateGifs) {
loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
return
}
try { try {
val gifDrawable = GifDrawable(path) val gifDrawable = GifDrawable(path)
target.setImageDrawable(gifDrawable) target.setImageDrawable(gifDrawable)
if (animateGifs) { gifDrawable.start()
gifDrawable.start()
} else {
gifDrawable.stop()
}
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER
} catch (e: Exception) { } catch (e: Exception) {
loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths) loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
} catch (e: OutOfMemoryError) { } catch (e: OutOfMemoryError) {
loadJpg(path, target, cropThumbnails, skipMemoryCacheAtPaths) loadStaticGIF(path, target, cropThumbnails, skipMemoryCacheAtPaths)
} }
} else if (type == TYPE_SVGS) { } else if (type == TYPE_SVGS) {
loadSVG(path, target, cropThumbnails) loadSVG(path, target, cropThumbnails)
@ -525,6 +526,22 @@ fun Context.loadJpg(path: String, target: MySquareImageView, cropThumbnails: Boo
.into(target) .into(target)
} }
fun Context.loadStaticGIF(path: String, target: MySquareImageView, cropThumbnails: Boolean, skipMemoryCacheAtPaths: ArrayList<String>? = 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) { fun Context.loadSVG(path: String, target: MySquareImageView, cropThumbnails: Boolean) {
target.scaleType = if (cropThumbnails) ImageView.ScaleType.CENTER_CROP else ImageView.ScaleType.FIT_CENTER 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<Directory>) -> Unit) { fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, directoryDao: DirectoryDao = galleryDB.DirectoryDao(), forceShowHidden: Boolean = false, callback: (ArrayList<Directory>) -> Unit) {
Thread { ensureBackgroundThread {
val directories = try { val directories = try {
directoryDao.getAll() as ArrayList<Directory> directoryDao.getAll() as ArrayList<Directory>
} catch (e: Exception) { } catch (e: Exception) {
@ -581,12 +598,12 @@ fun Context.getCachedDirectories(getVideosOnly: Boolean = false, getImagesOnly:
callback(clone.distinctBy { it.path.getDistinctPath() } as ArrayList<Directory>) callback(clone.distinctBy { it.path.getDistinctPath() } as ArrayList<Directory>)
removeInvalidDBDirectories(filteredDirectories, directoryDao) removeInvalidDBDirectories(filteredDirectories, directoryDao)
}.start() }
} }
fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, mediumDao: MediumDao = galleryDB.MediumDao(), fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImagesOnly: Boolean = false, mediumDao: MediumDao = galleryDB.MediumDao(),
callback: (ArrayList<ThumbnailItem>) -> Unit) { callback: (ArrayList<ThumbnailItem>) -> Unit) {
Thread { ensureBackgroundThread {
val mediaFetcher = MediaFetcher(this) val mediaFetcher = MediaFetcher(this)
val foldersToScan = if (path.isEmpty()) mediaFetcher.getFoldersToScan() else arrayListOf(path) val foldersToScan = if (path.isEmpty()) mediaFetcher.getFoldersToScan() else arrayListOf(path)
var media = ArrayList<Medium>() var media = ArrayList<Medium>()
@ -599,7 +616,7 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag
} }
val shouldShowHidden = config.shouldShowHidden val shouldShowHidden = config.shouldShowHidden
foldersToScan.forEach { foldersToScan.filter { path.isNotEmpty() || !config.isFolderProtected(it) }.forEach {
try { try {
val currMedia = mediumDao.getMediaFromPath(it) val currMedia = mediumDao.getMediaFromPath(it)
media.addAll(currMedia) media.addAll(currMedia)
@ -644,13 +661,16 @@ fun Context.getCachedMedia(path: String, getVideosOnly: Boolean = false, getImag
} }
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
}.start() }
} }
fun Context.removeInvalidDBDirectories(dirs: ArrayList<Directory>? = null, directoryDao: DirectoryDao = galleryDB.DirectoryDao()) { fun Context.removeInvalidDBDirectories(dirs: ArrayList<Directory>? = null, directoryDao: DirectoryDao = galleryDB.DirectoryDao()) {
val dirsToCheck = dirs ?: directoryDao.getAll() val dirsToCheck = dirs ?: directoryDao.getAll()
dirsToCheck.filter { !it.areFavorites() && !it.isRecycleBin() && !File(it.path).exists() && it.path != config.tempFolderPath }.forEach { 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) { fun Context.addPathToDB(path: String) {
Thread { ensureBackgroundThread {
if (!File(path).exists()) { if (!File(path).exists()) {
return@Thread return@ensureBackgroundThread
} }
val type = when { val type = when {
@ -791,7 +811,7 @@ fun Context.addPathToDB(path: String) {
mediumDao.insert(medium) mediumDao.insert(medium)
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
}.start() }
} }
fun Context.createDirectoryFromMedia(path: String, curMedia: ArrayList<Medium>, albumCovers: ArrayList<AlbumCover>, hiddenString: String, fun Context.createDirectoryFromMedia(path: String, curMedia: ArrayList<Medium>, albumCovers: ArrayList<AlbumCover>, hiddenString: String,

View file

@ -36,6 +36,7 @@ import com.davemorrissey.labs.subscaleview.ImageRegionDecoder
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaPhotoActivity import com.simplemobiletools.gallery.pro.activities.PanoramaPhotoActivity
import com.simplemobiletools.gallery.pro.activities.PhotoActivity import com.simplemobiletools.gallery.pro.activities.PhotoActivity
@ -241,10 +242,10 @@ class PhotoFragment : ViewPagerFragment() {
mLoadZoomableViewHandler.removeCallbacksAndMessages(null) mLoadZoomableViewHandler.removeCallbacksAndMessages(null)
if (mCurrentRotationDegrees != 0) { if (mCurrentRotationDegrees != 0) {
Thread { ensureBackgroundThread {
val path = mMedium.path val path = mMedium.path
(activity as? BaseSimpleActivity)?.saveRotatedImageToFile(path, path, mCurrentRotationDegrees, false) {} (activity as? BaseSimpleActivity)?.saveRotatedImageToFile(path, path, mCurrentRotationDegrees, false) {}
}.start() }
} }
} }

View file

@ -24,6 +24,7 @@ import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DataSpec import com.google.android.exoplayer2.upstream.DataSpec
import com.google.android.exoplayer2.upstream.FileDataSource import com.google.android.exoplayer2.upstream.FileDataSource
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity import com.simplemobiletools.gallery.pro.activities.PanoramaVideoActivity
import com.simplemobiletools.gallery.pro.activities.VideoActivity import com.simplemobiletools.gallery.pro.activities.VideoActivity
@ -139,12 +140,12 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
initTimeHolder() initTimeHolder()
checkIfPanorama() checkIfPanorama()
Thread { ensureBackgroundThread {
activity?.getVideoResolution(mMedium.path)?.apply { activity?.getVideoResolution(mMedium.path)?.apply {
mVideoSize.x = x mVideoSize.x = x
mVideoSize.y = y mVideoSize.y = y
} }
}.start() }
if (mIsPanorama) { if (mIsPanorama) {
mView.apply { mView.apply {
@ -657,10 +658,10 @@ class VideoFragment : ViewPagerFragment(), TextureView.SurfaceTextureListener, S
private fun releaseExoPlayer() { private fun releaseExoPlayer() {
mExoPlayer?.stop() mExoPlayer?.stop()
Thread { ensureBackgroundThread {
mExoPlayer?.release() mExoPlayer?.release()
mExoPlayer = null mExoPlayer = null
}.start() }
} }
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int) {} 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 onSurfaceTextureDestroyed(surface: SurfaceTexture?) = false
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) { override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) {
Thread { ensureBackgroundThread {
mExoPlayer?.setVideoSurface(Surface(mTextureView.surfaceTexture)) mExoPlayer?.setVideoSurface(Surface(mTextureView.surfaceTexture))
}.start() }
} }
private fun setVideoSize() { private fun setVideoSize() {

View file

@ -1,5 +1,6 @@
package com.simplemobiletools.gallery.pro.fragments package com.simplemobiletools.gallery.pro.fragments
import android.media.ExifInterface
import android.provider.MediaStore import android.provider.MediaStore
import android.view.MotionEvent import android.view.MotionEvent
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
@ -39,7 +40,7 @@ abstract class ViewPagerFragment : Fragment() {
} }
val path = "${file.parent.trimEnd('/')}/" val path = "${file.parent.trimEnd('/')}/"
val exif = android.media.ExifInterface(medium.path) val exif = ExifInterface(medium.path)
val details = StringBuilder() val details = StringBuilder()
val detailsFlag = context!!.config.extendedDetails val detailsFlag = context!!.config.extendedDetails
if (detailsFlag and EXT_NAME != 0) { if (detailsFlag and EXT_NAME != 0) {
@ -63,15 +64,19 @@ abstract class ViewPagerFragment : Fragment() {
} }
if (detailsFlag and EXT_DATE_TAKEN != 0) { 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) { 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) { 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() return details.toString().trim()
} }
@ -93,6 +98,23 @@ abstract class ViewPagerFragment : Fragment() {
return "" 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) { protected fun handleEvent(event: MotionEvent) {
when (event.actionMasked) { when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {

View file

@ -380,7 +380,7 @@ class Config(context: Context) : BaseConfig(context) {
} }
fun saveLastVideoPosition(path: String, value: Int) { fun saveLastVideoPosition(path: String, value: Int) {
if (!path.isEmpty()) { if (path.isNotEmpty()) {
prefs.edit().putInt("$LAST_VIDEO_POSITION_PREFIX${path.toLowerCase()}", value).apply() prefs.edit().putInt("$LAST_VIDEO_POSITION_PREFIX${path.toLowerCase()}", value).apply()
} }
} }

View file

@ -115,6 +115,7 @@ const val DRAG_THRESHOLD = 8
const val MONTH_MILLISECONDS = MONTH_SECONDS * 1000L const val MONTH_MILLISECONDS = MONTH_SECONDS * 1000L
const val MIN_SKIP_LENGTH = 2000 const val MIN_SKIP_LENGTH = 2000
const val HIDE_SYSTEM_UI_DELAY = 500L const val HIDE_SYSTEM_UI_DELAY = 500L
const val MAX_PRINT_SIDE_SIZE = 4096
const val DIRECTORY = "directory" const val DIRECTORY = "directory"
const val MEDIUM = "medium" const val MEDIUM = "medium"
@ -153,6 +154,7 @@ const val EXT_EXIF_PROPERTIES = 128
const val EXT_DURATION = 256 const val EXT_DURATION = 256
const val EXT_ARTIST = 512 const val EXT_ARTIST = 512
const val EXT_ALBUM = 1024 const val EXT_ALBUM = 1024
const val EXT_GPS = 2048
// media types // media types
const val TYPE_IMAGES = 1 const val TYPE_IMAGES = 1

View file

@ -2,6 +2,7 @@ package com.simplemobiletools.gallery.pro.helpers
import android.content.Context import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.os.Environment
import android.provider.MediaStore import android.provider.MediaStore
import android.text.format.DateFormat import android.text.format.DateFormat
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
@ -45,7 +46,20 @@ class MediaFetcher(val context: Context) {
return try { return try {
val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) 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) { } catch (e: Exception) {
ArrayList() ArrayList()
} }

View file

@ -14,6 +14,7 @@ import com.simplemobiletools.commons.extensions.getFileSignature
import com.simplemobiletools.commons.extensions.setBackgroundColor import com.simplemobiletools.commons.extensions.setBackgroundColor
import com.simplemobiletools.commons.extensions.setText import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setVisibleIf import com.simplemobiletools.commons.extensions.setVisibleIf
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.MediaActivity import com.simplemobiletools.gallery.pro.activities.MediaActivity
import com.simplemobiletools.gallery.pro.extensions.config import com.simplemobiletools.gallery.pro.extensions.config
@ -34,7 +35,7 @@ class MyWidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
super.onUpdate(context, appWidgetManager, appWidgetIds) super.onUpdate(context, appWidgetManager, appWidgetIds)
Thread { ensureBackgroundThread {
val config = context.config val config = context.config
context.widgetsDB.getWidgets().filter { appWidgetIds.contains(it.widgetId) }.forEach { context.widgetsDB.getWidgets().filter { appWidgetIds.contains(it.widgetId) }.forEach {
val views = RemoteViews(context.packageName, R.layout.widget).apply { val views = RemoteViews(context.packageName, R.layout.widget).apply {
@ -75,7 +76,7 @@ class MyWidgetProvider : AppWidgetProvider() {
setupAppOpenIntent(context, views, R.id.widget_holder, it) setupAppOpenIntent(context, views, R.id.widget_holder, it)
appWidgetManager.updateAppWidget(it.widgetId, views) appWidgetManager.updateAppWidget(it.widgetId, views)
} }
}.start() }
} }
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) { 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) { override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds) super.onDeleted(context, appWidgetIds)
Thread { ensureBackgroundThread {
appWidgetIds.forEach { appWidgetIds.forEach {
context.widgetsDB.deleteWidgetId(it) context.widgetsDB.deleteWidgetId(it)
} }
}.start() }
} }
} }

View file

@ -14,6 +14,7 @@ import android.os.Handler
import android.provider.MediaStore import android.provider.MediaStore
import com.simplemobiletools.commons.extensions.getParentPath import com.simplemobiletools.commons.extensions.getParentPath
import com.simplemobiletools.commons.extensions.getStringValue 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.addPathToDB
import com.simplemobiletools.gallery.pro.extensions.updateDirectoryPath import com.simplemobiletools.gallery.pro.extensions.updateDirectoryPath
@ -94,11 +95,11 @@ class NewPhotoFetcher : JobService() {
} }
} }
Thread { ensureBackgroundThread {
affectedFolderPaths.forEach { affectedFolderPaths.forEach {
updateDirectoryPath(it) updateDirectoryPath(it)
} }
}.start() }
mHandler.post(mWorker) mHandler.post(mWorker)
return true return true

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/media_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/media_empty_text_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingLeft="@dimen/big_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/big_margin"
android:text="@string/no_media_with_filters"
android:textSize="@dimen/bigger_text_size"
android:visibility="gone"/>
<com.simplemobiletools.commons.views.MyRecyclerView
android:id="@+id/media_grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:layoutManager="com.simplemobiletools.commons.views.MyGridLayoutManager"
app:spanCount="@integer/media_columns_vertical_scroll"/>
<com.simplemobiletools.commons.views.FastScroller
android:id="@+id/media_vertical_fastscroller"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:paddingStart="@dimen/normal_margin"
android:visibility="gone">
<include layout="@layout/fastscroller_handle_vertical"/>
</com.simplemobiletools.commons.views.FastScroller>
<com.simplemobiletools.commons.views.FastScroller
android:id="@+id/media_horizontal_fastscroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:paddingTop="@dimen/normal_margin"
android:visibility="gone">
<include layout="@layout/fastscroller_handle_horizontal"/>
</com.simplemobiletools.commons.views.FastScroller>
</RelativeLayout>

View file

@ -78,36 +78,13 @@
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:text="@string/exif"/> android:text="@string/exif"/>
<ImageView
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/divider_grey"
android:importantForAccessibility="no"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox <com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/manage_extended_details_duration" android:id="@+id/manage_extended_details_gps_coordinates"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin" android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin" android:paddingBottom="@dimen/activity_margin"
android:text="@string/duration"/> android:text="@string/gps_coordinates"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/manage_extended_details_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/artist"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/manage_extended_details_album"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/album"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -13,6 +13,20 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>
<ImageView
android:id="@+id/dir_lock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignStart="@+id/dir_thumbnail"
android:layout_alignTop="@+id/dir_thumbnail"
android:layout_alignEnd="@+id/dir_thumbnail"
android:layout_alignBottom="@+id/dir_thumbnail"
android:layout_centerInParent="true"
android:background="@color/default_background_color"
android:padding="@dimen/lock_padding"
android:src="@drawable/ic_lock_huge"
android:visibility="gone"/>
<ImageView <ImageView
android:id="@+id/dir_check" android:id="@+id/dir_check"
android:layout_width="@dimen/selection_check_size" android:layout_width="@dimen/selection_check_size"

View file

@ -14,6 +14,20 @@
android:layout_width="@dimen/list_view_folder_thumbnail_size" android:layout_width="@dimen/list_view_folder_thumbnail_size"
android:layout_height="@dimen/list_view_folder_thumbnail_size"/> android:layout_height="@dimen/list_view_folder_thumbnail_size"/>
<ImageView
android:id="@+id/dir_lock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignStart="@+id/dir_thumbnail"
android:layout_alignTop="@+id/dir_thumbnail"
android:layout_alignEnd="@+id/dir_thumbnail"
android:layout_alignBottom="@+id/dir_thumbnail"
android:layout_centerInParent="true"
android:background="@color/default_background_color"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_lock_huge"
android:visibility="gone"/>
<ImageView <ImageView
android:id="@+id/dir_check" android:id="@+id/dir_check"
android:layout_width="@dimen/selection_check_size" android:layout_width="@dimen/selection_check_size"

View file

@ -48,6 +48,14 @@
android:id="@+id/cab_exclude" android:id="@+id/cab_exclude"
android:title="@string/exclude" android:title="@string/exclude"
app:showAsAction="never"/> app:showAsAction="never"/>
<item
android:id="@+id/cab_lock"
android:title="@string/lock_folder"
app:showAsAction="never"/>
<item
android:id="@+id/cab_unlock"
android:title="@string/unlock_folder"
app:showAsAction="never"/>
<item <item
android:id="@+id/cab_select_all" android:id="@+id/cab_select_all"
android:icon="@drawable/ic_select_all" android:icon="@drawable/ic_select_all"

View file

@ -5,8 +5,7 @@
android:id="@+id/search" android:id="@+id/search"
android:icon="@drawable/ic_search" android:icon="@drawable/ic_search"
android:title="@string/search" android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView" app:showAsAction="always"/>
app:showAsAction="collapseActionView|ifRoom"/>
<item <item
android:id="@+id/open_camera" android:id="@+id/open_camera"
android:icon="@drawable/ic_camera" android:icon="@drawable/ic_camera"

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search"
android:title="@string/search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="collapseActionView|always"/>
</menu>

View file

@ -110,6 +110,10 @@
android:icon="@drawable/ic_rename_new" android:icon="@drawable/ic_rename_new"
android:title="@string/rename" android:title="@string/rename"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_print"
android:title="@string/print"
app:showAsAction="never"/>
<item <item
android:id="@+id/menu_create_shortcut" android:id="@+id/menu_create_shortcut"
android:title="@string/create_shortcut" android:title="@string/create_shortcut"

View file

@ -25,4 +25,8 @@
android:id="@+id/menu_open_with" android:id="@+id/menu_open_with"
android:title="@string/open_with" android:title="@string/open_with"
app:showAsAction="never"/> app:showAsAction="never"/>
<item
android:id="@+id/menu_show_on_map"
android:title="@string/show_on_map"
app:showAsAction="never"/>
</menu> </menu>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">فلتر الميديا</string> <string name="filter_media">فلتر الميديا</string>
@ -64,10 +65,8 @@
<string name="include_folders">المجلدات المضمنة</string> <string name="include_folders">المجلدات المضمنة</string>
<string name="manage_included_folders">إدارة المجلدات المضمنة</string> <string name="manage_included_folders">إدارة المجلدات المضمنة</string>
<string name="add_folder">اضافة مجلد</string> <string name="add_folder">اضافة مجلد</string>
<string name="included_activity_placeholder">إذا كان لديك بعض المجلدات التي تحتوي على الملتيميديا ، ولكن لم يتم التعرف عليها من قبل التطبيق، يمكنك إضافتها يدويا هنا.\n <string name="included_activity_placeholder">إذا كان لديك بعض المجلدات التي تحتوي على الملتيميديا ، ولكن لم يتم التعرف عليها من قبل التطبيق، يمكنك إضافتها يدويا هنا.\n \n لن تؤدي إضافة بعض العناصر هنا إلى استبعاد أي مجلد آخر.</string>
<string name="no_media_add_included">No media files have been found. You can solve it by adding the folders containing media files manually.</string> <string name="no_media_add_included">No media files have been found. You can solve it by adding the folders containing media files manually.</string>
\n
لن تؤدي إضافة بعض العناصر هنا إلى استبعاد أي مجلد آخر.</string>
<!-- Resizing --> <!-- Resizing -->
<string name="resize">تحجيم</string> <string name="resize">تحجيم</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filter media</string> <string name="filter_media">Filter media</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Data fixada correctament</string> <string name="dates_fixed_successfully">Data fixada correctament</string>
<string name="share_resized">Comparteix una versió redimensionada</string> <string name="share_resized">Comparteix una versió redimensionada</string>
<string name="upgraded_from_free">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 laplicació.\nNomés seliminaran els elements de la paperera, els elements preferits sense marcar i també caldrà restablirla configuració de la vostra aplicació.\n\nGràcies!</string> <string name="upgraded_from_free">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 laplicació.\nNomés seliminaran els elements de la paperera, els elements preferits sense marcar i també caldrà restablirla configuració de la vostra aplicació.\n\nGràcies!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtre darxius</string> <string name="filter_media">Filtre darxius</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datumy byly úspěšně opraveny</string> <string name="dates_fixed_successfully">Datumy byly úspěšně opraveny</string>
<string name="share_resized">Sdílet verzi se změněnou velikostí</string> <string name="share_resized">Sdílet verzi se změněnou velikostí</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtr médií</string> <string name="filter_media">Filtr médií</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datoer fikset med succes</string> <string name="dates_fixed_successfully">Datoer fikset med succes</string>
<string name="share_resized">Del en skaleret version</string> <string name="share_resized">Del en skaleret version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrer medier</string> <string name="filter_media">Filtrer medier</string>
@ -116,9 +117,9 @@
<string name="move_backwards">Kør baglæns</string> <string name="move_backwards">Kør baglæns</string>
<string name="loop_slideshow">Endeløs kørsel</string> <string name="loop_slideshow">Endeløs kørsel</string>
<string name="animation">Animation</string> <string name="animation">Animation</string>
<string name="no_animation">None</string> <string name="no_animation">Ingen</string>
<string name="fade">Fade</string> <string name="fade">Udton</string>
<string name="slide">Slide</string> <string name="slide">Glid</string>
<string name="slideshow_ended">Slideshowet endte</string> <string name="slideshow_ended">Slideshowet endte</string>
<string name="no_media_for_slideshow">Der blev ikke funket nogen mediefiler til slideshowet</string> <string name="no_media_for_slideshow">Der blev ikke funket nogen mediefiler til slideshowet</string>
@ -133,11 +134,11 @@
<string name="do_not_group_files">Gruppér ikke filer</string> <string name="do_not_group_files">Gruppér ikke filer</string>
<string name="by_folder">Mappe</string> <string name="by_folder">Mappe</string>
<string name="by_last_modified">Sidst ændret</string> <string name="by_last_modified">Sidst ændret</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Sidst ændret (daglig)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Sidst ændret (månedlig)</string>
<string name="by_date_taken">Eksponeringsdato</string> <string name="by_date_taken">Eksponeringsdato</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Eksponeringsdato (daglig)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Eksponeringsdato (månedlig)</string>
<string name="by_file_type">Filtype</string> <string name="by_file_type">Filtype</string>
<string name="by_extension">Filendelse</string> <string name="by_extension">Filendelse</string>
<string name="grouping_and_sorting">Vær opmærksom på at gruppering og sortering er to individuelle felter</string> <string name="grouping_and_sorting">Vær opmærksom på at gruppering og sortering er to individuelle felter</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datum erfolgreich korrigiert.</string> <string name="dates_fixed_successfully">Datum erfolgreich korrigiert.</string>
<string name="share_resized">Teile eine verkleinerte Version</string> <string name="share_resized">Teile eine verkleinerte Version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filter</string> <string name="filter_media">Filter</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Η Ημερ. διορθώθηκε με επιτυχία</string> <string name="dates_fixed_successfully">Η Ημερ. διορθώθηκε με επιτυχία</string>
<string name="share_resized">Διαμοιρασμός έκδοσης με αλλαγμένο μέγεθος</string> <string name="share_resized">Διαμοιρασμός έκδοσης με αλλαγμένο μέγεθος</string>
<string name="upgraded_from_free">Γειά σας,\n\nΦαίνεται πως αναβαθμίσατε από την παλιά δωρεάν εφαρμογή. Τώρα θα πρέπει να απεγκαταστήσετε την παλιά έκδοση, απο το πλήκτρο \"Αναβάθμιση σε Pro\" στο επάνω των ρυθμίσεων της εφαρμογής.\n\nΘα πρέπει να διαγράψετε μόνο τα αντικείμενα του Κάδου, πρέπει να επαναφέρετε τα αγαπημένα στοιχεία που δεν έχουν επισημανθεί καθώς και τις ρυθμίσεις της εφαρμογής σας.\n\nΣας ευχαριστώ!</string> <string name="upgraded_from_free">Γειά σας,\n\nΦαίνεται πως αναβαθμίσατε από την παλιά δωρεάν εφαρμογή. Τώρα θα πρέπει να απεγκαταστήσετε την παλιά έκδοση, απο το πλήκτρο \"Αναβάθμιση σε Pro\" στο επάνω των ρυθμίσεων της εφαρμογής.\n\nΘα πρέπει να διαγράψετε μόνο τα αντικείμενα του Κάδου, πρέπει να επαναφέρετε τα αγαπημένα στοιχεία που δεν έχουν επισημανθεί καθώς και τις ρυθμίσεις της εφαρμογής σας.\n\nΣας ευχαριστώ!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Φιλτράρισμα πολυμέσων</string> <string name="filter_media">Φιλτράρισμα πολυμέσων</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Fecha fijada correctamente</string> <string name="dates_fixed_successfully">Fecha fijada correctamente</string>
<string name="share_resized">Comparte una versión redimensionada</string> <string name="share_resized">Comparte una versión redimensionada</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtro de medios</string> <string name="filter_media">Filtro de medios</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Suodata media</string> <string name="filter_media">Suodata media</string>

View file

@ -17,9 +17,9 @@
<string name="unknown_location">Position inconnue</string> <string name="unknown_location">Position inconnue</string>
<string name="increase_column_count">Ajouter une colonne</string> <string name="increase_column_count">Ajouter une colonne</string>
<string name="reduce_column_count">Supprimer une colonne</string> <string name="reduce_column_count">Supprimer une colonne</string>
<string name="change_cover_image">Changer l\'image de vignette</string> <string name="change_cover_image">Changer l\'image du dossier</string>
<string name="select_photo">Sélectionner une image</string> <string name="select_photo">Choisir une image</string>
<string name="use_default">Utiliser par défaut</string> <string name="use_default">Image par défaut</string>
<string name="volume">Volume</string> <string name="volume">Volume</string>
<string name="brightness">Luminosité</string> <string name="brightness">Luminosité</string>
<string name="lock_orientation">Verrouiller la rotation</string> <string name="lock_orientation">Verrouiller la rotation</string>
@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates corrigées</string> <string name="dates_fixed_successfully">Dates corrigées</string>
<string name="share_resized">Partager une version redimensionnée</string> <string name="share_resized">Partager une version redimensionnée</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrer les médias</string> <string name="filter_media">Filtrer les médias</string>
@ -133,14 +134,14 @@
<string name="do_not_group_files">Ne pas grouper les fichiers</string> <string name="do_not_group_files">Ne pas grouper les fichiers</string>
<string name="by_folder">Dossier</string> <string name="by_folder">Dossier</string>
<string name="by_last_modified">Date de modification</string> <string name="by_last_modified">Date de modification</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Date de modification (par jour)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Date de modification (par mois)</string>
<string name="by_date_taken">Date de prise de vue</string> <string name="by_date_taken">Date de prise de vue</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Date de prise de vue (par jour)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Date de prise de vue (par mois)</string>
<string name="by_file_type">Type de fichier</string> <string name="by_file_type">Type de fichier</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<string name="grouping_and_sorting">Notez que grouper et trier sont 2 modes de tri indépendants</string> <string name="grouping_and_sorting">Notez que \'Grouper par\' et \'Trier par\' sont 2 modes indépendants</string>
<!-- Widgets --> <!-- Widgets -->
<string name="folder_on_widget">Dossier affiché sur le widget :</string> <string name="folder_on_widget">Dossier affiché sur le widget :</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrar medios</string> <string name="filter_media">Filtrar medios</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datumi uspješno popravljeni</string> <string name="dates_fixed_successfully">Datumi uspješno popravljeni</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtriranje medija</string> <string name="filter_media">Filtriranje medija</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Sikeres dátum javítás</string> <string name="dates_fixed_successfully">Sikeres dátum javítás</string>
<string name="share_resized">Átméretezett verzió megosztása</string> <string name="share_resized">Átméretezett verzió megosztása</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Média szűrő</string> <string name="filter_media">Média szűrő</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Tanggal berhasil diperbaiki</string> <string name="dates_fixed_successfully">Tanggal berhasil diperbaiki</string>
<string name="share_resized">Bagikan versi yang diubah ukurannya</string> <string name="share_resized">Bagikan versi yang diubah ukurannya</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filter media</string> <string name="filter_media">Filter media</string>

View file

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Simple Gallery</string>
<string name="app_launcher_name">Galeri</string>
<string name="edit">Sunting</string>
<string name="open_camera">Buka kamera</string>
<string name="hidden">(tersembunyi)</string>
<string name="excluded">(dikecualikan)</string>
<string name="pin_folder">Pin folder</string>
<string name="unpin_folder">Lepas pin folder</string>
<string name="pin_to_the_top">Pin ke atas</string>
<string name="show_all">Tampilkan semua isi folder</string>
<string name="all_folders">Semua folder</string>
<string name="folder_view">Beralih ke tampilan folder</string>
<string name="other_folder">Folder lain</string>
<string name="show_on_map">Tampilkan di peta</string>
<string name="unknown_location">Lokasi tidak diketahui</string>
<string name="increase_column_count">Tambah jumlah kolom</string>
<string name="reduce_column_count">Kurangi jumlah kolom</string>
<string name="change_cover_image">Ubah sampul</string>
<string name="select_photo">Pilih foto</string>
<string name="use_default">Gunakan default</string>
<string name="volume">Volume</string>
<string name="brightness">Kecerahan</string>
<string name="lock_orientation">Kunci rotasi</string>
<string name="unlock_orientation">Aktifkan rotasi</string>
<string name="change_orientation">Ubah orientasi</string>
<string name="force_portrait">Paksa potret</string>
<string name="force_landscape">Paksa lanskap</string>
<string name="use_default_orientation">Gunakan orientasi default</string>
<string name="fix_date_taken">Perbaiki Tanggal Diambil</string>
<string name="fixing">Memperbaiki…</string>
<string name="dates_fixed_successfully">Tanggal berhasil diperbaiki</string>
<string name="share_resized">Bagikan versi yang diubah ukurannya</string>
<string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter -->
<string name="filter_media">Filter media</string>
<string name="images">Gambar</string>
<string name="videos">Video</string>
<string name="gifs">GIF</string>
<string name="raw_images">Gambar RAW</string>
<string name="svgs">SVG</string>
<string name="no_media_with_filters">Tidak ada berkas media ditemukan dari filter ini.</string>
<string name="change_filters_underlined"><u>Ubah filter</u></string>
<!-- Hide / Exclude -->
<string name="hide_folder_description">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?</string>
<string name="exclude">Kecualikan</string>
<string name="excluded_folders">Folder yang dikecualikan</string>
<string name="manage_excluded_folders">Atur folder yang dikecualikan</string>
<string name="exclude_folder_description">Ini hanya akan mengecualikan pilihan bersama dengan subfoldernya di Simple Gallery. Anda bisa mengatur pengecualian di Pengaturan.</string>
<string name="exclude_folder_parent">Kecualikan folder induk?</string>
<string name="excluded_activity_placeholder">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.</string>
<string name="remove_all">Bersihkan daftar</string>
<string name="remove_all_description">Hapus semua folder dari daftar pengecualian? Ini tidak akan menghapus folder tersebut.</string>
<string name="hidden_folders">Folder tersembunyi</string>
<string name="manage_hidden_folders">Atur folder tersembunyi</string>
<string name="hidden_folders_placeholder">Sepertinya tidak ada folder tersembunyi dengan berkas \".nomedia\" didalamnya.</string>
<!-- Include folders -->
<string name="include_folders">Folder yang disertakan</string>
<string name="manage_included_folders">Atur folder yang disertakan</string>
<string name="add_folder">Tambah folder</string>
<string name="included_activity_placeholder">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.</string>
<string name="no_media_add_included">Tidak ada berkas media yang ditemukan. Anda bisa memperbaikinya dengan menambahkan folder yang berisi berkas media secara manual.</string>
<!-- Resizing -->
<string name="resize">Ubah ukuran</string>
<string name="resize_and_save">Ubah ukuran terpilih dan simpan</string>
<string name="width">Lebar</string>
<string name="height">Tinggi</string>
<string name="keep_aspect_ratio">Jaga aspek rasio</string>
<string name="invalid_values">Harap masukkan resolusi dengan benar</string>
<!-- Editor -->
<string name="editor">Penyunting</string>
<string name="save">Simpan</string>
<string name="rotate">Rotasi</string>
<string name="path">Jalur</string>
<string name="invalid_image_path">Jalur gambar tidak valid</string>
<string name="image_editing_failed">Gagal menyunting gambar</string>
<string name="edit_image_with">Sunting dengan:</string>
<string name="no_editor_found">Tidak ada aplikasi penyunting gambar</string>
<string name="unknown_file_location">Lokasi berkas tidak diketahui</string>
<string name="error_saving_file">Tidak bisa mengganti berkas sumber</string>
<string name="rotate_left">Putar ke kiri</string>
<string name="rotate_right">Putar ke kanan</string>
<string name="rotate_one_eighty">Putar 180º</string>
<string name="flip">Balik</string>
<string name="flip_horizontally">Balik horizontal</string>
<string name="flip_vertically">Balik vertikal</string>
<string name="free_aspect_ratio">Bebas</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Lainnya</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper -->
<string name="simple_wallpaper">Simple Wallpaper</string>
<string name="set_as_wallpaper">Setel wallpaper</string>
<string name="set_as_wallpaper_failed">Gagal menyetel sebagai wallpaper</string>
<string name="set_as_wallpaper_with">Setel wallpaper dengan:</string>
<string name="setting_wallpaper">Menyetel wallpaper&#8230;</string>
<string name="wallpaper_set_successfully">Wallpaper berhasil disetel</string>
<string name="portrait_aspect_ratio">Aspek rasio potret</string>
<string name="landscape_aspect_ratio">Aspek rasio lanskap</string>
<string name="home_screen">Layar beranda</string>
<string name="lock_screen">Layar kunci</string>
<string name="home_and_lock_screen">Beranda dan layar kunci</string>
<!-- Slideshow -->
<string name="slideshow">Slideshow</string>
<string name="interval">Interval (detik):</string>
<string name="include_photos">Sertakan foto</string>
<string name="include_videos">Sertakan video</string>
<string name="include_gifs">Sertakan GIF</string>
<string name="random_order">Urutan acak</string>
<string name="move_backwards">Mundur</string>
<string name="loop_slideshow">Slideshow tanpa henti</string>
<string name="animation">Animation</string>
<string name="no_animation">None</string>
<string name="fade">Fade</string>
<string name="slide">Slide</string>
<string name="slideshow_ended">Slideshow berakhir</string>
<string name="no_media_for_slideshow">Tidak ditemukan media untuk slideshow</string>
<!-- View types -->
<string name="change_view_type">Ubah jenis tampilan</string>
<string name="grid">Kotak</string>
<string name="list">Daftar</string>
<string name="group_direct_subfolders">Kelompokkan subfolder langsung</string>
<!-- Grouping at media thumbnails -->
<string name="group_by">Kelompokkan menurut</string>
<string name="do_not_group_files">Jangan kelompokkan berkas</string>
<string name="by_folder">Folder</string>
<string name="by_last_modified">Terakhir diubah</string>
<string name="by_last_modified_daily">Last modified (daily)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string>
<string name="by_date_taken">Tanggal diambil</string>
<string name="by_date_taken_daily">Date taken (daily)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string>
<string name="by_file_type">Jenis berkas</string>
<string name="by_extension">Ekstensi</string>
<string name="grouping_and_sorting">Harap dicatat bahwa mengelompokkan dan mengurutkan adalah 2 ruas yang berbeda</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder yang ditampilkan pada widget:</string>
<string name="show_folder_name">Tampilkan nama folder</string>
<!-- Settings -->
<string name="autoplay_videos">Putar video otomatis</string>
<string name="remember_last_video_position">Ingat posisi pemutaran terakhir</string>
<string name="toggle_filename">Tampil/sembunyikan nama berkas</string>
<string name="loop_videos">Ulangi video</string>
<string name="animate_gifs">Animasi GIF di thumbnail</string>
<string name="max_brightness">Kecerahan maksimal saat melihat di layar penuh</string>
<string name="crop_thumbnails">Pangkas thumbnail menjadi persegi</string>
<string name="show_thumbnail_video_duration">Tampilkan durasi video</string>
<string name="screen_rotation_by">Rotasi layar penuh dari</string>
<string name="screen_rotation_system_setting">Pengaturan sistem</string>
<string name="screen_rotation_device_rotation">Rotasi perangkat</string>
<string name="screen_rotation_aspect_ratio">Aspek rasio</string>
<string name="black_background_at_fullscreen">Background dan status bar hitam saat layar penuh</string>
<string name="scroll_thumbnails_horizontally">Gulir thumbnail secara horizontal</string>
<string name="hide_system_ui_at_fullscreen">Otomatis sembunyikan sistem UI saat layar penuh</string>
<string name="delete_empty_folders">Hapus folder kosong setelah menghapus isinya</string>
<string name="allow_photo_gestures">Izinkan mengontrol kecerahan foto dengan gerakan vertikal</string>
<string name="allow_video_gestures">Izinkan mengontrol kecerahan dan volume video dengan gerakan vertikal</string>
<string name="show_media_count">Tampilkan jumlah folder media di tampilan utama</string>
<string name="show_extended_details">Tampilkan detail tambahan saat layar penuh</string>
<string name="manage_extended_details">Atur detail tambahan</string>
<string name="one_finger_zoom">Izinkan zoom satu jari di layar penuh</string>
<string name="allow_instant_change">Izinkan mengganti media dengan mengklik sisi layar</string>
<string name="allow_deep_zooming_images">Izinkan zoom gambar lebih dalam</string>
<string name="hide_extended_details">Sembunyikan detail tambahan ketika status bar disembunyikan</string>
<string name="show_at_bottom">Tampilkan beberapa tombol tindakan dibawah layar</string>
<string name="show_recycle_bin">Tampilkan Sampah di layar folder</string>
<string name="deep_zoomable_images">Zoom gambar mendalam</string>
<string name="show_highest_quality">Tampilkan gambar dalam kualitas tertinggi</string>
<string name="show_recycle_bin_last">Tampilkan Sampah sebagai item terakhir di layar utama</string>
<string name="allow_down_gesture">Izinkan keluar dari layar penuh dengan menggeser kebawah</string>
<string name="allow_one_to_one_zoom">Izinkan pembesaran 1:1 dengan dua kali ketuk</string>
<string name="open_videos_on_separate_screen">Selalu buka video pada layar terpisah dengan gestur horizontal baru</string>
<string name="show_notch">Tampilkan notch jika tersedia</string>
<string name="allow_rotating_gestures">Izinkan memutar gambar dengan gestur</string>
<string name="file_loading_priority">Prioritas pemuatan berkas</string>
<string name="speed">Kecepatan</string>
<string name="compromise">Kompromi</string>
<string name="avoid_showing_invalid_files">Hindari menampilkan berkas yang tidak valid</string>
<!-- Setting sections -->
<string name="thumbnails">Thumbnail</string>
<string name="fullscreen_media">Media layar penuh</string>
<string name="extended_details">Detail tambahan</string>
<string name="bottom_actions">Tindakan bawah</string>
<!-- Bottom actions -->
<string name="manage_bottom_actions">Sesuaikan tombol tindakan bawah</string>
<string name="toggle_favorite">Favorit</string>
<string name="toggle_file_visibility">Tampil/sembunyikan berkas</string>
<!-- FAQ -->
<string name="faq_1_title">Bagaimana cara menjadikan Simple Gallery sebagai aplikasi galeri default?</string>
<string name="faq_1_text">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.</string>
<string name="faq_2_title">Saya mengunci aplikasi dengan sandi, tapi saya lupa. Apa yang harus dilakukan?</string>
<string name="faq_2_text">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.</string>
<string name="faq_3_title">Bagaimana agar sebuah album selalu muncul paling atas di daftar?</string>
<string name="faq_3_text">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.</string>
<string name="faq_4_title">Bagaimana cara mempercepat laju video?</string>
<string name="faq_4_text">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.</string>
<string name="faq_5_title">Apa perbedaan antara menyembunyikan dan mengecualikan folder?</string>
<string name="faq_5_text">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.</string>
<string name="faq_6_title">Mengapa folder dengan gambar album musik atau stiker muncul?</string>
<string name="faq_6_text">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.</string>
<string name="faq_7_title">Ada folder berisi gambar namun tidak muncul, apa yang harus dilakukan?</string>
<string name="faq_7_text">Itu bisa disebabkan berbagai alasan, namun solusinya mudah. Pergi ke Pengaturan -> Atur folder yang disertakan, pilih Tambah dan cari folder yang diinginkan.</string>
<string name="faq_8_title">Bagaimana jika saya hanya ingin beberapa folder saja yang terlihat?</string>
<string name="faq_8_text">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.</string>
<string name="faq_10_title">Bisakah saya meng-crop gambar dengan aplikasi ini?</string>
<string name="faq_10_text">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.</string>
<string name="faq_11_title">Bisakah saya mengelompokkan thumbnail berkas media?</string>
<string name="faq_11_text">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.</string>
<string name="faq_12_title">Tidak bisa mengurutkan berdasarkan Tanggal Diambil, bagaimana cara memperbaikinya?</string>
<string name="faq_12_text">Itu umumnya disebabkan karena berkas yang disalin dari tempat lain. Anda bisa memperbaikinya dengan memilih berkas thumbnail dan pilih \"Perbaiki Tanggal Diambil\".</string>
<string name="faq_13_title">Saya melihat beberapa pita warna pada gambar. Bagaimana saya meningkatkan kualitasnya?</string>
<string name="faq_13_text">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\".</string>
<string name="faq_14_title">Saya punya berkas/folder tersembunyi. Bagaimana cara memunculkannya?</string>
<string name="faq_14_text">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.</string>
<string name="faq_15_title">Kenapa aplikasi menggunakan sangat banyak ruang kosong?</string>
<string name="faq_15_text">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.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple Gallery Pro: Pengelola &amp; Penyunting Foto</string>
<!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Galeri luring tanpa iklan. Kelola, sunting, pulihkan dan lindungi foto &amp; video</string>
<string name="app_long_description">
Simple Gallery Pro adalah aplikasi galeri luring yang sangat mudah diubahsuai. Mengelola &amp; menyunting foto anda, memulihkan berkas yang terhapus dari keranjang sampah, melindungi &amp; menyembunyikan berkas, dan menampilkan banyak format foto &amp; 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.
-------------------------------------------------
<b>SIMPLE GALLERY PRO FEATURES</b>
-------------------------------------------------
• Offline gallery with no ads or popups
• Simple gallery photo editor crop, rotate, resize, draw, filters &amp; more
• No internet access needed, giving you more privacy and security
• No unnecessary permissions required
• Quickly search images, videos &amp; files
• Open &amp; view many different photo and video types (RAW, SVG, panoramic etc)
• A variety of intuitive gestures to easily edit &amp; organize files
• Lots of ways to filter, group &amp; sort files
• Customize the appearance of Simple Gallery Pro
• Available in 32 languages
• Mark files as favorites for quick access
• Protect your photos &amp; videos with a pattern, pin or fingerprint
• Use pin, pattern &amp; fingerprint to protect the app launch or specific functions too
• Recover deleted photos &amp; videos from the recycle bin
• Toggle visibility of files to hide photos &amp; 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!
<b>PHOTO GALLERY EDITOR</b>
Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If youre feeling a little more creative you can add filters and draw on your pictures!
<b>SUPPORT FOR MANY FILE TYPES</b>
Unlike some other gallery viewers &amp; 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>HIGHLY CUSTOMIZABLE GALLERY MANAGER</b>
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, were also available in 32 languages!
<b>RECOVER DELETED PHOTOS &amp; VIDEOS</b>
Accidentally deleted a precious photo or video? Dont worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos &amp; videos easily.
<b>PROTECT &amp; HIDE PHOTOS, VIDEOS &amp; FILES</b>
Using pin, pattern or your devices fingerprint scanner you can protect and hide photos, videos &amp; entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you cant delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
<b>Check out the full suite of Simple Tools here:</b>
https://www.simplemobiletools.com
<b>Facebook:</b>
https://www.facebook.com/simplemobiletools
<b>Reddit:</b>
https://www.reddit.com/r/SimpleMobileTools
</string>
<!--
Haven't found some strings? There's more at
https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
-->
</resources>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Date aggiornate correttamente</string> <string name="dates_fixed_successfully">Date aggiornate correttamente</string>
<string name="share_resized">Condividi una versione ridimensionata</string> <string name="share_resized">Condividi una versione ridimensionata</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtra i file</string> <string name="filter_media">Filtra i file</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">撮影日が正常に修正されました</string> <string name="dates_fixed_successfully">撮影日が正常に修正されました</string>
<string name="share_resized">リサイズした画像を共有</string> <string name="share_resized">リサイズした画像を共有</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">表示する形式</string> <string name="filter_media">表示する形式</string>
@ -115,10 +116,10 @@
<string name="random_order">ランダムな順序</string> <string name="random_order">ランダムな順序</string>
<string name="move_backwards">逆方向に進む</string> <string name="move_backwards">逆方向に進む</string>
<string name="loop_slideshow">スライドショーをリピート再生する</string> <string name="loop_slideshow">スライドショーをリピート再生する</string>
<string name="animation">Animation</string> <string name="animation">アニメーション</string>
<string name="no_animation">None</string> <string name="no_animation">なし</string>
<string name="fade">Fade</string> <string name="fade">フェード</string>
<string name="slide">Slide</string> <string name="slide">スライド</string>
<string name="slideshow_ended">スライドショーが終了しました</string> <string name="slideshow_ended">スライドショーが終了しました</string>
<string name="no_media_for_slideshow">スライドショーに表示するメディアがありません</string> <string name="no_media_for_slideshow">スライドショーに表示するメディアがありません</string>
@ -133,11 +134,11 @@
<string name="do_not_group_files">何もしない</string> <string name="do_not_group_files">何もしない</string>
<string name="by_folder">フォルダ</string> <string name="by_folder">フォルダ</string>
<string name="by_last_modified">更新日時</string> <string name="by_last_modified">更新日時</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">更新日時 (毎日)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">更新日時 (毎月)</string>
<string name="by_date_taken">撮影日時</string> <string name="by_date_taken">撮影日時</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">撮影日時 (毎日)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">撮影日時 (毎月)</string>
<string name="by_file_type">ファイル形式</string> <string name="by_file_type">ファイル形式</string>
<string name="by_extension">拡張子</string> <string name="by_extension">拡張子</string>
<string name="grouping_and_sorting">Please note that grouping and sorting are 2 independent fields</string> <string name="grouping_and_sorting">Please note that grouping and sorting are 2 independent fields</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">미디어 필터 설정</string> <string name="filter_media">미디어 필터 설정</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtruoti mediją</string> <string name="filter_media">Filtruoti mediją</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datoer er korrigerte</string> <string name="dates_fixed_successfully">Datoer er korrigerte</string>
<string name="share_resized">Del versjon med endret størrelse</string> <string name="share_resized">Del versjon med endret størrelse</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrer media</string> <string name="filter_media">Filtrer media</string>
@ -63,7 +64,7 @@
<string name="manage_included_folders">Håndter inkluderte mapper</string> <string name="manage_included_folders">Håndter inkluderte mapper</string>
<string name="add_folder">Legg til mappe</string> <string name="add_folder">Legg til mappe</string>
<string name="included_activity_placeholder">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.</string> <string name="included_activity_placeholder">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.</string>
<string name="no_media_add_included">No media files have been found. You can solve it by adding the folders containing media files manually.</string> <string name="no_media_add_included">Ingen mediafiler er funnet. Dette kan løses ved å legge til mapper som inneholder mediafiler manuelt.</string>
<!-- Resizing --> <!-- Resizing -->
<string name="resize">Endre størrelse</string> <string name="resize">Endre størrelse</string>
@ -115,8 +116,8 @@
<string name="random_order">Tilfeldig rekkefølge</string> <string name="random_order">Tilfeldig rekkefølge</string>
<string name="move_backwards">Avspill bakover</string> <string name="move_backwards">Avspill bakover</string>
<string name="loop_slideshow">Gjenta lysbildeshow</string> <string name="loop_slideshow">Gjenta lysbildeshow</string>
<string name="animation">Animation</string> <string name="animation">Animasjon</string>
<string name="no_animation">None</string> <string name="no_animation">Ingen</string>
<string name="fade">Fade</string> <string name="fade">Fade</string>
<string name="slide">Slide</string> <string name="slide">Slide</string>
<string name="slideshow_ended">Lysbildeshowet er slutt</string> <string name="slideshow_ended">Lysbildeshowet er slutt</string>
@ -133,11 +134,11 @@
<string name="do_not_group_files">Ikke grupper filer</string> <string name="do_not_group_files">Ikke grupper filer</string>
<string name="by_folder">Mappe</string> <string name="by_folder">Mappe</string>
<string name="by_last_modified">Sist endret</string> <string name="by_last_modified">Sist endret</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Sist endret (daglig)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Sist endret (månedlig)</string>
<string name="by_date_taken">Dato tatt</string> <string name="by_date_taken">Dato tatt</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Dato tatt (daglig)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Dato tatt (månedlig)</string>
<string name="by_file_type">Filtype</string> <string name="by_file_type">Filtype</string>
<string name="by_extension">Endelse</string> <string name="by_extension">Endelse</string>
<string name="grouping_and_sorting">Vær oppmerksom på at gruppering og sortering er to uavhengige områder</string> <string name="grouping_and_sorting">Vær oppmerksom på at gruppering og sortering er to uavhengige områder</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datums zijn gecorrigeerd</string> <string name="dates_fixed_successfully">Datums zijn gecorrigeerd</string>
<string name="share_resized">Verkleinde versie delen</string> <string name="share_resized">Verkleinde versie delen</string>
<string name="upgraded_from_free">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.</string> <string name="upgraded_from_free">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.</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Media filteren</string> <string name="filter_media">Media filteren</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Daty zostały naprawione</string> <string name="dates_fixed_successfully">Daty zostały naprawione</string>
<string name="share_resized">Udostępnij zmienioną wersję</string> <string name="share_resized">Udostępnij zmienioną wersję</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtruj multimedia</string> <string name="filter_media">Filtruj multimedia</string>

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Simple Gallery</string> <string name="app_name">Simple Galeria</string>
<string name="app_launcher_name">Galeria</string> <string name="app_launcher_name">Galeria</string>
<string name="edit">Editar</string> <string name="edit">Editar</string>
<string name="open_camera">Abrir câmera</string> <string name="open_camera">Abrir câmera</string>
<string name="hidden">(oculto)</string> <string name="hidden">(oculto)</string>
<string name="excluded">(excluído)</string> <string name="excluded">(excluído)</string>
<string name="pin_folder">Fixar pasta</string> <string name="pin_folder">Fixar pasta</string>
<string name="unpin_folder">Desfixar pasta</string> <string name="unpin_folder">Desafixar pasta</string>
<string name="pin_to_the_top">Fixar no topo</string> <string name="pin_to_the_top">Fixar no topo</string>
<string name="show_all">Mostrar conteúdo de todas as pastas</string> <string name="show_all">Mostrar conteúdo de todas as pastas</string>
<string name="all_folders">Todas as pastas</string> <string name="all_folders">Todas as pastas</string>
@ -24,46 +24,47 @@
<string name="brightness">Brilho</string> <string name="brightness">Brilho</string>
<string name="lock_orientation">Travar orientação</string> <string name="lock_orientation">Travar orientação</string>
<string name="unlock_orientation">Destravar orientação</string> <string name="unlock_orientation">Destravar orientação</string>
<string name="change_orientation">Mudar orientação</string> <string name="change_orientation">Alterar orientação</string>
<string name="force_portrait">Forçar modo retrato</string> <string name="force_portrait">Forçar modo retrato</string>
<string name="force_landscape">Forçar modo paisagem</string> <string name="force_landscape">Forçar modo paisagem</string>
<string name="use_default_orientation">Usar orientação padrão</string> <string name="use_default_orientation">Usar orientação padrão</string>
<string name="fix_date_taken">Fix Date Taken value</string> <string name="fix_date_taken">Corrigir data da foto</string>
<string name="fixing">Fixing…</string> <string name="fixing">Corrigindo…</string>
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Datas corrigidas com sucesso</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Compartilhar uma versão redimensionada</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrar mídia</string> <string name="filter_media">Filtrar mídia</string>
<string name="images">Imagens</string> <string name="images">Imagens</string>
<string name="videos">Vídeos</string> <string name="videos">Vídeos</string>
<string name="gifs">GIFs</string> <string name="gifs">GIFs</string>
<string name="raw_images">RAW images</string> <string name="raw_images">Imagens RAW</string>
<string name="svgs">SVGs</string> <string name="svgs">SVGs</string>
<string name="no_media_with_filters">Nenhum arquivo de mídia encontrado a partir dos filtros selecionados.</string> <string name="no_media_with_filters">Nenhum arquivo de mídia encontrado a partir dos filtros selecionados.</string>
<string name="change_filters_underlined"><u>Mudar filtros</u></string> <string name="change_filters_underlined"><u>Alterar filtros</u></string>
<!-- Hide / Exclude --> <!-- Hide / Exclude -->
<string name="hide_folder_description">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?</string> <string name="hide_folder_description">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?</string>
<string name="exclude">Excluir</string> <string name="exclude">Ignorar</string>
<string name="excluded_folders">Pastas excluídas</string> <string name="excluded_folders">Pastas ignoradas</string>
<string name="manage_excluded_folders">Gerenciar pastas excluídas</string> <string name="manage_excluded_folders">Gerenciar pastas ignoradas</string>
<string name="exclude_folder_description">Esta ação irá excluir as pastas selecionadas apenas dentro deste aplicativo. Você pode gerenciar as pastas excuídas nas Configurações do aplicativo.</string> <string name="exclude_folder_description">Esta ação deixará de exibir as pastas selecionadas apenas dentro deste aplicativo. Você pode gerenciar as pastas ignoradas nas Configurações do aplicativo.</string>
<string name="exclude_folder_parent">Excluir antes a pasta raiz?</string> <string name="exclude_folder_parent">Ignorar a pasta raiz ao invés desta?</string>
<string name="excluded_activity_placeholder">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.</string> <string name="excluded_activity_placeholder">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.</string>
<string name="remove_all">Remover todas</string> <string name="remove_all">Remover todas</string>
<string name="remove_all_description">Remover todas as pastas da lista de exclusões? Esta ação não apaga as pastas.</string> <string name="remove_all_description">Remover todas as pastas da lista de pastas ignoradas? Esta ação não exclui as pastas.</string>
<string name="hidden_folders">Pastas ocultas</string> <string name="hidden_folders">Pastas ocultas</string>
<string name="manage_hidden_folders">Gerenciar pastas ocultas</string> <string name="manage_hidden_folders">Gerenciar pastas ocultas</string>
<string name="hidden_folders_placeholder">Parece que você não tem nenhuma pasta oculta com um arquivo \".nomedia\".</string> <string name="hidden_folders_placeholder">Parece que você não tem nenhuma pasta ocultada por um arquivo \".nomedia\".</string>
<!-- Include folders --> <!-- Include folders -->
<string name="include_folders">Pastas incluídas</string> <string name="include_folders">Pastas incluídas</string>
<string name="manage_included_folders">Gerenciar pastas incluídas</string> <string name="manage_included_folders">Gerenciar pastas incluídas</string>
<string name="add_folder">Adicionar pasta</string> <string name="add_folder">Adicionar pasta</string>
<string name="included_activity_placeholder">Se possuir pastas com dados multimídia não reconhecidos pelo aplicativo, aqui você pode adicioná-las manualmente.</string> <string name="included_activity_placeholder">Se você possuir pastas com dados multimídia não reconhecidos pelo aplicativo, aqui você pode adicioná-las manualmente.</string>
<string name="no_media_add_included">No media files have been found. You can solve it by adding the folders containing media files manually.</string> <string name="no_media_add_included">Nenhum arquivo de mídia foi encontrado. Como alternativa você pode tentar incluir manualmente as pastas com arquivos de mídia.</string>
<!-- Resizing --> <!-- Resizing -->
<string name="resize">Redimensionar</string> <string name="resize">Redimensionar</string>
@ -90,16 +91,16 @@
<string name="flip">Inverter</string> <string name="flip">Inverter</string>
<string name="flip_horizontally">Horizontalmente</string> <string name="flip_horizontally">Horizontalmente</string>
<string name="flip_vertically">Verticalmente</string> <string name="flip_vertically">Verticalmente</string>
<string name="free_aspect_ratio">Gratuito</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">Livre</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Outro</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">Outro</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">Simple Wallpaper</string> <string name="simple_wallpaper">Simple Papel de Parede</string>
<string name="set_as_wallpaper">Definir como papel de parede</string> <string name="set_as_wallpaper">Definir como papel de parede</string>
<string name="set_as_wallpaper_failed">Falha ao definir como papel de parede</string> <string name="set_as_wallpaper_failed">Falha ao definir como papel de parede</string>
<string name="set_as_wallpaper_with">Definir papel de parede com:</string> <string name="set_as_wallpaper_with">Definir papel de parede com:</string>
<string name="setting_wallpaper">Definindo como papel de parede</string> <string name="setting_wallpaper">Definindo como papel de parede</string>
<string name="wallpaper_set_successfully">Papel de parede com sucesso</string> <string name="wallpaper_set_successfully">Papel de parede definido com sucesso</string>
<string name="portrait_aspect_ratio">Retrato</string> <string name="portrait_aspect_ratio">Retrato</string>
<string name="landscape_aspect_ratio">Paisagem</string> <string name="landscape_aspect_ratio">Paisagem</string>
<string name="home_screen">Tela inicial</string> <string name="home_screen">Tela inicial</string>
@ -110,15 +111,15 @@
<string name="slideshow">Apresentação</string> <string name="slideshow">Apresentação</string>
<string name="interval">Intervalo (segundos):</string> <string name="interval">Intervalo (segundos):</string>
<string name="include_photos">Incluir fotos</string> <string name="include_photos">Incluir fotos</string>
<string name="include_videos">Incluir videos</string> <string name="include_videos">Incluir vídeos</string>
<string name="include_gifs">Incluir GIFs</string> <string name="include_gifs">Incluir GIFs</string>
<string name="random_order">Ordem aleatória</string> <string name="random_order">Ordem aleatória</string>
<string name="move_backwards">Retroceder</string> <string name="move_backwards">Retroceder</string>
<string name="loop_slideshow">Apresentação em ciclo</string> <string name="loop_slideshow">Apresentação em ciclo</string>
<string name="animation">Animation</string> <string name="animation">Animação</string>
<string name="no_animation">None</string> <string name="no_animation">Nenhuma</string>
<string name="fade">Fade</string> <string name="fade">Esmaecer</string>
<string name="slide">Slide</string> <string name="slide">Deslizar</string>
<string name="slideshow_ended">Fim da apresentação</string> <string name="slideshow_ended">Fim da apresentação</string>
<string name="no_media_for_slideshow">Nenhuma mídia encontrada para a apresentação</string> <string name="no_media_for_slideshow">Nenhuma mídia encontrada para a apresentação</string>
@ -126,24 +127,24 @@
<string name="change_view_type">Alterar modo de visualização</string> <string name="change_view_type">Alterar modo de visualização</string>
<string name="grid">Grade</string> <string name="grid">Grade</string>
<string name="list">Lista</string> <string name="list">Lista</string>
<string name="group_direct_subfolders">Agrupar subpastas do diretório</string> <string name="group_direct_subfolders">Agrupar subpastas diretas</string>
<!-- Grouping at media thumbnails --> <!-- Grouping at media thumbnails -->
<string name="group_by">Agrupar por</string> <string name="group_by">Agrupar por</string>
<string name="do_not_group_files">Não agrupar arquivos</string> <string name="do_not_group_files">Não agrupar arquivos</string>
<string name="by_folder">Pasta</string> <string name="by_folder">Pasta</string>
<string name="by_last_modified">Última modificação</string> <string name="by_last_modified">Última modificação</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Última modificação (por dia)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Última modificação (por mês)</string>
<string name="by_date_taken">Data de criação</string> <string name="by_date_taken">Data da foto</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Data da foto (por dia)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Data da foto (por mês)</string>
<string name="by_file_type">Tipo de arquivo</string> <string name="by_file_type">Tipo de arquivo</string>
<string name="by_extension">Extensão</string> <string name="by_extension">Extensão</string>
<string name="grouping_and_sorting">Por favor, note que o agrupamento e classificação são 2 campos independentes</string> <string name="grouping_and_sorting">Por favor, lembre-se que o agrupamento e classificação são configurados por dois campos independentes</string>
<!-- Widgets --> <!-- Widgets -->
<string name="folder_on_widget">Exibição da Pasta no widget:</string> <string name="folder_on_widget">Pasta exibida no widget:</string>
<string name="show_folder_name">Exibir nome da pasta</string> <string name="show_folder_name">Exibir nome da pasta</string>
<!-- Settings --> <!-- Settings -->
@ -151,135 +152,132 @@
<string name="remember_last_video_position">Lembrar da última posição de reprodução de vídeo</string> <string name="remember_last_video_position">Lembrar da última posição de reprodução de vídeo</string>
<string name="toggle_filename">Mostrar/ocultar nome do arquivo</string> <string name="toggle_filename">Mostrar/ocultar nome do arquivo</string>
<string name="loop_videos">Reproduzir vídeos em ciclo</string> <string name="loop_videos">Reproduzir vídeos em ciclo</string>
<string name="animate_gifs">Animação de GIFs nas miniaturas</string> <string name="animate_gifs">Animar GIFs nas miniaturas</string>
<string name="max_brightness">Brilho máximo ao visualizar mídia</string> <string name="max_brightness">Maximizar o brilho ao visualizar mídia em tela cheia</string>
<string name="crop_thumbnails">Recortar miniaturas em quadrados</string> <string name="crop_thumbnails">Recortar miniaturas em quadrados</string>
<string name="show_thumbnail_video_duration">Exibir durações de vídeo</string> <string name="show_thumbnail_video_duration">Exibir duração dos vídeos</string>
<string name="screen_rotation_by">Critério para rotação de tela</string> <string name="screen_rotation_by">Critério para rotação de tela</string>
<string name="screen_rotation_system_setting">Padrão do sistema</string> <string name="screen_rotation_system_setting">Padrão do sistema</string>
<string name="screen_rotation_device_rotation">Sensor do aparelho</string> <string name="screen_rotation_device_rotation">Sensor do aparelho</string>
<string name="screen_rotation_aspect_ratio">Proporção da mídia</string> <string name="screen_rotation_aspect_ratio">Proporção da mídia</string>
<string name="black_background_at_fullscreen">Fundo de tela e barra de status preta quando em visualização de tela cheia</string> <string name="black_background_at_fullscreen">Fundo de tela e barra de status preta quando em visualização de tela cheia</string>
<string name="scroll_thumbnails_horizontally">Rolar miniaturas horizontalmente</string> <string name="scroll_thumbnails_horizontally">Rolar miniaturas horizontalmente</string>
<string name="hide_system_ui_at_fullscreen">Esconder interface do sistema automaticamente quando em tela cheia</string> <string name="hide_system_ui_at_fullscreen">Esconder interface do sistema quando em tela cheia</string>
<string name="delete_empty_folders">Apagar pastas vazias após deleter seu conteúdo</string> <string name="delete_empty_folders">Apagar pastas vazias após excluir o seu conteúdo</string>
<string name="allow_photo_gestures">Permitir controle do brilho com gestos na vertical</string> <string name="allow_photo_gestures">Permitir controle do brilho com gestos na vertical</string>
<string name="allow_video_gestures">Permitir controle do volume e brilho com gestos na vertical</string> <string name="allow_video_gestures">Permitir controle do volume e brilho com gestos na vertical</string>
<string name="show_media_count">Mostrar quantidade de arquivos das pastas</string> <string name="show_media_count">Mostrar quantidade de arquivos em cada pasta na tela inicial</string>
<string name="show_extended_details">Exibir detalhes extendidos quando em tela cheia</string> <string name="show_extended_details">Exibir detalhes adicionais quando em tela cheia</string>
<string name="manage_extended_details">Gerenciar detalhes extendidos</string> <string name="manage_extended_details">Gerenciar detalhes adicionais</string>
<string name="one_finger_zoom">Permitir zoom com um dedo quando em exibição de tela cheia</string> <string name="one_finger_zoom">Permitir zoom com um dedo quando em exibição de tela cheia</string>
<string name="allow_instant_change">Permitir alternância instantânia de mídia clicando nas laterais da tela</string> <string name="allow_instant_change">Tocar na lateral da tela navega para a próxima imagem ou vídeo</string>
<string name="allow_deep_zooming_images">Permitir zoom aprofundado em imagens</string> <string name="allow_deep_zooming_images">Permitir zoom aprofundado para imagens</string>
<string name="hide_extended_details">Ocultar detalhes extendidos quando a barra de status estiver oculta</string> <string name="hide_extended_details">Ocultar detalhes adicionais quando a barra de status estiver oculta</string>
<string name="show_at_bottom">Mostrar alguns botões de ação na parte inferior da tela</string> <string name="show_at_bottom">Mostrar alguns botões de ação na parte inferior da tela</string>
<string name="show_recycle_bin">Mostar a Lixeira na tela de pastas</string> <string name="show_recycle_bin">Mostrar a Lixeira na tela inicial</string>
<string name="deep_zoomable_images">Imagens com zoom aprofundado</string> <string name="deep_zoomable_images">Zoom aprofundado para imagens</string>
<string name="show_highest_quality">Mostrar imagens com a maior qualidade possível</string> <string name="show_highest_quality">Mostrar imagens na maior qualidade possível</string>
<string name="show_recycle_bin_last">Mostrar a Lixeira como o último item na tela principal</string> <string name="show_recycle_bin_last">Mostrar a Lixeira como o último item na tela inicial</string>
<string name="allow_down_gesture">Permitir fechar a exibição em tela cheia com um gesto para baixo</string> <string name="allow_down_gesture">Gesto para baixo sai da exibição em tela cheia</string>
<string name="allow_one_to_one_zoom">Permitir zoom 1:1 com dois toques duplos</string> <string name="allow_one_to_one_zoom">Dois toques duplos fazem zoom 1:1</string>
<string name="open_videos_on_separate_screen">Sempre abrir vídeos em uma tela separada com novos gestos horizontais</string> <string name="open_videos_on_separate_screen">Sempre abrir vídeos em uma tela separada com novos gestos horizontais</string>
<string name="show_notch">Mostrar um encaixe, se disponível</string> <string name="show_notch">Mostrar o notch, se existente</string>
<string name="allow_rotating_gestures">Permitir rotação de imagens com gestos</string> <string name="allow_rotating_gestures">Permitir rotação de imagens com gestos</string>
<string name="file_loading_priority">Prioridade de carregamento de arquivos</string> <string name="file_loading_priority">Prioridade de carregamento de arquivos</string>
<string name="speed">Velocidade</string> <string name="speed">Velocidade</string>
<string name="compromise">Compromise</string> <string name="compromise">Meio termo</string>
<string name="avoid_showing_invalid_files">Evite exibit arquivos inválidos</string> <string name="avoid_showing_invalid_files">Evitar a exibição de arquivos inválidos</string>
<!-- Setting sections --> <!-- Setting sections -->
<string name="thumbnails">Miniaturas</string> <string name="thumbnails">Miniaturas</string>
<string name="fullscreen_media">Mídia em tela cheia</string> <string name="fullscreen_media">Mídia em tela cheia</string>
<string name="extended_details">Detalhes extendidos</string> <string name="extended_details">Detalhes adicionais</string>
<string name="bottom_actions">Bottom actions</string> <string name="bottom_actions">Botões de ação</string>
<!-- Bottom actions --> <!-- Bottom actions -->
<string name="manage_bottom_actions">Manage visible bottom actions</string> <string name="manage_bottom_actions">Gerenciar botões de ação</string>
<string name="toggle_favorite">Toggle favorite</string> <string name="toggle_favorite">Favoritar/Desfavoritar</string>
<string name="toggle_file_visibility">Toggle file visibility</string>v <string name="toggle_file_visibility">Exibir/Ocultar arquivo</string>v
<!-- FAQ --> <!-- FAQ -->
<string name="faq_1_title">Como eu posso tornar o Simple Gallery como galeria padrão do meu aparelho?</string> <string name="faq_1_title">O que devo fazer para que a Simple Galeria seja o aplicativo de galeria padrão do meu aparelho?</string>
<string name="faq_1_text">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\". <string name="faq_1_text">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".
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.</string> 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.</string>
<string name="faq_2_title">I locked the app with a password, but I forgot it. What can I do?</string> <string name="faq_2_title">Eu protegi o app com senha, mas me esqueci da senha. O que posso fazer?</string>
<string name="faq_2_text">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.</string> <string name="faq_2_text">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".</string>
<string name="faq_3_title">How can I make an album always appear at the top?</string> <string name="faq_3_title">Como posso fazer para que uma pasta sempre apareça no topo da lista?</string>
<string name="faq_3_text">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.</string> <string name="faq_3_text">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.</string>
<string name="faq_4_title">How can I fast-forward videos?</string> <string name="faq_4_title">Como faço para avançar rapidamente um vídeo (fast-forward)?</string>
<string name="faq_4_text">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.</string> <string name="faq_4_text">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.</string>
<string name="faq_5_title">What is the difference between hiding and excluding a folder?</string> <string name="faq_5_title">Qual é a diferença entre ocultar e ignorar uma pasta?</string>
<string name="faq_5_text">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.</string> <string name="faq_5_text">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.</string>
<string name="faq_6_title">Why do folders with music cover art or stickers show up?</string> <string name="faq_6_title">Porque pastas com capas de CD de música ou figurinhas aparecem na lista?</string>
<string name="faq_6_text">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.</string> <string name="faq_6_text">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.</string>
<string name="faq_7_title">A folder with images isn\'t showing up, or it doesn\'t show all items. What can I do?</string> <string name="faq_7_title">Uma das minhas pastas não aparece, ou nem todos os seus itens são exibidos. O que posso fazer?</string>
<string name="faq_7_text">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.</string> <string name="faq_7_text">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.</string>
<string name="faq_8_title">What if I want just a few particular folders visible?</string> <string name="faq_8_title">Como posso fazer para exibir apenas certas pastas?</string>
<string name="faq_8_text">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. <string name="faq_8_text">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.</string>
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.</string> <string name="faq_10_title">Posso recortar imagens usando este app?</string>
<string name="faq_10_title">Can I crop images with this app?</string> <string name="faq_10_text">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.</string>
<string name="faq_10_text">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.</string> <string name="faq_11_title">É possível exibir os meus arquivos de mídia em subgrupos ao invés de em uma única grande lista?</string>
<string name="faq_11_title">Can I somehow group media file thumbnails?</string> <string name="faq_11_text">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.</string>
<string name="faq_11_text">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.</string> <string name="faq_12_title">A ordenação por Data da Foto não funciona corretamente. O que posso fazer?</string>
<string name="faq_12_title">Sorting by Date Taken doesn\'t seem to work properly, how can I fix it?</string> <string name="faq_12_text">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.</string>
<string name="faq_12_text">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\".</string> <string name="faq_13_title">Algumas imagens exibem artefatos de exibição, como bandas de cor. Como posso melhorar a qualidade da exibição?</string>
<string name="faq_13_title">I see some color banding on the images. How can I improve the quality?</string> <string name="faq_13_text">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.</string>
<string name="faq_13_text">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.</string> <string name="faq_14_title">Eu ocultei um arquivo/pasta. Como posso desfazer isso?</string>
<string name="faq_14_title">I have hidden a file/folder. How can I unhide it?</string> <string name="faq_14_text">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.</string>
<string name="faq_14_text">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.</string> <string name="faq_15_title">Porque este app gasta tanto espaço?</string>
<string name="faq_15_title">Why does the app take up so much space?</string> <string name="faq_15_text">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.</string>
<string name="faq_15_text">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.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it --> <!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple Gallery Pro: Photo Manager &amp; Editor</string> <string name="app_title">Simple Galeria Pro: Gerenciador de Imagens</string>
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Offline gallery without ads. Organize, edit, recover and protect photos &amp; videos</string> <string name="app_short_description">Galeria offline sem anúncios. Organize, edite, e proteja fotos e vídeos.</string>
<string name="app_long_description"> <string name="app_long_description">
Simple Gallery Pro is a highly customizable offline gallery. Organize &amp; edit your photos, recover deleted files with the recycle bin, protect &amp; hide files and view a huge variety of different photo &amp; video formats including RAW, SVG and much more. 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.
The app contains no ads and unnecessary permissions. As the app doesnt require internet access either, your privacy is protected.
------------------------------------------------- -------------------------------------------------
<b>SIMPLE GALLERY PRO FEATURES</b> <b>SIMPLE GALERIA PRO FUNCIONALIDADES</b>
------------------------------------------------- -------------------------------------------------
• Offline gallery with no ads or popups • Galeria offline sem anúncios ou popups
• Simple gallery photo editor crop, rotate, resize, draw, filters &amp; more • Editor de imagens recorte, rotacione, redimensione, desenhe, adicione filtros, e muito mais
• No internet access needed, giving you more privacy and security • Não requer acesso à internet. Mais privacidade e segurança.
• No unnecessary permissions required • Não pede permissões desnecessárias
• Quickly search images, videos &amp; files • Pesquise por imagens, vídeos e arquivos rapidamente
• Open &amp; view many different photo and video types (RAW, SVG, panoramic etc) • Visualize diversos formatos de arquivos de imagem ou vídeo (RAW, SVG, imagens panorâmicas, etc)
• A variety of intuitive gestures to easily edit &amp; organize files • Use uma variedade de gestos intuitivos para editar e organizar seus arquivos
• Lots of ways to filter, group &amp; sort files • Varias maneiras de filtrar, agrupar, e ordenar seus arquivos
• Customize the appearance of Simple Gallery Pro • Customize a aparência da Simple Galeria Pro
• Available in 32 languages • Disponível em 32 idiomas
• Mark files as favorites for quick access • Marque seus arquivos favoritos para acesso mais rápido
• Protect your photos &amp; videos with a pattern, pin or fingerprint • Proteja suas imagens e vídeos com um padrão, PIN, ou impressão digital
• Use pin, pattern &amp; fingerprint to protect the app launch or specific functions too • Recupere imagens e vídeos que foram excluídos para a lixeira
• Recover deleted photos &amp; videos from the recycle bin • Oculte arquivos para deixar de exibir certas imagens ou vídeos no app.
• Toggle visibility of files to hide photos &amp; videos • Crie um slideshow customizado com os seus arquivos
• Create a customizable slideshow of your files • Exiba informações avançadas sobre seus arquivos (resolução, metadados EXIF, etc)
• View detailed information of your files (resolution, EXIF values etc) • A Simple Galeria Pro tem código aberto!
• Simple Gallery Pro is open source … e muito mais!
… and much much more!
<b>PHOTO GALLERY EDITOR</b> <b>EDITOR DE IMAGENS</b>
Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If youre feeling a little more creative you can add filters and draw on your pictures! 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!
<b>SUPPORT FOR MANY FILE TYPES</b> <b>SUPORTE A VÁRIOS FORMATOS DE ARQUIVO</b>
Unlike some other gallery viewers &amp; 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. 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.
<b>HIGHLY CUSTOMIZABLE GALLERY MANAGER</b> <b>GERENCIADOR DE IMAGENS ALTAMENTE CUSTOMIZÁVEL</b>
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, were also available in 32 languages! 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!
<b>RECOVER DELETED PHOTOS &amp; VIDEOS</b> <b>RECUPERE IMAGENS E VÍDEOS EXCLUÍDOS</b>
Accidentally deleted a precious photo or video? Dont worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos &amp; videos easily. 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.
<b>PROTEJA E OCULTE FOTOS, VÍDEOS E ARQUIVOS</b>
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.
<b>PROTECT &amp; HIDE PHOTOS, VIDEOS &amp; FILES</b> <b>Dê uma olhada nos nossos outros aplicativos Simple:</b>
Using pin, pattern or your devices fingerprint scanner you can protect and hide photos, videos &amp; entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you cant delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
<b>Check out the full suite of Simple Tools here:</b>
https://www.simplemobiletools.com https://www.simplemobiletools.com
<b>Facebook:</b> <b>Facebook:</b>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dados corrigidos com sucesso</string> <string name="dates_fixed_successfully">Dados corrigidos com sucesso</string>
<string name="share_resized">Partilhar foto redimensionada</string> <string name="share_resized">Partilhar foto redimensionada</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrar multimédia</string> <string name="filter_media">Filtrar multimédia</string>
@ -115,10 +116,10 @@
<string name="random_order">Ordem aleatória</string> <string name="random_order">Ordem aleatória</string>
<string name="move_backwards">Mover para trás</string> <string name="move_backwards">Mover para trás</string>
<string name="loop_slideshow">Apresentação em ciclo</string> <string name="loop_slideshow">Apresentação em ciclo</string>
<string name="animation">Animation</string> <string name="animation">Animação</string>
<string name="no_animation">None</string> <string name="no_animation">Nenhuma</string>
<string name="fade">Fade</string> <string name="fade">Desvanecer</string>
<string name="slide">Slide</string> <string name="slide">Deslizar</string>
<string name="slideshow_ended">Apresentação terminada</string> <string name="slideshow_ended">Apresentação terminada</string>
<string name="no_media_for_slideshow">Não foram encontrados ficheiros para a apresentação</string> <string name="no_media_for_slideshow">Não foram encontrados ficheiros para a apresentação</string>
@ -133,11 +134,11 @@
<string name="do_not_group_files">Não agrupar ficheiros</string> <string name="do_not_group_files">Não agrupar ficheiros</string>
<string name="by_folder">Pasta</string> <string name="by_folder">Pasta</string>
<string name="by_last_modified">Última modificação</string> <string name="by_last_modified">Última modificação</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Última modificação (diária)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Última modificação (mensal)</string>
<string name="by_date_taken">Data de obtenção</string> <string name="by_date_taken">Data de obtenção</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Data de obtenção (diária)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Data de obtenção (mensal)</string>
<string name="by_file_type">Tipo de ficheiro</string> <string name="by_file_type">Tipo de ficheiro</string>
<string name="by_extension">Extensão</string> <string name="by_extension">Extensão</string>
<string name="grouping_and_sorting">Tenha em atenção de que agrupamento e ordenação são campos independentes</string> <string name="grouping_and_sorting">Tenha em atenção de que agrupamento e ordenação são campos independentes</string>
@ -238,7 +239,7 @@
<string name="app_long_description"> <string name="app_long_description">
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. 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.
------------------------------------------------- -------------------------------------------------
<b>SIMPLE GALLERY PRO FUNCIONALIDADES</b> <b>SIMPLE GALLERY PRO FUNCIONALIDADES</b>
@ -279,7 +280,7 @@
<b>PROTECT &amp; HIDE PHOTOS, VIDEOS &amp; FILES</b> <b>PROTECT &amp; HIDE PHOTOS, VIDEOS &amp; FILES</b>
Using pin, pattern or your devices fingerprint scanner you can protect and hide photos, videos &amp; entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you cant delete a file without a fingerprint scan, helping to protect your files from accidental deletion. Using pin, pattern or your devices fingerprint scanner you can protect and hide photos, videos &amp; entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you cant delete a file without a fingerprint scan, helping to protect your files from accidental deletion.
<b>Check out the full suite of Simple Tools here:</b> <b>Consulte todas as aplicações Simple Tools aqui:</b>
https://www.simplemobiletools.com https://www.simplemobiletools.com
<b>Facebook:</b> <b>Facebook:</b>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Даты исправлены</string> <string name="dates_fixed_successfully">Даты исправлены</string>
<string name="share_resized">Поделиться изменённой версией</string> <string name="share_resized">Поделиться изменённой версией</string>
<string name="upgraded_from_free">Привет,\n\nпохоже, что вы обновились со старого бесплатного приложения. Теперь вы можете удалить старую версию, которая содержит кнопку \"Обновить до Pro\" в верхней части настроек приложения.\n\nБудет очищена корзина, сняты отметки избранного, а также вам придётся сбросить настройки приложения.\n\nСпасибо!</string> <string name="upgraded_from_free">Привет,\n\nпохоже, что вы обновились со старого бесплатного приложения. Теперь вы можете удалить старую версию, которая содержит кнопку \"Обновить до Pro\" в верхней части настроек приложения.\n\nБудет очищена корзина, сняты отметки избранного, а также вам придётся сбросить настройки приложения.\n\nСпасибо!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Фильтр медиа</string> <string name="filter_media">Фильтр медиа</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dátumy boli úspešne opravené</string> <string name="dates_fixed_successfully">Dátumy boli úspešne opravené</string>
<string name="share_resized">Zdieľať verziu so zmenenou veľkosťou</string> <string name="share_resized">Zdieľať verziu so zmenenou veľkosťou</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Prepnúť na vyhľadávanie súborov vo všetkých viditeľných priečinkoch</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filter médií</string> <string name="filter_media">Filter médií</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datumi uspešno popravljeni</string> <string name="dates_fixed_successfully">Datumi uspešno popravljeni</string>
<string name="share_resized">Deli spremenjeno verzijo</string> <string name="share_resized">Deli spremenjeno verzijo</string>
<string name="upgraded_from_free">Ž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!</string> <string name="upgraded_from_free">Ž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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtriranje datotek</string> <string name="filter_media">Filtriranje datotek</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Датуми успешно исправљени</string> <string name="dates_fixed_successfully">Датуми успешно исправљени</string>
<string name="share_resized">Подели верзију са промењеним димензијама</string> <string name="share_resized">Подели верзију са промењеним димензијама</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Филтрирај медију</string> <string name="filter_media">Филтрирај медију</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Datumen har korrigerats</string> <string name="dates_fixed_successfully">Datumen har korrigerats</string>
<string name="share_resized">Dela en version med ändrad storlek</string> <string name="share_resized">Dela en version med ändrad storlek</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filtrera media</string> <string name="filter_media">Filtrera media</string>
@ -116,9 +117,9 @@
<string name="move_backwards">Spela upp i omvänd ordning</string> <string name="move_backwards">Spela upp i omvänd ordning</string>
<string name="loop_slideshow">Spela upp i en slinga</string> <string name="loop_slideshow">Spela upp i en slinga</string>
<string name="animation">Animation</string> <string name="animation">Animation</string>
<string name="no_animation">None</string> <string name="no_animation">Ingen</string>
<string name="fade">Fade</string> <string name="fade">Tona</string>
<string name="slide">Slide</string> <string name="slide">Glid</string>
<string name="slideshow_ended">Bildspelet har avslutats</string> <string name="slideshow_ended">Bildspelet har avslutats</string>
<string name="no_media_for_slideshow">Ingen media hittades för bildspelet</string> <string name="no_media_for_slideshow">Ingen media hittades för bildspelet</string>
@ -133,14 +134,14 @@
<string name="do_not_group_files">Gruppera inte filer</string> <string name="do_not_group_files">Gruppera inte filer</string>
<string name="by_folder">Mapp</string> <string name="by_folder">Mapp</string>
<string name="by_last_modified">Senast ändrad</string> <string name="by_last_modified">Senast ändrad</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">Senast ändrad (dag)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">Senast ändrad (månad)</string>
<string name="by_date_taken">Fotodatum</string> <string name="by_date_taken">Fotodatum</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">Fotodatum (dag)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">Fotodatum (månad)</string>
<string name="by_file_type">Filtyp</string> <string name="by_file_type">Filtyp</string>
<string name="by_extension">Filnamnstillägg</string> <string name="by_extension">Filnamnstillägg</string>
<string name="grouping_and_sorting">Please note that grouping and sorting are 2 independent fields</string> <string name="grouping_and_sorting">Observera att gruppering och sortering är två oberoende funktioner</string>
<!-- Widgets --> <!-- Widgets -->
<string name="folder_on_widget">Mapp som visas i widgeten:</string> <string name="folder_on_widget">Mapp som visas i widgeten:</string>

View file

@ -6,4 +6,5 @@
<dimen name="selection_check_size">38dp</dimen> <dimen name="selection_check_size">38dp</dimen>
<dimen name="tmb_shadow_height">70dp</dimen> <dimen name="tmb_shadow_height">70dp</dimen>
<dimen name="instant_change_bar_width">100dp</dimen> <dimen name="instant_change_bar_width">100dp</dimen>
<dimen name="lock_padding">80dp</dimen>
</resources> </resources>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Tarihler başarıyla düzeltildi</string> <string name="dates_fixed_successfully">Tarihler başarıyla düzeltildi</string>
<string name="share_resized">Yeniden boyutlandırılmış sürümü paylaş</string> <string name="share_resized">Yeniden boyutlandırılmış sürümü paylaş</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Medyayı filtrele</string> <string name="filter_media">Medyayı filtrele</string>
@ -227,59 +228,59 @@
<string name="faq_13_text">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.</string> <string name="faq_13_text">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.</string>
<string name="faq_14_title">Bir dosya/klasör gizledim. Nasıl gösterebilirim?</string> <string name="faq_14_title">Bir dosya/klasör gizledim. Nasıl gösterebilirim?</string>
<string name="faq_14_text">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.</string> <string name="faq_14_text">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.</string>
<string name="faq_15_title">Why does the app take up so much space?</string> <string name="faq_15_title">Uygulama neden bu kadar yer kaplıyor?</string>
<string name="faq_15_text">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.</string> <string name="faq_15_text">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.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it --> <!-- App title has to have less than 50 characters. If you cannot squeeze it, just remove a part of it -->
<string name="app_title">Simple Gallery Pro: Photo Manager &amp; Editor</string> <string name="app_title">Basit Galeri Pro: Fotoğraf Yönetici &amp; Düzenleyici</string>
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Offline gallery without ads. Organize, edit, recover and protect photos &amp; videos</string> <string name="app_short_description">Reklamsız çevrimdışı galeri. Fotoğraf &amp; videolarınızı yönetin ve düzenleyin</string>
<string name="app_long_description"> <string name="app_long_description">
Simple Gallery Pro is a highly customizable offline gallery. Organize &amp; edit your photos, recover deleted files with the recycle bin, protect &amp; hide files and view a huge variety of different photo &amp; 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 doesnt 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.
------------------------------------------------- -------------------------------------------------
<b>SIMPLE GALLERY PRO FEATURES</b> <b>BASİT GALERİ PRO ÖZELLİKLER</b>
------------------------------------------------- -------------------------------------------------
Offline gallery with no ads or popups Reklamsız veya açılır penceresiz, çevrimdışı galeri
Simple gallery photo editor crop, rotate, resize, draw, filters &amp; more Basit galeri fotoğraf editörü - kırpma, döndürme, yeniden boyutlandırma, çizim, filtreler ve daha fazlası
No internet access needed, giving you more privacy and security İnternet erişimi gerekmez, size daha fazla gizlilik ve güvenlik sunar
No unnecessary permissions required Gereksiz izinler gerekmez
Quickly search images, videos &amp; files Resimleri, videoları ve dosyaları hızlıca arama
Open &amp; view many different photo and video types (RAW, SVG, panoramic etc) Birçok farklı fotoğraf ve video türünü (RAW, SVG, panoramik vb.) açma ve görüntüleme
A variety of intuitive gestures to easily edit &amp; organize files Dosyaları kolayca düzenlemek ve organize etmek için çeşitli sezgisel hareketler
Lots of ways to filter, group &amp; sort files Dosyaları filtrelemenin, gruplandırmanın ve sıralamanın birçok yolu
Customize the appearance of Simple Gallery Pro Basit Galeri Pro\'nun görünümünü özelleştirme
Available in 32 languages 32 dilde mevcut
Mark files as favorites for quick access Hızlı erişim için dosyaları sık kullanılan olarak işaretleme
Protect your photos &amp; videos with a pattern, pin or fingerprint Fotoğraflarınızı ve videolarınızı desen, pin veya parmak izi ile koruma
• Use pin, pattern &amp; fingerprint to protect the app launch or specific functions too • Uygulama başlatılmasını veya belirli işlevleri de korumak için pin, desen ve parmak izi kullanma
Recover deleted photos &amp; videos from the recycle bin Silinen fotoğrafları ve videoları geri dönüşüm kutusundan kurtarma
Toggle visibility of files to hide photos &amp; videos Fotoğrafları ve videoları gizlemek için dosyaların görünürlüğünü değiştirme
Create a customizable slideshow of your files Dosyalarınızın özelleştirilebilir bir slayt gösterisini oluşturma
View detailed information of your files (resolution, EXIF values etc) Dosyalarınızın ayrıntılı bilgilerini (çözünürlük, EXIF değerleri vb.) görüntüleme
Simple Gallery Pro is open source Basit Galeri Pro açık kaynak kodludur
and much much more! ve çok daha fazlası!
<b>PHOTO GALLERY EDITOR</b> <b>FOTOĞRAF GALERİSİ EDİTÖRÜ</b>
Simple Gallery Pro makes it easy to edit your pictures on the fly. Crop, flip, rotate and resize your pictures. If youre feeling a little more creative you can add filters and draw on your pictures! 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!
<b>SUPPORT FOR MANY FILE TYPES</b> <b>BİRÇOK DOSYA TÜRÜ İÇİN DESTEK</b>
Unlike some other gallery viewers &amp; 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. 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.
<b>HIGHLY CUSTOMIZABLE GALLERY MANAGER</b> <b>SON DERECE ÖZELLEŞTİRİLEBİLİR GALERİ YÖNETİCİSİ</b>
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, were also available in 32 languages! 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!
<b>RECOVER DELETED PHOTOS &amp; VIDEOS</b> <b>SİLİNEN FOTOĞRAFLARI VE VİDEOLARI KURTARIN</b>
Accidentally deleted a precious photo or video? Dont worry! Simple Gallery Pro features a handy recycle bin where you can recover deleted photos &amp; videos easily. 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.
<b>PROTECT &amp; HIDE PHOTOS, VIDEOS &amp; FILES</b> <b>FOTOĞRAFLARI, VİDEOLARI VE DOSYALARI KORUYUN VE GİZLEYİN</b>
Using pin, pattern or your devices fingerprint scanner you can protect and hide photos, videos &amp; entire albums. You can protect the app itself or place locks on specific functions of the app. For example, you cant delete a file without a fingerprint scan, helping to protect your files from accidental deletion. 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.
<b>Check out the full suite of Simple Tools here:</b> <b>Tüm Basit Araçlar paketini buradan inceleyin:</b>
https://www.simplemobiletools.com https://www.simplemobiletools.com
<b>Facebook:</b> <b>Facebook:</b>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Дати успішно виправлені</string> <string name="dates_fixed_successfully">Дати успішно виправлені</string>
<string name="share_resized">Поділитися зображенням іншого розміру</string> <string name="share_resized">Поділитися зображенням іншого розміру</string>
<string name="upgraded_from_free">Агов,\n\nздається, ви оновились зі старого безкоштовного додатка. Тепер ви можете видалити стару версію, у якій є кнопка \"Перейти на Pro\" вгорі налаштувань додатка.\n\nВи втратите лише елементи з Кошика, позначки улюблених елементів, а також потрібно буде скинути ваші налаштування додатка.\n\nДякую!</string> <string name="upgraded_from_free">Агов,\n\nздається, ви оновились зі старого безкоштовного додатка. Тепер ви можете видалити стару версію, у якій є кнопка \"Перейти на Pro\" вгорі налаштувань додатка.\n\nВи втратите лише елементи з Кошика, позначки улюблених елементів, а також потрібно буде скинути ваші налаштування додатка.\n\nДякую!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Фільтр мультимедійних файлів</string> <string name="filter_media">Фільтр мультимедійних файлів</string>
@ -115,10 +116,10 @@
<string name="random_order">Випадковий порядок</string> <string name="random_order">Випадковий порядок</string>
<string name="move_backwards">Рухатися назад</string> <string name="move_backwards">Рухатися назад</string>
<string name="loop_slideshow">Зациклити показ слайдів</string> <string name="loop_slideshow">Зациклити показ слайдів</string>
<string name="animation">Animation</string> <string name="animation">Анімація</string>
<string name="no_animation">None</string> <string name="no_animation">Немає</string>
<string name="fade">Fade</string> <string name="fade">Згасання</string>
<string name="slide">Slide</string> <string name="slide">Зміщення</string>
<string name="slideshow_ended">Слайдшоу закінчено</string> <string name="slideshow_ended">Слайдшоу закінчено</string>
<string name="no_media_for_slideshow">Не знайдено медіафайлів для показу у слайдшоу</string> <string name="no_media_for_slideshow">Не знайдено медіафайлів для показу у слайдшоу</string>
@ -133,11 +134,11 @@
<string name="do_not_group_files">Не групувати файли</string> <string name="do_not_group_files">Не групувати файли</string>
<string name="by_folder">текою</string> <string name="by_folder">текою</string>
<string name="by_last_modified">останньою зміною</string> <string name="by_last_modified">останньою зміною</string>
<string name="by_last_modified_daily">Last modified (daily)</string> <string name="by_last_modified_daily">останньою зміною (по днях)</string>
<string name="by_last_modified_monthly">Last modified (monthly)</string> <string name="by_last_modified_monthly">останньою зміною (по місяцях)</string>
<string name="by_date_taken">датою зйомки</string> <string name="by_date_taken">датою зйомки</string>
<string name="by_date_taken_daily">Date taken (daily)</string> <string name="by_date_taken_daily">датою зйомки (по днях)</string>
<string name="by_date_taken_monthly">Date taken (monthly)</string> <string name="by_date_taken_monthly">датою зйомки (по місяцях)</string>
<string name="by_file_type">типом файлу</string> <string name="by_file_type">типом файлу</string>
<string name="by_extension">розширенням</string> <string name="by_extension">розширенням</string>
<string name="grouping_and_sorting">Зверніть увагу, що групування і сортування - це два окремих поля</string> <string name="grouping_and_sorting">Зверніть увагу, що групування і сортування - це два окремих поля</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">日期修复成功</string> <string name="dates_fixed_successfully">日期修复成功</string>
<string name="share_resized">调整图像尺寸并分享</string> <string name="share_resized">调整图像尺寸并分享</string>
<string name="upgraded_from_free">嘿,\n\n看起来您是从旧的免费版应用程序升级的。您现在可以卸载旧版本在该版本应用的设置菜单顶部有一个“升级到专业版”按钮。\n\n此操作将会删除回收站项目并取消收藏已收藏的项目你的应用设置也将会重置。\n\n谢谢</string> <string name="upgraded_from_free">嘿,\n\n看起来您是从旧的免费版应用程序升级的。您现在可以卸载旧版本在该版本应用的设置菜单顶部有一个“升级到专业版”按钮。\n\n此操作将会删除回收站项目并取消收藏已收藏的项目你的应用设置也将会重置。\n\n谢谢</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">要显示的媒体文件</string> <string name="filter_media">要显示的媒体文件</string>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">日期修復成功</string> <string name="dates_fixed_successfully">日期修復成功</string>
<string name="share_resized">分享調整大小的版本</string> <string name="share_resized">分享調整大小的版本</string>
<string name="upgraded_from_free">嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除我的最愛項目會被解除標記以及也會重置你的應用程式設定。\n\n感謝!</string> <string name="upgraded_from_free">嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除我的最愛項目會被解除標記以及也會重置你的應用程式設定。\n\n感謝!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">篩選媒體檔案</string> <string name="filter_media">篩選媒體檔案</string>

View file

@ -28,11 +28,12 @@
<string name="force_portrait">強制直向</string> <string name="force_portrait">強制直向</string>
<string name="force_landscape">強制橫向</string> <string name="force_landscape">強制橫向</string>
<string name="use_default_orientation">使用預設方向</string> <string name="use_default_orientation">使用預設方向</string>
<string name="fix_date_taken">修復拍日期數值</string> <string name="fix_date_taken">修復拍日期數值</string>
<string name="fixing">修復中…</string> <string name="fixing">修復中…</string>
<string name="dates_fixed_successfully">日期修復成功</string> <string name="dates_fixed_successfully">日期修復成功</string>
<string name="share_resized">分享調整大小的版本</string> <string name="share_resized">分享調整大小的版本</string>
<string name="upgraded_from_free">嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除我的最愛項目會被解除標記以及也會重置你的應用程式設定。\n\n感謝!</string> <string name="upgraded_from_free">嘿\n\n你似乎從舊版免費應用程式升級了。現在你能解除安裝舊版了在應用程式設定的頂端有個\'升級至專業版\'按鈕。\n\n將只有回收桶項目會被刪除我的最愛項目會被解除標記以及也會重置你的應用程式設定。\n\n感謝!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">篩選媒體檔案</string> <string name="filter_media">篩選媒體檔案</string>
@ -115,10 +116,10 @@
<string name="random_order">隨機順序</string> <string name="random_order">隨機順序</string>
<string name="move_backwards">反向播放</string> <string name="move_backwards">反向播放</string>
<string name="loop_slideshow">投影片循環</string> <string name="loop_slideshow">投影片循環</string>
<string name="animation">Animation</string> <string name="animation">動畫</string>
<string name="no_animation">None</string> <string name="no_animation"></string>
<string name="fade">Fade</string> <string name="fade">漸變</string>
<string name="slide">Slide</string> <string name="slide">滑動</string>
<string name="slideshow_ended">投影片結束</string> <string name="slideshow_ended">投影片結束</string>
<string name="no_media_for_slideshow">找不到投影片的媒體檔案</string> <string name="no_media_for_slideshow">找不到投影片的媒體檔案</string>
@ -220,9 +221,9 @@
<string name="faq_10_title">我可以用這程式裁減圖片嗎?</string> <string name="faq_10_title">我可以用這程式裁減圖片嗎?</string>
<string name="faq_10_text">是的,你能夠在編輯器內拉動圖片角落來裁剪圖片。要進入編輯器,你可以長按圖片縮圖然後選擇[編輯],或是在全螢幕檢視下選擇[編輯]。</string> <string name="faq_10_text">是的,你能夠在編輯器內拉動圖片角落來裁剪圖片。要進入編輯器,你可以長按圖片縮圖然後選擇[編輯],或是在全螢幕檢視下選擇[編輯]。</string>
<string name="faq_11_title">我可以歸類媒體檔案的縮圖嗎?</string> <string name="faq_11_title">我可以歸類媒體檔案的縮圖嗎?</string>
<string name="faq_11_text">當然,只要在縮圖瀏覽中使用[歸類]選單項目就可以了。你能依多種條件歸類檔案,包含拍日期。如果你使用了[資料夾內容全部顯示]功能,你還能以資料夾來歸類。</string> <string name="faq_11_text">當然,只要在縮圖瀏覽中使用[歸類]選單項目就可以了。你能依多種條件歸類檔案,包含拍日期。如果你使用了[資料夾內容全部顯示]功能,你還能以資料夾來歸類。</string>
<string name="faq_12_title">依拍日期排序似乎沒正確運作,我該如何修復?</string> <string name="faq_12_title">依拍日期排序似乎沒正確運作,我該如何修復?</string>
<string name="faq_12_text">那很可能是由於檔案從某處複製過來所造成的。你可以選擇檔案縮圖,然後選擇\"修復拍日期數值\"來進行修復。</string> <string name="faq_12_text">那很可能是由於檔案從某處複製過來所造成的。你可以選擇檔案縮圖,然後選擇\"修復拍日期數值\"來進行修復。</string>
<string name="faq_13_title">我在圖片上看到一些色彩條紋。我如何提升品質?</string> <string name="faq_13_title">我在圖片上看到一些色彩條紋。我如何提升品質?</string>
<string name="faq_13_text">目前顯示圖片的處理方法,在大部分情況下都能正常運行。但如果你想要更好的圖片品質,你可以在程式設定中[可深度縮放的圖片]部分,啟用[以最高品質顯示圖片]。</string> <string name="faq_13_text">目前顯示圖片的處理方法,在大部分情況下都能正常運行。但如果你想要更好的圖片品質,你可以在程式設定中[可深度縮放的圖片]部分,啟用[以最高品質顯示圖片]。</string>
<string name="faq_14_title">我隱藏了一個檔案/資料夾。我如何取消隱藏?</string> <string name="faq_14_title">我隱藏了一個檔案/資料夾。我如何取消隱藏?</string>

View file

@ -22,4 +22,5 @@
<dimen name="default_status_action_height">86dp</dimen> <dimen name="default_status_action_height">86dp</dimen>
<dimen name="widget_initial_size">110dp</dimen> <dimen name="widget_initial_size">110dp</dimen>
<dimen name="full_brush_size">40dp</dimen> <dimen name="full_brush_size">40dp</dimen>
<dimen name="lock_padding">40dp</dimen>
</resources> </resources>

View file

@ -33,6 +33,7 @@
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<string name="share_resized">Share a resized version</string> <string name="share_resized">Share a resized version</string>
<string name="upgraded_from_free">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!</string> <string name="upgraded_from_free">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!</string>
<string name="switch_to_file_search">Switch to file search across all visible folders</string>
<!-- Filter --> <!-- Filter -->
<string name="filter_media">Filter media</string> <string name="filter_media">Filter media</string>

View file

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.3.40' ext.kotlin_version = '1.3.41'
repositories { repositories {
google() google()