Merge pull request #42 from SimpleMobileTools/master

upd
This commit is contained in:
solokot 2018-12-19 22:49:28 +03:00 committed by GitHub
commit 9e17022f39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
74 changed files with 1627 additions and 211 deletions

View file

@ -1,6 +1,21 @@
Changelog Changelog
========== ==========
Version 6.1.1 *(2018-12-18)*
----------------------------
* Fixing some crashes
Version 6.1.0 *(2018-12-17)*
----------------------------
* Added an initial widget implementation for creating homescreen folder shortcuts
* Added optional grouping of direct subfolders, as a check at the "Change view type" dialog
* Added an option to set custom crop aspect ratio at the editor
* Save exif data at edited files on Android 7+
* Handle only Mass Storage USB devices, ignore the rest
* Many other smaller UX/stability/performance improvements
Version 6.0.4 *(2018-12-04)* Version 6.0.4 *(2018-12-04)*
---------------------------- ----------------------------

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 212 versionCode 214
versionName "6.0.4" versionName "6.1.1"
multiDexEnabled true multiDexEnabled true
setProperty("archivesBaseName", "gallery") setProperty("archivesBaseName", "gallery")
} }
@ -57,15 +57,15 @@ android {
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:5.5.4' implementation 'com.simplemobiletools:commons:5.5.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.0' implementation 'androidx.multidex:multidex:2.0.0'
implementation 'it.sephiroth.android.exif:library:1.0.1' implementation 'it.sephiroth.android.exif:library:1.0.1'
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.15' implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2' implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha2'
implementation 'com.google.android.exoplayer:exoplayer-core:2.9.2' implementation 'com.google.android.exoplayer:exoplayer-core:2.9.2'
implementation 'com.google.vr:sdk-panowidget:1.170.0' implementation 'com.google.vr:sdk-panowidget:1.180.0'
implementation 'com.google.vr:sdk-videowidget:1.170.0' implementation 'com.google.vr:sdk-videowidget:1.180.0'
implementation 'org.apache.sanselan:sanselan:0.97-incubator' implementation 'org.apache.sanselan:sanselan:0.97-incubator'
implementation 'info.androidhive:imagefilters:1.0.7' implementation 'info.androidhive:imagefilters:1.0.7'
implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.squareup.picasso:picasso:2.71828'
@ -77,8 +77,9 @@ dependencies {
annotationProcessor 'androidx.room:room-compiler:2.0.0' annotationProcessor 'androidx.room:room-compiler:2.0.0'
//implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' //implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0'
implementation 'com.github.tibbi:subsampling-scale-image-view:v3.10.1-fork' //implementation 'com.github.tibbi:subsampling-scale-image-view:v3.10.1-fork'
implementation 'com.github.tibbi:subsampling-scale-image-view:fcb724fb0a'
// implementation 'com.github.chrisbanes:PhotoView:2.1.4' // implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.github.tibbi:PhotoView:2.2.1-fork' implementation 'com.github.tibbi:PhotoView:2.3.0-fork'
} }

View file

@ -215,6 +215,15 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".activities.WidgetConfigureActivity"
android:screenOrientation="portrait"
android:theme="@style/MyWidgetConfigTheme">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider" android:authorities="${applicationId}.provider"
@ -233,6 +242,18 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
android:name=".helpers.MyWidgetProvider"
android:icon="@drawable/img_widget_preview">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info"/>
</receiver>
<activity-alias <activity-alias
android:name=".activities.SplashActivity.Red" android:name=".activities.SplashActivity.Red"
android:enabled="false" android:enabled="false"

View file

@ -1,12 +1,15 @@
package com.simplemobiletools.gallery.pro.activities package com.simplemobiletools.gallery.pro.activities
import android.annotation.TargetApi
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat import android.graphics.Bitmap.CompressFormat
import android.graphics.Color import android.graphics.Color
import android.graphics.Point import android.graphics.Point
import android.media.ExifInterface
import android.net.Uri import android.net.Uri
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.view.Menu import android.view.Menu
@ -24,6 +27,7 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.OTG_PATH import com.simplemobiletools.commons.helpers.OTG_PATH
import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE
import com.simplemobiletools.commons.helpers.REAL_FILE_PATH import com.simplemobiletools.commons.helpers.REAL_FILE_PATH
import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.FiltersAdapter import com.simplemobiletools.gallery.pro.adapters.FiltersAdapter
@ -576,6 +580,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
} }
} }
@TargetApi(Build.VERSION_CODES.N)
private fun saveBitmap(file: File, bitmap: Bitmap, out: OutputStream, showSavingToast: Boolean) { private fun saveBitmap(file: File, bitmap: Bitmap, out: OutputStream, showSavingToast: Boolean) {
if (showSavingToast) { if (showSavingToast) {
toast(R.string.saving) toast(R.string.saving)
@ -587,6 +592,20 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener
} else { } else {
bitmap.compress(file.absolutePath.getCompressionFormat(), 90, out) bitmap.compress(file.absolutePath.getCompressionFormat(), 90, out)
} }
var inputStream: InputStream? = null
try {
if (isNougatPlus()) {
inputStream = contentResolver.openInputStream(uri)
val oldExif = ExifInterface(inputStream)
val newExif = ExifInterface(file.absolutePath)
oldExif.copyTo(newExif, false)
}
} catch (e: Exception) {
} finally {
inputStream?.close()
}
setResult(Activity.RESULT_OK, intent) setResult(Activity.RESULT_OK, intent)
scanFinalPath(file.absolutePath) scanFinalPath(file.absolutePath)
out.close() out.close()

View file

@ -17,13 +17,12 @@ import android.widget.Toast
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuItemCompat 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.CreateNewFolderDialog import com.simplemobiletools.commons.dialogs.CreateNewFolderDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.FileDirItem import com.simplemobiletools.commons.models.FileDirItem
import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.commons.models.Release import com.simplemobiletools.commons.models.Release
import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.commons.views.MyRecyclerView
@ -32,6 +31,7 @@ import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.DirectoryAdapter import com.simplemobiletools.gallery.pro.adapters.DirectoryAdapter
import com.simplemobiletools.gallery.pro.databases.GalleryDatabase import com.simplemobiletools.gallery.pro.databases.GalleryDatabase
import com.simplemobiletools.gallery.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.gallery.pro.dialogs.ChangeSortingDialog
import com.simplemobiletools.gallery.pro.dialogs.ChangeViewTypeDialog
import com.simplemobiletools.gallery.pro.dialogs.FilterMediaDialog import com.simplemobiletools.gallery.pro.dialogs.FilterMediaDialog
import com.simplemobiletools.gallery.pro.extensions.* import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.* import com.simplemobiletools.gallery.pro.helpers.*
@ -67,6 +67,8 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private var mIsSearchOpen = 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 mOpenedSubfolders = arrayListOf("") // used at "Group direct subfolders" for navigating Up with the back button
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
@ -126,10 +128,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
NewAppDialog(this, NEW_APP_PACKAGE, "Simple Clock") NewAppDialog(this, NEW_APP_PACKAGE, "Simple Clock")
}*/ }*/
if (!config.wasOTGHandled && hasPermission(PERMISSION_WRITE_STORAGE)) {
checkOTGInclusion()
}
if (!config.wereFavoritesPinned) { if (!config.wereFavoritesPinned) {
config.addPinnedFolders(hashSetOf(FAVORITES)) config.addPinnedFolders(hashSetOf(FAVORITES))
config.wereFavoritesPinned = true config.wereFavoritesPinned = true
@ -147,6 +145,8 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
config.filterMedia += TYPE_SVGS config.filterMedia += TYPE_SVGS
} }
} }
updateWidgets()
} }
override fun onStart() { override fun onStart() {
@ -246,6 +246,20 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
} }
override fun onBackPressed() {
if (config.groupDirectSubfolders) {
if (mCurrentPathPrefix.isEmpty()) {
super.onBackPressed()
} else {
mOpenedSubfolders.removeAt(mOpenedSubfolders.size - 1)
mCurrentPathPrefix = mOpenedSubfolders.last()
setupAdapter(mDirs)
}
} else {
super.onBackPressed()
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (mIsThirdPartyIntent) { if (mIsThirdPartyIntent) {
menuInflater.inflate(R.menu.menu_main_intent, menu) menuInflater.inflate(R.menu.menu_main_intent, menu)
@ -318,7 +332,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
override fun onQueryTextChange(newText: String): Boolean { override fun onQueryTextChange(newText: String): Boolean {
if (mIsSearchOpen) { if (mIsSearchOpen) {
searchQueryChanged(newText) setupAdapter(mDirs, newText)
} }
return true return true
} }
@ -337,25 +351,13 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (mIsSearchOpen) { if (mIsSearchOpen) {
mIsSearchOpen = false mIsSearchOpen = false
directories_refresh_layout.isEnabled = config.enablePullToRefresh directories_refresh_layout.isEnabled = config.enablePullToRefresh
searchQueryChanged("") setupAdapter(mDirs, "")
} }
return true return true
} }
}) })
} }
private fun searchQueryChanged(text: String) {
Thread {
val filtered = getUniqueSortedDirs(mDirs).filter { it.name.contains(text, true) } as ArrayList
filtered.sortBy { !it.name.startsWith(text, true) }
runOnUiThread {
getRecyclerAdapter()?.updateDirs(filtered)
measureRecyclerViewContent(filtered)
}
}.start()
}
private fun removeTempFolder() { private fun removeTempFolder() {
if (config.tempFolderPath.isNotEmpty()) { if (config.tempFolderPath.isNotEmpty()) {
val newFolder = File(config.tempFolderPath) val newFolder = File(config.tempFolderPath)
@ -373,8 +375,10 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
Thread { Thread {
if (hasOTGConnected()) { if (hasOTGConnected()) {
runOnUiThread { runOnUiThread {
handleOTGPermission { ConfirmationDialog(this, getString(R.string.usb_detected), positive = R.string.ok, negative = 0) {
config.addIncludedFolder(OTG_PATH) handleOTGPermission {
config.addIncludedFolder(OTG_PATH)
}
} }
} }
config.wasOTGHandled = true config.wasOTGHandled = true
@ -385,6 +389,10 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private fun tryLoadGallery() { private fun tryLoadGallery() {
handlePermission(PERMISSION_WRITE_STORAGE) { handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) { if (it) {
if (!config.wasOTGHandled && hasPermission(PERMISSION_WRITE_STORAGE)) {
checkOTGInclusion()
}
if (config.showAll) { if (config.showAll) {
showAllMedia() showAllMedia()
} else { } else {
@ -451,17 +459,11 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
private fun changeViewType() { private fun changeViewType() {
val items = arrayListOf( ChangeViewTypeDialog(this) {
RadioItem(VIEW_TYPE_GRID, getString(R.string.grid)),
RadioItem(VIEW_TYPE_LIST, getString(R.string.list)))
RadioGroupDialog(this, items, config.viewTypeFolders) {
config.viewTypeFolders = it as Int
invalidateOptionsMenu() invalidateOptionsMenu()
setupLayoutManager() setupLayoutManager()
val dirs = getCurrentlyDisplayedDirs()
directories_grid.adapter = null directories_grid.adapter = null
setupAdapter(dirs) setupAdapter(mDirs)
} }
} }
@ -768,10 +770,10 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
private fun gotDirectories(newDirs: ArrayList<Directory>) { private fun gotDirectories(newDirs: ArrayList<Directory>) {
// if hidden item showing is disabled but all Favorite items are hidden, hide the Favorites folder
mIsGettingDirs = false mIsGettingDirs = false
mShouldStopFetching = false mShouldStopFetching = false
// if hidden item showing is disabled but all Favorite items are hidden, hide the Favorites folder
if (!config.shouldShowHidden) { if (!config.shouldShowHidden) {
val favoritesFolder = newDirs.firstOrNull { it.areFavorites() } val favoritesFolder = newDirs.firstOrNull { it.areFavorites() }
if (favoritesFolder != null && favoritesFolder.tmb.getFilenameFromPath().startsWith('.')) { if (favoritesFolder != null && favoritesFolder.tmb.getFilenameFromPath().startsWith('.')) {
@ -821,7 +823,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
// we are looping through the already displayed folders looking for changes, do not do anything if nothing changed // we are looping through the already displayed folders looking for changes, do not do anything if nothing changed
if (directory == newDir) { if (directory.copy(subfoldersCount = 0, subfoldersMediaCount = 0) == newDir) {
continue continue
} }
@ -835,7 +837,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
types = newDir.types types = newDir.types
} }
showSortedDirs(dirs) setupAdapter(dirs)
// update directories and media files in the local db, delete invalid items // update directories and media files in the local db, delete invalid items
updateDBDirectory(directory, mDirectoryDao) updateDBDirectory(directory, mDirectoryDao)
@ -862,7 +864,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
mDirectoryDao.deleteDirPath(it.path) mDirectoryDao.deleteDirPath(it.path)
} }
dirs.removeAll(dirsToRemove) dirs.removeAll(dirsToRemove)
showSortedDirs(dirs) setupAdapter(dirs)
} }
val foldersToScan = mediaFetcher.getFoldersToScan() val foldersToScan = mediaFetcher.getFoldersToScan()
@ -899,7 +901,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
val newDir = createDirectoryFromMedia(folder, newMedia, albumCovers, hiddenString, includedFolders, isSortingAscending) val newDir = createDirectoryFromMedia(folder, newMedia, albumCovers, hiddenString, includedFolders, isSortingAscending)
dirs.add(newDir) dirs.add(newDir)
showSortedDirs(dirs) setupAdapter(dirs)
mDirectoryDao.insert(newDir) mDirectoryDao.insert(newDir)
if (folder != RECYCLE_BIN) { if (folder != RECYCLE_BIN) {
mMediumDao.insertAll(newMedia) mMediumDao.insertAll(newMedia)
@ -936,18 +938,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
directories_grid.beVisibleIf(directories_empty_text_label.isGone()) directories_grid.beVisibleIf(directories_empty_text_label.isGone())
} }
private fun showSortedDirs(dirs: ArrayList<Directory>) {
val updatedDirs = getUniqueSortedDirs(dirs).toMutableList() as ArrayList
runOnUiThread {
(directories_grid.adapter as? DirectoryAdapter)?.updateDirs(updatedDirs)
}
}
private fun getUniqueSortedDirs(dirs: ArrayList<Directory>): ArrayList<Directory> {
val distinctDirs = dirs.distinctBy { it.path.getDistinctPath() } as ArrayList<Directory>
return getSortedDirectories(distinctDirs)
}
private fun createDirectoryFromMedia(path: String, curMedia: ArrayList<Medium>, albumCovers: ArrayList<AlbumCover>, hiddenString: String, private fun createDirectoryFromMedia(path: String, curMedia: ArrayList<Medium>, albumCovers: ArrayList<AlbumCover>, hiddenString: String,
includedFolders: MutableSet<String>, isSortingAscending: Boolean): Directory { includedFolders: MutableSet<String>, isSortingAscending: Boolean): Directory {
var thumbnail = curMedia.firstOrNull { getDoesFilePathExist(it.path) }?.path ?: "" var thumbnail = curMedia.firstOrNull { getDoesFilePathExist(it.path) }?.path ?: ""
@ -961,43 +951,59 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
} }
} }
val mediaTypes = curMedia.getDirMediaTypes()
val dirName = when (path) {
FAVORITES -> getString(R.string.favorites)
RECYCLE_BIN -> getString(R.string.recycle_bin)
else -> checkAppendingHidden(path, hiddenString, includedFolders)
}
val firstItem = curMedia.first() val firstItem = curMedia.first()
val lastItem = curMedia.last() val lastItem = curMedia.last()
val dirName = checkAppendingHidden(path, hiddenString, includedFolders)
val lastModified = if (isSortingAscending) Math.min(firstItem.modified, lastItem.modified) else Math.max(firstItem.modified, lastItem.modified) val lastModified = if (isSortingAscending) Math.min(firstItem.modified, lastItem.modified) else Math.max(firstItem.modified, lastItem.modified)
val dateTaken = if (isSortingAscending) Math.min(firstItem.taken, lastItem.taken) else Math.max(firstItem.taken, lastItem.taken) val dateTaken = if (isSortingAscending) Math.min(firstItem.taken, lastItem.taken) else Math.max(firstItem.taken, lastItem.taken)
val size = curMedia.sumByLong { it.size } val size = curMedia.sumByLong { it.size }
val mediaTypes = curMedia.getDirMediaTypes()
return Directory(null, path, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, getPathLocation(path), mediaTypes) return Directory(null, path, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, getPathLocation(path), mediaTypes)
} }
private fun setupAdapter(dirs: ArrayList<Directory>) { private fun setupAdapter(dirs: ArrayList<Directory>, textToSearch: String = "") {
val currAdapter = directories_grid.adapter val currAdapter = directories_grid.adapter
val distinctDirs = dirs.distinctBy { it.path.getDistinctPath() }.toMutableList() as ArrayList<Directory>
val sortedDirs = getSortedDirectories(distinctDirs)
var dirsToShow = getDirsToShow(sortedDirs, mDirs, mCurrentPathPrefix).clone() as ArrayList<Directory>
if (currAdapter == null) { if (currAdapter == null) {
initZoomListener() initZoomListener()
val fastscroller = if (config.scrollHorizontally) directories_horizontal_fastscroller else directories_vertical_fastscroller val fastscroller = if (config.scrollHorizontally) directories_horizontal_fastscroller else directories_vertical_fastscroller
DirectoryAdapter(this, dirs.clone() as ArrayList<Directory>, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) { DirectoryAdapter(this, dirsToShow, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) {
val path = (it as Directory).path val clickedDir = it as Directory
if (path != config.tempFolderPath) { val path = clickedDir.path
itemClicked(path) if (clickedDir.subfoldersCount == 1 || !config.groupDirectSubfolders) {
if (path != config.tempFolderPath) {
itemClicked(path)
}
} else {
mCurrentPathPrefix = path
mOpenedSubfolders.add(path)
setupAdapter(mDirs, "")
} }
}.apply { }.apply {
setupZoomListener(mZoomListener) setupZoomListener(mZoomListener)
directories_grid.adapter = this runOnUiThread {
directories_grid.adapter = this
setupScrollDirection()
}
} }
measureRecyclerViewContent(dirsToShow)
} else { } else {
showSortedDirs(dirs) if (textToSearch.isNotEmpty()) {
dirsToShow = dirsToShow.filter { it.name.contains(textToSearch, true) }.sortedBy { !it.name.startsWith(textToSearch, true) }.toMutableList() as ArrayList
}
runOnUiThread {
(directories_grid.adapter as? DirectoryAdapter)?.updateDirs(dirsToShow)
measureRecyclerViewContent(dirsToShow)
}
} }
getRecyclerAdapter()?.dirs?.apply { // recyclerview sometimes becomes empty at init/update, triggering an invisible refresh like this seems to work fine
measureRecyclerViewContent(this) directories_grid.postDelayed({
} directories_grid.scrollBy(0, 0)
setupScrollDirection() }, 500)
} }
private fun setupScrollDirection() { private fun setupScrollDirection() {
@ -1051,7 +1057,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (invalidDirs.isNotEmpty()) { if (invalidDirs.isNotEmpty()) {
dirs.removeAll(invalidDirs) dirs.removeAll(invalidDirs)
showSortedDirs(dirs) setupAdapter(dirs)
invalidDirs.forEach { invalidDirs.forEach {
mDirectoryDao.deleteDirPath(it.path) mDirectoryDao.deleteDirPath(it.path)
} }
@ -1223,6 +1229,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
add(Release(201, R.string.release_201)) add(Release(201, R.string.release_201))
add(Release(202, R.string.release_202)) add(Release(202, R.string.release_202))
add(Release(206, R.string.release_206)) add(Release(206, R.string.release_206))
add(Release(213, R.string.release_213))
checkWhatsNew(this, BuildConfig.VERSION_CODE) checkWhatsNew(this, BuildConfig.VERSION_CODE)
} }
} }

View file

@ -118,6 +118,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
media_empty_text.setOnClickListener { media_empty_text.setOnClickListener {
showFilterMediaDialog() showFilterMediaDialog()
} }
updateWidgets()
} }
override fun onStart() { override fun onStart() {
@ -339,7 +341,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
val dirName = when { val dirName = when {
mPath == FAVORITES -> getString(R.string.favorites) mPath == FAVORITES -> getString(R.string.favorites)
mPath == RECYCLE_BIN -> getString(R.string.recycle_bin) mPath == RECYCLE_BIN -> getString(R.string.recycle_bin)
mPath == OTG_PATH -> getString(R.string.otg) mPath == OTG_PATH -> getString(R.string.usb)
mPath.startsWith(OTG_PATH) -> mPath.trimEnd('/').substringAfterLast('/') mPath.startsWith(OTG_PATH) -> mPath.trimEnd('/').substringAfterLast('/')
else -> getHumanizedFilename(mPath) else -> getHumanizedFilename(mPath)
} }
@ -585,7 +587,15 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
mCurrAsyncTask?.stopFetching() mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) { mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
Thread { Thread {
gotMedia(it) val oldMedia = mMedia.clone() as ArrayList<ThumbnailItem>
val newMedia = it
gotMedia(newMedia, false)
try {
oldMedia.filter { !newMedia.contains(it) }.mapNotNull { it as? Medium }.filter { !File(it.path).exists() }.forEach {
mMediumDao.deleteMediumPath(it.path)
}
} catch (e: Exception) {
}
}.start() }.start()
} }
@ -689,8 +699,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
val pathToCheck = if (mPath.isEmpty()) SHOW_ALL else mPath val pathToCheck = if (mPath.isEmpty()) SHOW_ALL else mPath
val hasSections = config.getFolderGrouping(pathToCheck) and GROUP_BY_NONE == 0 && !config.scrollHorizontally val hasSections = config.getFolderGrouping(pathToCheck) and GROUP_BY_NONE == 0 && !config.scrollHorizontally
val sectionTitleHeight = if (hasSections) layoutManager.getChildAt(0)?.height ?: 0 else 0 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 val thumbnailHeight = if (hasSections) layoutManager.getChildAt(1)?.height ?: 0 else layoutManager.getChildAt(0)?.height ?: 0
?: 0
var fullHeight = 0 var fullHeight = 0
var curSectionItems = 0 var curSectionItems = 0
@ -820,7 +829,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
} }
} }
private fun gotMedia(media: ArrayList<ThumbnailItem>, isFromCache: Boolean = false) { private fun gotMedia(media: ArrayList<ThumbnailItem>, isFromCache: Boolean) {
mIsGettingMedia = false mIsGettingMedia = false
checkLastMediaChanged() checkLastMediaChanged()
mMedia = media mMedia = media

View file

@ -80,6 +80,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
var screenHeight = 0 var screenHeight = 0
} }
@TargetApi(Build.VERSION_CODES.P)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_medium) setContentView(R.layout.activity_medium)
@ -337,6 +338,24 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
} }
} }
if (intent.action == "com.android.camera.action.REVIEW") {
Thread {
if (galleryDB.MediumDao().getMediaFromPath(mPath).isEmpty()) {
val type = when {
mPath.isVideoFast() -> TYPE_VIDEOS
mPath.isGif() -> TYPE_GIFS
mPath.isSvg() -> TYPE_SVGS
mPath.isRawFast() -> TYPE_RAWS
else -> TYPE_IMAGES
}
val duration = if (type == TYPE_VIDEOS) mPath.getVideoDuration() else 0
val medium = Medium(null, mPath.getFilenameFromPath(), mPath, mPath.getParentPath(), System.currentTimeMillis(), System.currentTimeMillis(), File(mPath).length(), type, duration, false, 0)
galleryDB.MediumDao().insert(medium)
}
}.start()
}
} }
private fun initBottomActions() { private fun initBottomActions() {
@ -936,8 +955,16 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
private fun askConfirmDelete() { private fun askConfirmDelete() {
val message = if (config.useRecycleBin && !getCurrentMedium()!!.getIsInRecycleBin()) R.string.are_you_sure_recycle_bin else R.string.are_you_sure_delete val filename = "\"${getCurrentPath().getFilenameFromPath()}\""
DeleteWithRememberDialog(this, getString(message)) {
val baseString = if (config.useRecycleBin && !getCurrentMedium()!!.getIsInRecycleBin()) {
R.string.move_to_recycle_bin_confirmation
} else {
R.string.deletion_confirmation
}
val message = String.format(resources.getString(baseString), filename)
DeleteWithRememberDialog(this, message) {
config.tempSkipDeleteConfirmation = it config.tempSkipDeleteConfirmation = it
deleteConfirmed() deleteConfirmed()
} }

View file

@ -0,0 +1,184 @@
package com.simplemobiletools.gallery.pro.activities
import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.widget.RelativeLayout
import android.widget.RemoteViews
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.dialogs.PickDirectoryDialog
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.helpers.MyWidgetProvider
import com.simplemobiletools.gallery.pro.models.Directory
import com.simplemobiletools.gallery.pro.models.Widget
import kotlinx.android.synthetic.main.activity_widget_config.*
class WidgetConfigureActivity : SimpleActivity() {
private var mBgAlpha = 0f
private var mWidgetId = 0
private var mBgColor = 0
private var mBgColorWithoutTransparency = 0
private var mTextColor = 0
private var mFolderPath = ""
private var mDirectories = ArrayList<Directory>()
public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false
super.onCreate(savedInstanceState)
setResult(RESULT_CANCELED)
setContentView(R.layout.activity_widget_config)
initVariables()
mWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID
if (mWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish()
}
config_save.setOnClickListener { saveConfig() }
config_bg_color.setOnClickListener { pickBackgroundColor() }
config_text_color.setOnClickListener { pickTextColor() }
folder_picker_value.setOnClickListener { changeSelectedFolder() }
config_image_holder.setOnClickListener { changeSelectedFolder() }
folder_picker_show_folder_name.isChecked = config.showWidgetFolderName
handleFolderNameDisplay()
folder_picker_show_folder_name_holder.setOnClickListener {
folder_picker_show_folder_name.toggle()
handleFolderNameDisplay()
}
updateTextColors(folder_picker_holder)
folder_picker_holder.background = ColorDrawable(config.backgroundColor)
getCachedDirectories(false, false) {
mDirectories = it
val path = it.firstOrNull()?.path
if (path != null) {
updateFolderImage(path)
}
}
}
private fun initVariables() {
mBgColor = config.widgetBgColor
if (mBgColor == 1) {
mBgColor = Color.BLACK
mBgAlpha = .2f
} else {
mBgAlpha = Color.alpha(mBgColor) / 255f
}
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
config_bg_seekbar.apply {
progress = (mBgAlpha * 100).toInt()
onSeekBarChangeListener {
mBgAlpha = it / 100f
updateBackgroundColor()
}
}
updateBackgroundColor()
mTextColor = config.widgetTextColor
updateTextColor()
}
private fun saveConfig() {
val views = RemoteViews(packageName, R.layout.widget)
views.setBackgroundColor(R.id.widget_holder, mBgColor)
AppWidgetManager.getInstance(this).updateAppWidget(mWidgetId, views)
config.showWidgetFolderName = folder_picker_show_folder_name.isChecked
val widget = Widget(null, mWidgetId, mFolderPath)
Thread {
widgetsDB.insertOrUpdate(widget)
}.start()
storeWidgetColors()
requestWidgetUpdate()
Intent().apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mWidgetId)
setResult(Activity.RESULT_OK, this)
}
finish()
}
private fun storeWidgetColors() {
config.apply {
widgetBgColor = mBgColor
widgetTextColor = mTextColor
}
}
private fun requestWidgetUpdate() {
Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidgetProvider::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mWidgetId))
sendBroadcast(this)
}
}
private fun updateBackgroundColor() {
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
config_save.setBackgroundColor(mBgColor)
config_image_holder.setBackgroundColor(mBgColor)
config_bg_color.setFillWithStroke(mBgColor, Color.BLACK)
}
private fun updateTextColor() {
config_save.setTextColor(mTextColor)
config_folder_name.setTextColor(mTextColor)
config_text_color.setFillWithStroke(mTextColor, Color.BLACK)
}
private fun pickBackgroundColor() {
ColorPickerDialog(this, mBgColorWithoutTransparency) { wasPositivePressed, color ->
if (wasPositivePressed) {
mBgColorWithoutTransparency = color
updateBackgroundColor()
}
}
}
private fun pickTextColor() {
ColorPickerDialog(this, mTextColor) { wasPositivePressed, color ->
if (wasPositivePressed) {
mTextColor = color
updateTextColor()
}
}
}
private fun changeSelectedFolder() {
PickDirectoryDialog(this, "", false) {
updateFolderImage(it)
}
}
private fun updateFolderImage(folderPath: String) {
mFolderPath = folderPath
runOnUiThread {
folder_picker_value.text = getFolderNameFromPath(folderPath)
config_folder_name.text = getFolderNameFromPath(folderPath)
}
Thread {
val path = directoryDB.getDirectoryThumbnail(folderPath)
if (path != null) {
runOnUiThread {
loadJpg(path, config_image, config.cropThumbnails)
}
}
}.start()
}
private fun handleFolderNameDisplay() {
val showFolderName = folder_picker_show_folder_name.isChecked
config_folder_name.beVisibleIf(showFolderName)
(config_image.layoutParams as RelativeLayout.LayoutParams).bottomMargin = if (showFolderName) 0 else resources.getDimension(R.dimen.normal_margin).toInt()
}
}

View file

@ -38,6 +38,7 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
private var showMediaCount = config.showMediaCount private var showMediaCount = config.showMediaCount
private var animateGifs = config.animateGifs private var animateGifs = config.animateGifs
private var cropThumbnails = config.cropThumbnails private var cropThumbnails = config.cropThumbnails
private var groupDirectSubfolders = config.groupDirectSubfolders
private var currentDirectoriesHash = dirs.hashCode() private var currentDirectoriesHash = dirs.hashCode()
init { init {
@ -371,7 +372,12 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
config.skipDeleteConfirmation -> deleteFolders() config.skipDeleteConfirmation -> deleteFolders()
else -> { else -> {
val itemsCnt = selectedKeys.size val itemsCnt = selectedKeys.size
val items = resources.getQuantityString(R.plurals.delete_items, itemsCnt, itemsCnt) val items = if (itemsCnt == 1) {
"\"${getSelectedPaths().first().getFilenameFromPath()}\""
} else {
resources.getQuantityString(R.plurals.delete_items, itemsCnt, itemsCnt)
}
val fileDirItem = getFirstSelectedItem() ?: return val fileDirItem = getFirstSelectedItem() ?: return
val baseString = if (!config.useRecycleBin || (isOneItemSelected() && fileDirItem.isRecycleBin()) || (isOneItemSelected() && fileDirItem.areFavorites())) { val baseString = if (!config.useRecycleBin || (isOneItemSelected() && fileDirItem.isRecycleBin()) || (isOneItemSelected() && fileDirItem.areFavorites())) {
R.string.deletion_confirmation R.string.deletion_confirmation
@ -501,9 +507,9 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList<Directo
private fun setupView(view: View, directory: Directory) { private fun setupView(view: View, directory: Directory) {
val isSelected = selectedKeys.contains(directory.path.hashCode()) val isSelected = selectedKeys.contains(directory.path.hashCode())
view.apply { view.apply {
dir_name.text = directory.name dir_name.text = if (groupDirectSubfolders) "${directory.name} (${directory.subfoldersCount})" else directory.name
dir_path?.text = "${directory.path.substringBeforeLast("/")}/" dir_path?.text = "${directory.path.substringBeforeLast("/")}/"
photo_cnt.text = directory.mediaCnt.toString() photo_cnt.text = directory.subfoldersMediaCount.toString()
val thumbnailType = when { val thumbnailType = when {
directory.tmb.isVideoFast() -> TYPE_VIDEOS directory.tmb.isVideoFast() -> TYPE_VIDEOS
directory.tmb.isGif() -> TYPE_GIFS directory.tmb.isGif() -> TYPE_GIFS

View file

@ -372,8 +372,15 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList<Thumbnai
} }
private fun askConfirmDelete() { private fun askConfirmDelete() {
val items = resources.getQuantityString(R.plurals.delete_items, selectedKeys.size, selectedKeys.size) val itemsCnt = selectedKeys.size
val isRecycleBin = getSelectedPaths().first().startsWith(activity.recycleBinPath) val firstPath = getSelectedPaths().first()
val items = if (itemsCnt == 1) {
"\"${firstPath.getFilenameFromPath()}\""
} else {
resources.getQuantityString(R.plurals.delete_items, itemsCnt, itemsCnt)
}
val isRecycleBin = firstPath.startsWith(activity.recycleBinPath)
val baseString = if (config.useRecycleBin && !isRecycleBin) R.string.move_to_recycle_bin_confirmation else R.string.deletion_confirmation val baseString = if (config.useRecycleBin && !isRecycleBin) R.string.move_to_recycle_bin_confirmation else R.string.deletion_confirmation
val question = String.format(resources.getString(baseString), items) val question = String.format(resources.getString(baseString), items)
DeleteWithRememberDialog(activity, question) { DeleteWithRememberDialog(activity, question) {

View file

@ -8,16 +8,20 @@ import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao
import com.simplemobiletools.gallery.pro.interfaces.MediumDao import com.simplemobiletools.gallery.pro.interfaces.MediumDao
import com.simplemobiletools.gallery.pro.interfaces.WidgetsDao
import com.simplemobiletools.gallery.pro.models.Directory import com.simplemobiletools.gallery.pro.models.Directory
import com.simplemobiletools.gallery.pro.models.Medium import com.simplemobiletools.gallery.pro.models.Medium
import com.simplemobiletools.gallery.pro.models.Widget
@Database(entities = [Directory::class, Medium::class], version = 5) @Database(entities = [Directory::class, Medium::class, Widget::class], version = 6)
abstract class GalleryDatabase : RoomDatabase() { abstract class GalleryDatabase : RoomDatabase() {
abstract fun DirectoryDao(): DirectoryDao abstract fun DirectoryDao(): DirectoryDao
abstract fun MediumDao(): MediumDao abstract fun MediumDao(): MediumDao
abstract fun WidgetsDao(): WidgetsDao
companion object { companion object {
private var db: GalleryDatabase? = null private var db: GalleryDatabase? = null
@ -26,7 +30,9 @@ abstract class GalleryDatabase : RoomDatabase() {
synchronized(GalleryDatabase::class) { synchronized(GalleryDatabase::class) {
if (db == null) { if (db == null) {
db = Room.databaseBuilder(context.applicationContext, GalleryDatabase::class.java, "gallery.db") db = Room.databaseBuilder(context.applicationContext, GalleryDatabase::class.java, "gallery.db")
.fallbackToDestructiveMigration()
.addMigrations(MIGRATION_4_5) .addMigrations(MIGRATION_4_5)
.addMigrations(MIGRATION_5_6)
.build() .build()
} }
} }
@ -43,5 +49,12 @@ abstract class GalleryDatabase : RoomDatabase() {
database.execSQL("ALTER TABLE media ADD COLUMN video_duration INTEGER default 0 NOT NULL") database.execSQL("ALTER TABLE media ADD COLUMN video_duration INTEGER default 0 NOT NULL")
} }
} }
private val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `widgets` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `widget_id` INTEGER NOT NULL, `folder_path` TEXT NOT NULL)")
database.execSQL("CREATE UNIQUE INDEX `index_widgets_widget_id` ON `widgets` (`widget_id`)")
}
}
} }
} }

View file

@ -0,0 +1,38 @@
package com.simplemobiletools.gallery.pro.dialogs
import android.view.View
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.extensions.config
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_LIST
import kotlinx.android.synthetic.main.dialog_change_view_type.view.*
class ChangeViewTypeDialog(val activity: BaseSimpleActivity, val callback: () -> Unit) {
private var view: View
private var config = activity.config
init {
view = activity.layoutInflater.inflate(R.layout.dialog_change_view_type, null).apply {
val viewToCheck = if (config.viewTypeFolders == VIEW_TYPE_GRID) change_view_type_dialog_radio_grid.id else change_view_type_dialog_radio_list.id
change_view_type_dialog_radio.check(viewToCheck)
change_view_type_dialog_group_direct_subfolders.isChecked = config.groupDirectSubfolders
}
AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this)
}
}
private fun dialogConfirmed() {
val viewType = if (view.change_view_type_dialog_radio.checkedRadioButtonId == view.change_view_type_dialog_radio_grid.id) VIEW_TYPE_GRID else VIEW_TYPE_LIST
config.viewTypeFolders = viewType
config.groupDirectSubfolders = view.change_view_type_dialog_group_direct_subfolders.isChecked
callback()
}
}

View file

@ -0,0 +1,39 @@
package com.simplemobiletools.gallery.pro.dialogs
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.commons.extensions.showKeyboard
import com.simplemobiletools.commons.extensions.value
import com.simplemobiletools.gallery.pro.R
import kotlinx.android.synthetic.main.dialog_custom_aspect_ratio.view.*
class CustomAspectRatioDialog(val activity: BaseSimpleActivity, val defaultCustomAspectRatio: Pair<Int, Int>?, val callback: (aspectRatio: Pair<Int, Int>) -> Unit) {
init {
val view = activity.layoutInflater.inflate(R.layout.dialog_custom_aspect_ratio, null).apply {
aspect_ratio_width.setText(defaultCustomAspectRatio?.first?.toString() ?: "")
aspect_ratio_height.setText(defaultCustomAspectRatio?.second?.toString() ?: "")
}
AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
.create().apply {
activity.setupDialogStuff(view, this) {
showKeyboard(view.aspect_ratio_width)
getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val width = getViewValue(view.aspect_ratio_width)
val height = getViewValue(view.aspect_ratio_height)
callback(Pair(width, height))
dismiss()
}
}
}
}
private fun getViewValue(view: EditText): Int {
val textValue = view.value
return if (textValue.isEmpty()) 0 else textValue.toInt()
}
}

View file

@ -17,6 +17,7 @@ class OtherAspectRatioDialog(val activity: BaseSimpleActivity, val lastOtherAspe
other_aspect_ratio_5_3.setOnClickListener { ratioPicked(Pair(5, 3)) } other_aspect_ratio_5_3.setOnClickListener { ratioPicked(Pair(5, 3)) }
other_aspect_ratio_16_9.setOnClickListener { ratioPicked(Pair(16, 9)) } other_aspect_ratio_16_9.setOnClickListener { ratioPicked(Pair(16, 9)) }
other_aspect_ratio_19_9.setOnClickListener { ratioPicked(Pair(19, 9)) } other_aspect_ratio_19_9.setOnClickListener { ratioPicked(Pair(19, 9)) }
other_aspect_ratio_custom.setOnClickListener { customRatioPicked() }
other_aspect_ratio_1_2.setOnClickListener { ratioPicked(Pair(1, 2)) } other_aspect_ratio_1_2.setOnClickListener { ratioPicked(Pair(1, 2)) }
other_aspect_ratio_2_3.setOnClickListener { ratioPicked(Pair(2, 3)) } other_aspect_ratio_2_3.setOnClickListener { ratioPicked(Pair(2, 3)) }
@ -46,6 +47,10 @@ class OtherAspectRatioDialog(val activity: BaseSimpleActivity, val lastOtherAspe
else -> 0 else -> 0
} }
other_aspect_ratio_dialog_radio_2.check(radio2SelectedItemId) other_aspect_ratio_dialog_radio_2.check(radio2SelectedItemId)
if (radio1SelectedItemId == 0 && radio2SelectedItemId == 0) {
other_aspect_ratio_dialog_radio_1.check(other_aspect_ratio_custom.id)
}
} }
dialog = AlertDialog.Builder(activity) dialog = AlertDialog.Builder(activity)
@ -55,6 +60,13 @@ class OtherAspectRatioDialog(val activity: BaseSimpleActivity, val lastOtherAspe
} }
} }
private fun customRatioPicked() {
CustomAspectRatioDialog(activity, lastOtherAspectRatio) {
callback(it)
dialog.dismiss()
}
}
private fun ratioPicked(pair: Pair<Int, Int>) { private fun ratioPicked(pair: Pair<Int, Int>) {
callback(pair) callback(pair)
dialog.dismiss() dialog.dismiss()

View file

@ -1,5 +1,6 @@
package com.simplemobiletools.gallery.pro.dialogs package com.simplemobiletools.gallery.pro.dialogs
import android.view.KeyEvent
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
@ -8,20 +9,20 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.views.MyGridLayoutManager import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.DirectoryAdapter import com.simplemobiletools.gallery.pro.adapters.DirectoryAdapter
import com.simplemobiletools.gallery.pro.extensions.addTempFolderIfNeeded import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.extensions.config
import com.simplemobiletools.gallery.pro.extensions.getCachedDirectories
import com.simplemobiletools.gallery.pro.extensions.getSortedDirectories
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_GRID import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.pro.models.Directory import com.simplemobiletools.gallery.pro.models.Directory
import kotlinx.android.synthetic.main.dialog_directory_picker.view.* import kotlinx.android.synthetic.main.dialog_directory_picker.view.*
class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) { class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: String, showOtherFolderButton: Boolean, val callback: (path: String) -> Unit) {
var dialog: AlertDialog private var dialog: AlertDialog
var shownDirectories = ArrayList<Directory>() private var shownDirectories = ArrayList<Directory>()
var view = activity.layoutInflater.inflate(R.layout.dialog_directory_picker, null) private var allDirectories = ArrayList<Directory>()
var isGridViewType = activity.config.viewTypeFolders == VIEW_TYPE_GRID private var openedSubfolders = arrayListOf("")
var showHidden = activity.config.shouldShowHidden private var view = activity.layoutInflater.inflate(R.layout.dialog_directory_picker, null)
private var isGridViewType = activity.config.viewTypeFolders == VIEW_TYPE_GRID
private var showHidden = activity.config.shouldShowHidden
private var currentPathPrefix = ""
init { init {
(view.directories_grid.layoutManager as MyGridLayoutManager).apply { (view.directories_grid.layoutManager as MyGridLayoutManager).apply {
@ -29,22 +30,32 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
spanCount = if (isGridViewType) activity.config.dirColumnCnt else 1 spanCount = if (isGridViewType) activity.config.dirColumnCnt else 1
} }
dialog = AlertDialog.Builder(activity) val builder = AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok, null) .setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(R.string.cancel, null)
.setNeutralButton(R.string.other_folder) { dialogInterface, i -> showOtherFolder() } .setOnKeyListener { dialogInterface, i, keyEvent ->
.create().apply { if (keyEvent.action == KeyEvent.ACTION_UP && i == KeyEvent.KEYCODE_BACK) {
activity.setupDialogStuff(view, this, R.string.select_destination) { backPressed()
view.directories_show_hidden.beVisibleIf(!context.config.shouldShowHidden) }
view.directories_show_hidden.setOnClickListener { true
activity.handleHiddenFolderPasswordProtection { }
view.directories_show_hidden.beGone()
showHidden = true if (showOtherFolderButton) {
fetchDirectories(true) builder.setNeutralButton(R.string.other_folder) { dialogInterface, i -> showOtherFolder() }
} }
}
dialog = builder.create().apply {
activity.setupDialogStuff(view, this, R.string.select_destination) {
view.directories_show_hidden.beVisibleIf(!context.config.shouldShowHidden)
view.directories_show_hidden.setOnClickListener {
activity.handleHiddenFolderPasswordProtection {
view.directories_show_hidden.beGone()
showHidden = true
fetchDirectories(true)
} }
} }
}
}
fetchDirectories(false) fetchDirectories(false)
} }
@ -52,6 +63,10 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
private fun fetchDirectories(forceShowHidden: Boolean) { private fun fetchDirectories(forceShowHidden: Boolean) {
activity.getCachedDirectories(forceShowHidden = forceShowHidden) { activity.getCachedDirectories(forceShowHidden = forceShowHidden) {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
it.forEach {
it.subfoldersMediaCount = it.mediaCnt
}
activity.runOnUiThread { activity.runOnUiThread {
gotDirectories(activity.addTempFolderIfNeeded(it)) gotDirectories(activity.addTempFolderIfNeeded(it))
} }
@ -66,18 +81,32 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
} }
private fun gotDirectories(newDirs: ArrayList<Directory>) { private fun gotDirectories(newDirs: ArrayList<Directory>) {
val dirs = activity.getSortedDirectories(newDirs) if (allDirectories.isEmpty()) {
if (dirs.hashCode() == shownDirectories.hashCode()) allDirectories = newDirs.clone() as ArrayList<Directory>
}
val distinctDirs = newDirs.distinctBy { it.path.getDistinctPath() }.toMutableList() as ArrayList<Directory>
val sortedDirs = activity.getSortedDirectories(distinctDirs)
val dirs = activity.getDirsToShow(sortedDirs, allDirectories, currentPathPrefix).clone() as ArrayList<Directory>
if (dirs.hashCode() == shownDirectories.hashCode()) {
return return
}
shownDirectories = dirs shownDirectories = dirs
val adapter = DirectoryAdapter(activity, dirs.clone() as ArrayList<Directory>, null, view.directories_grid, true) { val adapter = DirectoryAdapter(activity, dirs.clone() as ArrayList<Directory>, null, view.directories_grid, true) {
if ((it as Directory).path.trimEnd('/') == sourcePath) { val clickedDir = it as Directory
activity.toast(R.string.source_and_destination_same) val path = clickedDir.path
return@DirectoryAdapter if (clickedDir.subfoldersCount == 1 || !activity.config.groupDirectSubfolders) {
if (path.trimEnd('/') == sourcePath) {
activity.toast(R.string.source_and_destination_same)
return@DirectoryAdapter
} else {
callback(path)
dialog.dismiss()
}
} else { } else {
callback(it.path) currentPathPrefix = path
dialog.dismiss() openedSubfolders.add(path)
gotDirectories(allDirectories)
} }
} }
@ -105,4 +134,18 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
} }
} }
} }
private fun backPressed() {
if (activity.config.groupDirectSubfolders) {
if (currentPathPrefix.isEmpty()) {
dialog.dismiss()
} else {
openedSubfolders.removeAt(openedSubfolders.size - 1)
currentPathPrefix = openedSubfolders.last()
gotDirectories(allDirectories)
}
} else {
dialog.dismiss()
}
}
} }

View file

@ -53,7 +53,7 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
} }
private fun showOtherFolder() { private fun showOtherFolder() {
PickDirectoryDialog(activity, path) { PickDirectoryDialog(activity, path, true) {
callback(it) callback(it)
dialog.dismiss() dialog.dismiss()
} }

View file

@ -6,11 +6,11 @@ import androidx.appcompat.app.AlertDialog
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.gallery.pro.R import com.simplemobiletools.gallery.pro.R
import kotlinx.android.synthetic.main.resize_image.view.* import kotlinx.android.synthetic.main.dialog_resize_image.view.*
class ResizeDialog(val activity: BaseSimpleActivity, val size: Point, val callback: (newSize: Point) -> Unit) { class ResizeDialog(val activity: BaseSimpleActivity, val size: Point, val callback: (newSize: Point) -> Unit) {
init { init {
val view = activity.layoutInflater.inflate(R.layout.resize_image, null) val view = activity.layoutInflater.inflate(R.layout.dialog_resize_image, null)
val widthView = view.image_width val widthView = view.image_width
val heightView = view.image_height val heightView = view.image_height
@ -69,7 +69,7 @@ class ResizeDialog(val activity: BaseSimpleActivity, val size: Point, val callba
} }
} }
fun getViewValue(view: EditText): Int { private fun getViewValue(view: EditText): Int {
val textValue = view.value val textValue = view.value
return if (textValue.isEmpty()) 0 else textValue.toInt() return if (textValue.isEmpty()) 0 else textValue.toInt()
} }

View file

@ -149,6 +149,7 @@ fun BaseSimpleActivity.removeNoMedia(path: String, callback: (() -> Unit)? = nul
} }
tryDeleteFileDirItem(file.toFileDirItem(applicationContext), false, false) { tryDeleteFileDirItem(file.toFileDirItem(applicationContext), false, false) {
scanPathRecursively(file.parent)
callback?.invoke() callback?.invoke()
} }
} }
@ -183,7 +184,7 @@ fun BaseSimpleActivity.tryCopyMoveFilesTo(fileDirItems: ArrayList<FileDirItem>,
} }
val source = fileDirItems[0].getParentPath() val source = fileDirItems[0].getParentPath()
PickDirectoryDialog(this, source) { PickDirectoryDialog(this, source, true) {
copyMoveFilesTo(fileDirItems, source.trimEnd('/'), it, isCopyOperation, true, config.shouldShowHidden, callback) copyMoveFilesTo(fileDirItems, source.trimEnd('/'), it, isCopyOperation, true, config.shouldShowHidden, callback)
} }
} }

View file

@ -1,5 +1,7 @@
package com.simplemobiletools.gallery.pro.extensions package com.simplemobiletools.gallery.pro.extensions
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
@ -25,6 +27,7 @@ import com.simplemobiletools.gallery.pro.databases.GalleryDatabase
import com.simplemobiletools.gallery.pro.helpers.* import com.simplemobiletools.gallery.pro.helpers.*
import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao import com.simplemobiletools.gallery.pro.interfaces.DirectoryDao
import com.simplemobiletools.gallery.pro.interfaces.MediumDao import com.simplemobiletools.gallery.pro.interfaces.MediumDao
import com.simplemobiletools.gallery.pro.interfaces.WidgetsDao
import com.simplemobiletools.gallery.pro.models.Directory import com.simplemobiletools.gallery.pro.models.Directory
import com.simplemobiletools.gallery.pro.models.Medium import com.simplemobiletools.gallery.pro.models.Medium
import com.simplemobiletools.gallery.pro.models.ThumbnailItem import com.simplemobiletools.gallery.pro.models.ThumbnailItem
@ -32,6 +35,10 @@ import com.simplemobiletools.gallery.pro.svg.SvgSoftwareLayerSetter
import com.simplemobiletools.gallery.pro.views.MySquareImageView import com.simplemobiletools.gallery.pro.views.MySquareImageView
import pl.droidsonroids.gif.GifDrawable import pl.droidsonroids.gif.GifDrawable
import java.io.File import java.io.File
import java.util.HashSet
import java.util.LinkedHashSet
import kotlin.Comparator
import kotlin.collections.ArrayList
val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT val Context.portrait get() = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager val Context.audioManager get() = getSystemService(Context.AUDIO_SERVICE) as AudioManager
@ -104,6 +111,10 @@ val Context.config: Config get() = Config.newInstance(applicationContext)
val Context.galleryDB: GalleryDatabase get() = GalleryDatabase.getInstance(applicationContext) val Context.galleryDB: GalleryDatabase get() = GalleryDatabase.getInstance(applicationContext)
val Context.widgetsDB: WidgetsDao get() = GalleryDatabase.getInstance(applicationContext).WidgetsDao()
val Context.directoryDB: DirectoryDao get() = GalleryDatabase.getInstance(applicationContext).DirectoryDao()
val Context.recycleBin: File get() = filesDir val Context.recycleBin: File get() = filesDir
val Context.recycleBinPath: String get() = filesDir.absolutePath val Context.recycleBinPath: String get() = filesDir.absolutePath
@ -159,6 +170,10 @@ fun Context.getSortedDirectories(source: ArrayList<Directory>): ArrayList<Direct
else -> o1.taken.compareTo(o2.taken) else -> o1.taken.compareTo(o2.taken)
} }
if (result == 0) {
result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
}
if (sorting and SORT_DESCENDING != 0) { if (sorting and SORT_DESCENDING != 0) {
result *= -1 result *= -1
} }
@ -168,6 +183,120 @@ fun Context.getSortedDirectories(source: ArrayList<Directory>): ArrayList<Direct
return movePinnedDirectoriesToFront(dirs) return movePinnedDirectoriesToFront(dirs)
} }
fun Context.getDirsToShow(dirs: ArrayList<Directory>, allDirs: ArrayList<Directory>, currentPathPrefix: String): ArrayList<Directory> {
return if (config.groupDirectSubfolders) {
dirs.forEach {
it.subfoldersCount = 0
it.subfoldersMediaCount = it.mediaCnt
}
val dirFolders = dirs.map { it.path }.sorted().toMutableSet() as HashSet<String>
val foldersToShow = getDirectParentSubfolders(dirFolders, currentPathPrefix)
val parentDirs = dirs.filter { foldersToShow.contains(it.path) } as ArrayList<Directory>
updateSubfolderCounts(dirs, parentDirs)
// show the current folder as an available option too, not just subfolders
if (currentPathPrefix.isNotEmpty()) {
val currentFolder = allDirs.firstOrNull { parentDirs.firstOrNull { it.path == currentPathPrefix } == null && it.path == currentPathPrefix }
currentFolder?.apply {
subfoldersCount = 1
parentDirs.add(this)
}
}
parentDirs
} else {
dirs.forEach { it.subfoldersMediaCount = it.mediaCnt }
dirs
}
}
fun Context.getDirectParentSubfolders(folders: HashSet<String>, currentPathPrefix: String): HashSet<String> {
val internalPath = internalStoragePath
val sdPath = sdCardPath
val currentPaths = LinkedHashSet<String>()
folders.forEach {
val path = it
if (path != RECYCLE_BIN && path != FAVORITES && !path.equals(internalPath, true) && !path.equals(sdPath, true)) {
if (currentPathPrefix.isNotEmpty()) {
if (path == currentPathPrefix || File(path).parent.equals(currentPathPrefix, true)) {
currentPaths.add(path)
}
} else if (folders.any { !it.equals(path, true) && (File(path).parent.equals(it, true) || File(it).parent.equals(File(path).parent, true)) }) {
// if we have folders like
// /storage/emulated/0/Pictures/Images and
// /storage/emulated/0/Pictures/Screenshots,
// but /storage/emulated/0/Pictures is empty, show Images and Screenshots as separate folders, do not group them at /Pictures
val parent = File(path).parent
if (folders.contains(parent)) {
currentPaths.add(parent)
} else {
currentPaths.add(path)
}
} else {
currentPaths.add(path)
}
}
}
var areDirectSubfoldersAvailable = false
currentPaths.forEach {
val path = it
currentPaths.forEach {
if (!it.equals(path) && File(it).parent?.equals(path) == true) {
areDirectSubfoldersAvailable = true
}
}
}
if (currentPathPrefix.isEmpty() && folders.contains(RECYCLE_BIN)) {
currentPaths.add(RECYCLE_BIN)
}
if (currentPathPrefix.isEmpty() && folders.contains(FAVORITES)) {
currentPaths.add(FAVORITES)
}
if (folders.size == currentPaths.size) {
return currentPaths
}
folders.clear()
folders.addAll(currentPaths)
return if (areDirectSubfoldersAvailable) {
getDirectParentSubfolders(folders, currentPathPrefix)
} else {
folders
}
}
fun Context.updateSubfolderCounts(children: ArrayList<Directory>, parentDirs: ArrayList<Directory>) {
for (child in children) {
var longestSharedPath = ""
for (parentDir in parentDirs) {
if (parentDir.path == child.path) {
longestSharedPath = child.path
continue
}
if (child.path.startsWith(parentDir.path, true) && parentDir.path.length > longestSharedPath.length) {
longestSharedPath = parentDir.path
}
}
// make sure we count only the proper direct subfolders, grouped the same way as on the main screen
parentDirs.firstOrNull { it.path == longestSharedPath }?.apply {
if (path.equals(child.path, true) || path.equals(File(child.path).parent, true) || children.any { it.path.equals(File(child.path).parent, true) }) {
subfoldersCount++
if (path != child.path) {
subfoldersMediaCount += child.mediaCnt
}
}
}
}
}
fun Context.getNoMediaFolders(callback: (folders: ArrayList<String>) -> Unit) { fun Context.getNoMediaFolders(callback: (folders: ArrayList<String>) -> Unit) {
Thread { Thread {
val folders = ArrayList<String>() val folders = ArrayList<String>()
@ -234,10 +363,21 @@ fun Context.storeDirectoryItems(items: ArrayList<Directory>, directoryDao: Direc
} }
fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet<String>): String { fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet<String>): String {
val dirName = when (path) { val dirName = getFolderNameFromPath(path)
return if (File(path).doesThisOrParentHaveNoMedia() && !path.isThisOrParentIncluded(includedFolders)) {
"$dirName $hidden"
} else {
dirName
}
}
fun Context.getFolderNameFromPath(path: String): String {
return when (path) {
internalStoragePath -> getString(R.string.internal) internalStoragePath -> getString(R.string.internal)
sdCardPath -> getString(R.string.sd_card) sdCardPath -> getString(R.string.sd_card)
OTG_PATH -> getString(R.string.otg) OTG_PATH -> getString(R.string.usb)
FAVORITES -> getString(R.string.favorites)
RECYCLE_BIN -> getString(R.string.recycle_bin)
else -> { else -> {
if (path.startsWith(OTG_PATH)) { if (path.startsWith(OTG_PATH)) {
path.trimEnd('/').substringAfterLast('/') path.trimEnd('/').substringAfterLast('/')
@ -246,12 +386,6 @@ fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders:
} }
} }
} }
return if (File(path).doesThisOrParentHaveNoMedia() && !path.isThisOrParentIncluded(includedFolders)) {
"$dirName $hidden"
} else {
dirName
}
} }
fun Context.loadImage(type: Int, path: String, target: MySquareImageView, horizontalScroll: Boolean, animateGifs: Boolean, cropThumbnails: Boolean) { fun Context.loadImage(type: Int, path: String, target: MySquareImageView, horizontalScroll: Boolean, animateGifs: Boolean, cropThumbnails: Boolean) {
@ -482,3 +616,14 @@ fun Context.getUpdatedDeletedMedia(mediumDao: MediumDao): ArrayList<Medium> {
fun Context.deleteDBPath(mediumDao: MediumDao, path: String) { fun Context.deleteDBPath(mediumDao: MediumDao, path: String) {
mediumDao.deleteMediumPath(path.replaceFirst(recycleBinPath, RECYCLE_BIN)) mediumDao.deleteMediumPath(path.replaceFirst(recycleBinPath, RECYCLE_BIN))
} }
fun Context.updateWidgets() {
val widgetIDs = AppWidgetManager.getInstance(applicationContext).getAppWidgetIds(ComponentName(applicationContext, MyWidgetProvider::class.java))
if (widgetIDs.isNotEmpty()) {
Intent(applicationContext, MyWidgetProvider::class.java).apply {
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIDs)
sendBroadcast(this)
}
}
}

View file

@ -26,6 +26,9 @@ import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.ImageSource
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.davemorrissey.labs.subscaleview.decoder.DecoderFactory
import com.davemorrissey.labs.subscaleview.decoder.ImageDecoder
import com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.OTG_PATH import com.simplemobiletools.commons.helpers.OTG_PATH
import com.simplemobiletools.gallery.pro.R import com.simplemobiletools.gallery.pro.R
@ -377,18 +380,26 @@ class PhotoFragment : ViewPagerFragment() {
val path = getPathToLoad(medium) val path = getPathToLoad(medium)
isSubsamplingVisible = true isSubsamplingVisible = true
val bitmapDecoder = object : DecoderFactory<ImageDecoder> {
override fun make() = PicassoDecoder(path, Picasso.get(), rotation)
}
val regionDecoder = object : DecoderFactory<ImageRegionDecoder> {
override fun make() = PicassoRegionDecoder()
}
view.subsampling_view.apply { view.subsampling_view.apply {
setMaxTileSize(if (context!!.config.showHighestQuality) Integer.MAX_VALUE else 4096) setMaxTileSize(if (context!!.config.showHighestQuality) Integer.MAX_VALUE else 4096)
setMinimumTileDpi(if (context!!.config.showHighestQuality) -1 else getMinTileDpi()) setMinimumTileDpi(if (context!!.config.showHighestQuality) -1 else getMinTileDpi())
background = ColorDrawable(Color.TRANSPARENT) background = ColorDrawable(Color.TRANSPARENT)
setBitmapDecoderFactory { PicassoDecoder(path, Picasso.get(), rotation) } setBitmapDecoderFactory(bitmapDecoder)
setRegionDecoderFactory { PicassoRegionDecoder() } setRegionDecoderFactory(regionDecoder)
maxScale = 10f maxScale = 10f
beVisible() beVisible()
isQuickScaleEnabled = context.config.oneFingerZoom isQuickScaleEnabled = context.config.oneFingerZoom
setResetScaleOnSizeChange(false) setResetScaleOnSizeChange(false)
setImage(ImageSource.uri(path)) setImage(ImageSource.uri(path))
orientation = rotation setOrientation(rotation)
setEagerLoadingEnabled(false) setEagerLoadingEnabled(false)
setOnImageEventListener(object : SubsamplingScaleImageView.OnImageEventListener { setOnImageEventListener(object : SubsamplingScaleImageView.OnImageEventListener {
override fun onImageLoaded() { override fun onImageLoaded() {
@ -402,7 +413,7 @@ class PhotoFragment : ViewPagerFragment() {
mOriginalSubsamplingScale = scale mOriginalSubsamplingScale = scale
} }
override fun onTileLoadError(e: Exception?) { override fun onTileLoadError(e: Exception) {
} }
override fun onPreviewReleased() { override fun onPreviewReleased() {
@ -415,7 +426,7 @@ class PhotoFragment : ViewPagerFragment() {
beGone() beGone()
} }
override fun onPreviewLoadError(e: Exception?) { override fun onPreviewLoadError(e: Exception) {
background = ColorDrawable(Color.TRANSPARENT) background = ColorDrawable(Color.TRANSPARENT)
isSubsamplingVisible = false isSubsamplingVisible = false
beGone() beGone()

View file

@ -423,4 +423,12 @@ class Config(context: Context) : BaseConfig(context) {
var lastEditorCropOtherAspectRatioY: Int var lastEditorCropOtherAspectRatioY: Int
get() = prefs.getInt(LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y, 1) get() = prefs.getInt(LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y, 1)
set(lastEditorCropOtherAspectRatioY) = prefs.edit().putInt(LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y, lastEditorCropOtherAspectRatioY).apply() set(lastEditorCropOtherAspectRatioY) = prefs.edit().putInt(LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y, lastEditorCropOtherAspectRatioY).apply()
var groupDirectSubfolders: Boolean
get() = prefs.getBoolean(GROUP_DIRECT_SUBFOLDERS, false)
set(groupDirectSubfolders) = prefs.edit().putBoolean(GROUP_DIRECT_SUBFOLDERS, groupDirectSubfolders).apply()
var showWidgetFolderName: Boolean
get() = prefs.getBoolean(SHOW_WIDGET_FOLDER_NAME, true)
set(showWidgetFolderName) = prefs.edit().putBoolean(SHOW_WIDGET_FOLDER_NAME, showWidgetFolderName).apply()
} }

View file

@ -71,6 +71,8 @@ const val ALLOW_DOWN_GESTURE = "allow_down_gesture"
const val LAST_EDITOR_CROP_ASPECT_RATIO = "last_editor_crop_aspect_ratio" const val LAST_EDITOR_CROP_ASPECT_RATIO = "last_editor_crop_aspect_ratio"
const val LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_X = "last_editor_crop_other_aspect_ratio_x" const val LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_X = "last_editor_crop_other_aspect_ratio_x"
const val LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y = "last_editor_crop_other_aspect_ratio_y" const val LAST_EDITOR_CROP_OTHER_ASPECT_RATIO_Y = "last_editor_crop_other_aspect_ratio_y"
const val GROUP_DIRECT_SUBFOLDERS = "group_direct_subfolders"
const val SHOW_WIDGET_FOLDER_NAME = "show_widget_folder_name"
// slideshow // slideshow
const val SLIDESHOW_INTERVAL = "slideshow_interval" const val SLIDESHOW_INTERVAL = "slideshow_interval"

View file

@ -364,6 +364,10 @@ class MediaFetcher(val context: Context) {
else -> o1.taken.compareTo(o2.taken) else -> o1.taken.compareTo(o2.taken)
} }
if (result == 0) {
result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
}
if (sorting and SORT_DESCENDING != 0) { if (sorting and SORT_DESCENDING != 0) {
result *= -1 result *= -1
} }

View file

@ -0,0 +1,85 @@
package com.simplemobiletools.gallery.pro.helpers
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.RemoteViews
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.simplemobiletools.commons.extensions.setBackgroundColor
import com.simplemobiletools.commons.extensions.setText
import com.simplemobiletools.commons.extensions.setVisibleIf
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.activities.MediaActivity
import com.simplemobiletools.gallery.pro.extensions.*
import com.simplemobiletools.gallery.pro.models.Widget
class MyWidgetProvider : AppWidgetProvider() {
private fun setupAppOpenIntent(context: Context, views: RemoteViews, id: Int, widget: Widget) {
val intent = Intent(context, MediaActivity::class.java).apply {
putExtra(DIRECTORY, widget.folderPath)
}
val pendingIntent = PendingIntent.getActivity(context, widget.widgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT)
views.setOnClickPendingIntent(id, pendingIntent)
}
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
Thread {
val config = context.config
context.widgetsDB.getWidgets().filter { appWidgetIds.contains(it.widgetId) }.forEach {
val views = RemoteViews(context.packageName, R.layout.widget).apply {
setBackgroundColor(R.id.widget_holder, config.widgetBgColor)
setVisibleIf(R.id.widget_folder_name, config.showWidgetFolderName)
setTextColor(R.id.widget_folder_name, config.widgetTextColor)
setText(R.id.widget_folder_name, context.getFolderNameFromPath(it.folderPath))
}
val path = context.directoryDB.getDirectoryThumbnail(it.folderPath) ?: return@forEach
val options = RequestOptions()
.signature(path.getFileSignature())
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
if (context.config.cropThumbnails) options.centerCrop() else options.fitCenter()
val density = context.resources.displayMetrics.density
val appWidgetOptions = appWidgetManager.getAppWidgetOptions(appWidgetIds.first())
val width = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val height = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
val widgetSize = (Math.max(width, height) * density).toInt()
try {
val image = Glide.with(context)
.asBitmap()
.load(path)
.apply(options)
.submit(widgetSize, widgetSize)
.get()
views.setImageViewBitmap(R.id.widget_imageview, image)
} catch (e: Exception) {
}
setupAppOpenIntent(context, views, R.id.widget_holder, it)
appWidgetManager.updateAppWidget(it.widgetId, views)
}
}.start()
}
override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
onUpdate(context, appWidgetManager, intArrayOf(appWidgetId))
}
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
Thread {
appWidgetIds.forEach {
context.widgetsDB.deleteWidgetId(it)
}
}.start()
}
}

View file

@ -29,4 +29,7 @@ interface DirectoryDao {
@Query("DELETE FROM directories WHERE path = \'$RECYCLE_BIN\' COLLATE NOCASE") @Query("DELETE FROM directories WHERE path = \'$RECYCLE_BIN\' COLLATE NOCASE")
fun deleteRecycleBin() fun deleteRecycleBin()
@Query("SELECT thumbnail FROM directories WHERE path = :path")
fun getDirectoryThumbnail(path: String): String?
} }

View file

@ -0,0 +1,19 @@
package com.simplemobiletools.gallery.pro.interfaces
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.simplemobiletools.gallery.pro.models.Widget
@Dao
interface WidgetsDao {
@Query("SELECT * FROM widgets")
fun getWidgets(): List<Widget>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertOrUpdate(widget: Widget): Long
@Query("DELETE FROM widgets WHERE widget_id = :widgetId")
fun deleteWidgetId(widgetId: Int)
}

View file

@ -1,9 +1,6 @@
package com.simplemobiletools.gallery.pro.models package com.simplemobiletools.gallery.pro.models
import androidx.room.ColumnInfo import androidx.room.*
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import com.simplemobiletools.commons.extensions.formatDate import com.simplemobiletools.commons.extensions.formatDate
import com.simplemobiletools.commons.extensions.formatSize import com.simplemobiletools.commons.extensions.formatSize
import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED import com.simplemobiletools.commons.helpers.SORT_BY_DATE_MODIFIED
@ -12,7 +9,6 @@ import com.simplemobiletools.commons.helpers.SORT_BY_PATH
import com.simplemobiletools.commons.helpers.SORT_BY_SIZE import com.simplemobiletools.commons.helpers.SORT_BY_SIZE
import com.simplemobiletools.gallery.pro.helpers.FAVORITES import com.simplemobiletools.gallery.pro.helpers.FAVORITES
import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN
import java.io.Serializable
@Entity(tableName = "directories", indices = [Index(value = ["path"], unique = true)]) @Entity(tableName = "directories", indices = [Index(value = ["path"], unique = true)])
data class Directory( data class Directory(
@ -24,12 +20,14 @@ data class Directory(
@ColumnInfo(name = "last_modified") var modified: Long, @ColumnInfo(name = "last_modified") var modified: Long,
@ColumnInfo(name = "date_taken") var taken: Long, @ColumnInfo(name = "date_taken") var taken: Long,
@ColumnInfo(name = "size") var size: Long, @ColumnInfo(name = "size") var size: Long,
@ColumnInfo(name = "location") val location: Int, @ColumnInfo(name = "location") var location: Int,
@ColumnInfo(name = "media_types") var types: Int) : Serializable { @ColumnInfo(name = "media_types") var types: Int,
companion object { // used with "Group direct subfolders" enabled
private const val serialVersionUID = -6553345863555455L @Ignore var subfoldersCount: Int = 0,
} @Ignore var subfoldersMediaCount: Int = 0) {
constructor() : this(null, "", "", "", 0, 0L, 0L, 0L, 0, 0, 0, 0)
fun getBubbleText(sorting: Int) = when { fun getBubbleText(sorting: Int) = when {
sorting and SORT_BY_NAME != 0 -> name sorting and SORT_BY_NAME != 0 -> name

View file

@ -0,0 +1,12 @@
package com.simplemobiletools.gallery.pro.models
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
@Entity(tableName = "widgets", indices = [(Index(value = ["widget_id"], unique = true))])
data class Widget(
@PrimaryKey(autoGenerate = true) var id: Int?,
@ColumnInfo(name = "widget_id") var widgetId: Int,
@ColumnInfo(name = "folder_path") var folderPath: String)

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View file

@ -0,0 +1,135 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/config_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_margin="@dimen/activity_margin">
<RelativeLayout
android:id="@+id/folder_picker_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_margin">
<RelativeLayout
android:id="@+id/folder_picker_show_folder_name_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/medium_margin"
android:paddingBottom="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MySwitchCompat
android:id="@+id/folder_picker_show_folder_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:text="@string/show_folder_name"
app:switchPadding="@dimen/medium_margin"/>
</RelativeLayout>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/folder_picker_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/folder_picker_show_folder_name_holder"
android:layout_marginTop="@dimen/small_margin"
android:layout_marginBottom="@dimen/normal_margin"
android:paddingLeft="@dimen/activity_margin"
android:text="@string/folder_on_widget"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/folder_picker_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/folder_picker_label"
android:layout_marginLeft="@dimen/activity_margin"
android:background="@drawable/button_background"
android:padding="@dimen/normal_margin"
tools:text="@string/internal"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/config_image_holder"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_below="@+id/folder_picker_holder">
<com.simplemobiletools.gallery.pro.views.MySquareImageView
android:id="@+id/config_image"
android:layout_width="@dimen/widget_initial_size"
android:layout_height="@dimen/widget_initial_size"
android:layout_centerHorizontal="true"
android:layout_marginLeft="@dimen/normal_margin"
android:layout_marginTop="@dimen/normal_margin"
android:layout_marginRight="@dimen/normal_margin"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/config_folder_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/config_image"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:padding="@dimen/tiny_margin"
android:textSize="@dimen/bigger_text_size"
tools:text="@string/internal"/>
</RelativeLayout>
<ImageView
android:id="@+id/config_bg_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"
android:layout_above="@+id/config_save"/>
<RelativeLayout
android:id="@+id/config_bg_seekbar_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="@+id/config_bg_color"
android:layout_alignBottom="@+id/config_bg_color"
android:layout_toEndOf="@+id/config_bg_color"
android:layout_toRightOf="@+id/config_bg_color"
android:background="@android:color/white">
<SeekBar
android:id="@+id/config_bg_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"/>
</RelativeLayout>
<ImageView
android:id="@+id/config_text_color"
android:layout_width="@dimen/widget_colorpicker_size"
android:layout_height="@dimen/widget_colorpicker_size"
android:layout_alignParentBottom="true"/>
<Button
android:id="@+id/config_save"
android:layout_width="wrap_content"
android:layout_height="@dimen/widget_colorpicker_size"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:fontFamily="sans-serif-light"
android:paddingLeft="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin"
android:text="@string/ok"
android:textColor="@android:color/white"
android:textSize="@dimen/big_text_size"/>
</RelativeLayout>

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/change_view_type_dialog_scrollview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/change_view_type_dialog_holder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin">
<RadioGroup
android:id="@+id/change_view_type_dialog_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/medium_margin">
<com.simplemobiletools.commons.views.MyCompatRadioButton
android:id="@+id/change_view_type_dialog_radio_grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin"
android:text="@string/grid"/>
<com.simplemobiletools.commons.views.MyCompatRadioButton
android:id="@+id/change_view_type_dialog_radio_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin"
android:text="@string/list"/>
</RadioGroup>
<include
android:id="@+id/group_direct_subfolders_divider"
layout="@layout/divider"/>
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
android:id="@+id/change_view_type_dialog_group_direct_subfolders"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/group_direct_subfolders"/>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/aspect_ratio_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_margin"
android:paddingTop="@dimen/activity_margin"
android:paddingRight="@dimen/activity_margin">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/aspect_ratio_width_label"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="@string/width"/>
<com.simplemobiletools.commons.views.MyEditText
android:id="@+id/aspect_ratio_width"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@+id/aspect_ratio_width_label"
android:layout_marginBottom="@dimen/activity_margin"
android:inputType="number"
android:maxLength="6"
android:maxLines="1"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/aspect_ratio_colon_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/aspect_ratio_width"
android:layout_alignBottom="@+id/aspect_ratio_width"
android:layout_toLeftOf="@+id/aspect_ratio_height"
android:layout_toRightOf="@+id/aspect_ratio_width"
android:gravity="center"
android:text=":"
android:textStyle="bold"/>
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/aspect_ratio_height_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginLeft="50dp"
android:layout_toRightOf="@+id/aspect_ratio_width_label"
android:text="@string/height"/>
<com.simplemobiletools.commons.views.MyEditText
android:id="@+id/aspect_ratio_height"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@+id/aspect_ratio_width_label"
android:layout_alignStart="@+id/aspect_ratio_height_label"
android:layout_alignLeft="@+id/aspect_ratio_height_label"
android:inputType="number"
android:maxLength="6"
android:maxLines="1"
android:textCursorDrawable="@null"
android:textSize="@dimen/normal_text_size"/>
</RelativeLayout>

View file

@ -84,6 +84,16 @@
android:text="19:9" android:text="19:9"
android:textSize="@dimen/bigger_text_size"/> android:textSize="@dimen/bigger_text_size"/>
<com.simplemobiletools.commons.views.MyCompatRadioButton
android:id="@+id/other_aspect_ratio_custom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/small_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin"
android:text="@string/custom"
android:textSize="@dimen/bigger_text_size"/>
</RadioGroup> </RadioGroup>
<RadioGroup <RadioGroup

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rename_directory_holder" android:id="@+id/resize_image_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/widget_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/widget_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/widget_folder_name"
android:layout_centerInParent="true"
android:paddingLeft="@dimen/tiny_margin"
android:paddingTop="@dimen/tiny_margin"
android:paddingRight="@dimen/tiny_margin"
tools:src="@mipmap/ic_launcher"/>
<TextView
android:id="@+id/widget_folder_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:padding="@dimen/tiny_margin"
android:textSize="@dimen/bigger_text_size"
tools:text="@string/internal"/>
</RelativeLayout>

View file

@ -136,6 +136,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">تشغيل الفديوهات تلقائيا</string> <string name="autoplay_videos">تشغيل الفديوهات تلقائيا</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Play videos automatically</string> <string name="autoplay_videos">Play videos automatically</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">Verticalment</string> <string name="flip_vertically">Verticalment</string>
<string name="edit_with">Editar amb</string> <string name="edit_with">Editar amb</string>
<string name="free_aspect_ratio">Lliure</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">Lliure</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">Altres</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">Fons de pantalla de Simple Gallery</string> <string name="simple_wallpaper">Fons de pantalla de Simple Gallery</string>
@ -132,6 +132,10 @@
<string name="by_file_type">Tipus de fitxer</string> <string name="by_file_type">Tipus de fitxer</string>
<string name="by_extension">Extensió</string> <string name="by_extension">Extensió</string>
<!-- Widgets -->
<string name="folder_on_widget">Carpeta que es mostra a l\'estri:</string>
<string name="show_folder_name">Mostra el nom de la carpeta</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Reproduir vídeos automàticament</string> <string name="autoplay_videos">Reproduir vídeos automàticament</string>
<string name="remember_last_video_position">Recordeu la posició de la darrera reproducció de vídeo</string> <string name="remember_last_video_position">Recordeu la posició de la darrera reproducció de vídeo</string>
@ -140,7 +144,7 @@
<string name="animate_gifs">Animar les miniatures dels GIFs</string> <string name="animate_gifs">Animar les miniatures dels GIFs</string>
<string name="max_brightness">Brillantor màxima quan es mostra multimèdia</string> <string name="max_brightness">Brillantor màxima quan es mostra multimèdia</string>
<string name="crop_thumbnails">Retallar miniatures en quadrats</string> <string name="crop_thumbnails">Retallar miniatures en quadrats</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">Mostra les durades del vídeo</string>
<string name="screen_rotation_by">Gira els mitjans a pantalla completa segons</string> <string name="screen_rotation_by">Gira els mitjans a pantalla completa segons</string>
<string name="screen_rotation_system_setting">Configuració del sistema</string> <string name="screen_rotation_system_setting">Configuració del sistema</string>
<string name="screen_rotation_device_rotation">Rotació del dispositiu</string> <string name="screen_rotation_device_rotation">Rotació del dispositiu</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Typu souboru</string> <string name="by_file_type">Typu souboru</string>
<string name="by_extension">Přípony</string> <string name="by_extension">Přípony</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Automaticky přehrávat videa</string> <string name="autoplay_videos">Automaticky přehrávat videa</string>
<string name="remember_last_video_position">Zapamatovat pozici posledního přehraného videa</string> <string name="remember_last_video_position">Zapamatovat pozici posledního přehraného videa</string>

View file

@ -6,9 +6,9 @@
<string name="open_camera">Åbn kamera</string> <string name="open_camera">Åbn kamera</string>
<string name="hidden">(skjult)</string> <string name="hidden">(skjult)</string>
<string name="excluded">(ekskluderet)</string> <string name="excluded">(ekskluderet)</string>
<string name="pin_folder">Pin folder</string> <string name="pin_folder">Fastgør mappe</string>
<string name="unpin_folder">Unpin folder</string> <string name="unpin_folder">Fjern fastgørelse af mappe</string>
<string name="pin_to_the_top">Pin to the top</string> <string name="pin_to_the_top">Fastgør til toppen</string>
<string name="show_all">Vis indholdet af alle mapper</string> <string name="show_all">Vis indholdet af alle mapper</string>
<string name="all_folders">Alle mapper</string> <string name="all_folders">Alle mapper</string>
<string name="folder_view">Skift til mappevisning</string> <string name="folder_view">Skift til mappevisning</string>
@ -17,19 +17,19 @@
<string name="unknown_location">Ukendt placering</string> <string name="unknown_location">Ukendt placering</string>
<string name="increase_column_count">Flere kolonner</string> <string name="increase_column_count">Flere kolonner</string>
<string name="reduce_column_count">Færre kolonner</string> <string name="reduce_column_count">Færre kolonner</string>
<string name="change_cover_image">Change cover image</string> <string name="change_cover_image">Skift cover billede</string>
<string name="select_photo">Select photo</string> <string name="select_photo">Vælg billede</string>
<string name="use_default">Use default</string> <string name="use_default">Brug standard</string>
<string name="volume">Volume</string> <string name="volume">Lydstyrke</string>
<string name="brightness">Brightness</string> <string name="brightness">Lysstyrke</string>
<string name="lock_orientation">Lås orientering</string> <string name="lock_orientation">Lås orientering</string>
<string name="unlock_orientation">Lås orientering op</string> <string name="unlock_orientation">Lås orientering op</string>
<string name="change_orientation">Change orientation</string> <string name="change_orientation">Skift orientering</string>
<string name="force_portrait">Force portrait</string> <string name="force_portrait">Tving portræt</string>
<string name="force_landscape">Force landscape</string> <string name="force_landscape">Tving landskab</string>
<string name="use_default_orientation">Use default orientation</string> <string name="use_default_orientation">Brug standard orientering</string>
<string name="fix_date_taken">Fix Date Taken value</string> <string name="fix_date_taken">Fiks Dato Taget værdi</string>
<string name="fixing">Fixing</string> <string name="fixing">Fikser</string>
<string name="dates_fixed_successfully">Dates fixed successfully</string> <string name="dates_fixed_successfully">Dates fixed successfully</string>
<!-- Filter --> <!-- Filter -->
@ -63,17 +63,17 @@
<string name="included_activity_placeholder">Hvis du har mapper med mediefiler som appen ikke har fundet, kan du manuelt tilføje dem her.\n\nDet vil ikke ekskludere andre mapper.</string> <string name="included_activity_placeholder">Hvis du har mapper med mediefiler som appen ikke har fundet, kan du manuelt tilføje dem her.\n\nDet vil ikke ekskludere andre mapper.</string>
<!-- Resizing --> <!-- Resizing -->
<string name="resize">Skaler</string> <string name="resize">Skalér</string>
<string name="resize_and_save">Resize selection and save</string> <string name="resize_and_save">Skalér valgte elementer og gem</string>
<string name="width">Width</string> <string name="width">Bredde</string>
<string name="height">Height</string> <string name="height">Højde</string>
<string name="keep_aspect_ratio">Keep aspect ratio</string> <string name="keep_aspect_ratio">Bevar billedeforhold</string>
<string name="invalid_values">Please enter a valid resolution</string> <string name="invalid_values">Indtast en gyldig opløsning</string>
<!-- Editor --> <!-- Editor -->
<string name="editor">Editor</string> <string name="editor">Editor</string>
<string name="save">Gem</string> <string name="save">Gem</string>
<string name="rotate">Roter</string> <string name="rotate">Rotér</string>
<string name="path">Sti</string> <string name="path">Sti</string>
<string name="invalid_image_path">Ugyldig sti til billede</string> <string name="invalid_image_path">Ugyldig sti til billede</string>
<string name="image_editing_failed">Redigering af billede mislykkedes</string> <string name="image_editing_failed">Redigering af billede mislykkedes</string>
@ -81,9 +81,9 @@
<string name="no_editor_found">Der blev ikke fundet en editor til billedbehandling</string> <string name="no_editor_found">Der blev ikke fundet en editor til billedbehandling</string>
<string name="unknown_file_location">Ukendt filplacering</string> <string name="unknown_file_location">Ukendt filplacering</string>
<string name="error_saving_file">Kunne ikke overskrive kildefilen</string> <string name="error_saving_file">Kunne ikke overskrive kildefilen</string>
<string name="rotate_left">Roter mod venstre</string> <string name="rotate_left">Rotér mod venstre</string>
<string name="rotate_right">Roter mod højre</string> <string name="rotate_right">Rotér mod højre</string>
<string name="rotate_one_eighty">Roter 180º</string> <string name="rotate_one_eighty">Rotér 180º</string>
<string name="flip">Spejlvend</string> <string name="flip">Spejlvend</string>
<string name="flip_horizontally">Spejlvend vandret</string> <string name="flip_horizontally">Spejlvend vandret</string>
<string name="flip_vertically">Spejlvend lodret</string> <string name="flip_vertically">Spejlvend lodret</string>
@ -121,27 +121,31 @@
<string name="change_view_type">Skift visning</string> <string name="change_view_type">Skift visning</string>
<string name="grid">Gitter</string> <string name="grid">Gitter</string>
<string name="list">Liste</string> <string name="list">Liste</string>
<string name="group_direct_subfolders">Group direct subfolders</string> <string name="group_direct_subfolders">Gruppér direkte undermapper</string>
<!-- Grouping at media thumbnails --> <!-- Grouping at media thumbnails -->
<string name="group_by">Group by</string> <string name="group_by">Gruppér efter</string>
<string name="do_not_group_files">Do not group files</string> <string name="do_not_group_files">Gruppér ikke filer</string>
<string name="by_folder">Folder</string> <string name="by_folder">Mappe</string>
<string name="by_last_modified">Last modified</string> <string name="by_last_modified">Sidst ændret</string>
<string name="by_date_taken">Date taken</string> <string name="by_date_taken">Dato taget</string>
<string name="by_file_type">File type</string> <string name="by_file_type">Filtype</string>
<string name="by_extension">Extension</string> <string name="by_extension">Filudvidelse</string>
<!-- Widgets -->
<string name="folder_on_widget">Mappe vist på widget:</string>
<string name="show_folder_name">Vis mappenavn</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Afspil automatisk videoer</string> <string name="autoplay_videos">Afspil automatisk videoer</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Husk sidste position ved videoafspilning</string>
<string name="toggle_filename">Toggle filename visibility</string> <string name="toggle_filename">Skift filnavnets synlighed</string>
<string name="loop_videos">Kør videoer i sløjfe</string> <string name="loop_videos">Kør videoer i sløjfe</string>
<string name="animate_gifs">Animér GIF\'er i miniaturer</string> <string name="animate_gifs">Animér GIF\'er i miniaturer</string>
<string name="max_brightness">Maksimal lysstyrke ved fuldskærmsvisning af medier</string> <string name="max_brightness">Maksimal lysstyrke ved fuldskærmsvisning af medier</string>
<string name="crop_thumbnails">Beskær miniaturer til kvadrater</string> <string name="crop_thumbnails">Beskær miniaturer til kvadrater</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">Vis varighed på video</string>
<string name="screen_rotation_by">Roter fuldskærmsmedier efter</string> <string name="screen_rotation_by">Rotér fuldskærmsmedier efter</string>
<string name="screen_rotation_system_setting">Systemindstilling</string> <string name="screen_rotation_system_setting">Systemindstilling</string>
<string name="screen_rotation_device_rotation">Enhedens orientering</string> <string name="screen_rotation_device_rotation">Enhedens orientering</string>
<string name="screen_rotation_aspect_ratio">Billedformat</string> <string name="screen_rotation_aspect_ratio">Billedformat</string>
@ -150,33 +154,33 @@
<string name="hide_system_ui_at_fullscreen">Skjul automatisk systemets brugerflade ved fuldskærmsvisning af medier</string> <string name="hide_system_ui_at_fullscreen">Skjul automatisk systemets brugerflade ved fuldskærmsvisning af medier</string>
<string name="delete_empty_folders">Slet tomme mapper efter sletning af deres indhold</string> <string name="delete_empty_folders">Slet tomme mapper efter sletning af deres indhold</string>
<string name="allow_photo_gestures">Tillad kontrol af lysstyrke på billeder med lodrette bevægelser</string> <string name="allow_photo_gestures">Tillad kontrol af lysstyrke på billeder med lodrette bevægelser</string>
<string name="allow_video_gestures">Tillad kontrol af videolyd og lysstyrke med lodrette bevægelser</string> <string name="allow_video_gestures">Tillad kontrol af lyd- og lysstyrke på videoer med lodrette bevægelser</string>
<string name="show_media_count">Vis antal filer i hver mappe i oversigten</string> <string name="show_media_count">Vis antal filer i hver mappe i oversigten</string>
<string name="replace_share_with_rotate">Erstat Del med Roter i fuldskærmsmenuen</string> <string name="replace_share_with_rotate">Erstat Del med Rotér i fuldskærmsmenuen</string>
<string name="show_extended_details">Vis udvidede oplysninger over medier i fuldskærm</string> <string name="show_extended_details">Vis udvidede oplysninger over medier i fuldskærm</string>
<string name="manage_extended_details">Manage extended details</string> <string name="manage_extended_details">Administrer udvidede oplysninger</string>
<string name="one_finger_zoom">Tillad zoom med en finger når medier er i fuldskærm</string> <string name="one_finger_zoom">Tillad zoom med en finger når medier er i fuldskærm</string>
<string name="allow_instant_change">Tillad skift af medie ved klik på skærmens sider</string> <string name="allow_instant_change">Tillad skift af medie ved klik på skærmens sider</string>
<string name="allow_deep_zooming_images">Allow deep zooming images</string> <string name="allow_deep_zooming_images">Allow deep zooming images</string>
<string name="hide_extended_details">Skjul udvidede oplysninger når statuslinjen er skjult</string> <string name="hide_extended_details">Skjul udvidede oplysninger når statuslinjen er skjult</string>
<string name="do_extra_check">Tjek en ekstra gang for at undgå visning af ugyldige filer</string> <string name="do_extra_check">Tjek en ekstra gang for at undgå visning af ugyldige filer</string>
<string name="show_at_bottom">Show some action buttons at the bottom of the screen</string> <string name="show_at_bottom">Vis handlingsknapper i bunden af skærmen</string>
<string name="show_recycle_bin">Show the Recycle Bin at the folders screen</string> <string name="show_recycle_bin">Vis papirkurven ved mappevisning</string>
<string name="deep_zoomable_images">Deep zoomable images</string> <string name="deep_zoomable_images">Deep zoomable images</string>
<string name="show_highest_quality">Show images in the highest possible quality</string> <string name="show_highest_quality">Vis billeder i den højst mulige kvalitet</string>
<string name="show_recycle_bin_last">Show the Recycle Bin as the last item on the main screen</string> <string name="show_recycle_bin_last">Vis papirkurven som sidste element på hovedskærmen</string>
<string name="allow_down_gesture">Allow closing the fullscreen view with a down gesture</string> <string name="allow_down_gesture">Allow closing the fullscreen view with a down gesture</string>
<!-- Setting sections --> <!-- Setting sections -->
<string name="thumbnails">Thumbnails</string> <string name="thumbnails">Miniaturer</string>
<string name="fullscreen_media">Fullscreen media</string> <string name="fullscreen_media">Fuldskærmsmedier</string>
<string name="extended_details">Flere oplysninger</string> <string name="extended_details">Flere oplysninger</string>
<string name="bottom_actions">Bottom actions</string> <string name="bottom_actions">Handlingsknapper</string>
<!-- Bottom actions --> <!-- Bottom actions -->
<string name="manage_bottom_actions">Manage visible bottom actions</string> <string name="manage_bottom_actions">Administrer synlige handlingsknapper</string>
<string name="toggle_favorite">Toggle favorite</string> <string name="toggle_favorite">Favorit</string>
<string name="toggle_file_visibility">Toggle file visibility</string> <string name="toggle_file_visibility">Synlighed</string>
<!-- FAQ --> <!-- FAQ -->
<string name="faq_1_title">How can I make Simple Gallery the default device gallery?</string> <string name="faq_1_title">How can I make Simple Gallery the default device gallery?</string>
@ -212,7 +216,7 @@
<!-- Strings displayed only on Google Playstore. Optional, but good to have --> <!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars --> <!-- Short description has to have less than 80 chars -->
<string name="app_short_description">A gallery for viewing photos and videos without ads.</string> <string name="app_short_description">Et galleri til visning af billeder og videoer uden reklamer.</string>
<string name="app_long_description"> <string name="app_long_description">
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos. A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">Vertikal spiegeln</string> <string name="flip_vertically">Vertikal spiegeln</string>
<string name="edit_with">Bearbeiten mit:</string> <string name="edit_with">Bearbeiten mit:</string>
<string name="free_aspect_ratio">Beliebiges</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">Beliebiges</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">Anderes</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">Schlichter Hintergrund</string> <string name="simple_wallpaper">Schlichter Hintergrund</string>
@ -132,6 +132,10 @@
<string name="by_file_type">Dateityp (Bilder/Videos)</string> <string name="by_file_type">Dateityp (Bilder/Videos)</string>
<string name="by_extension">Dateierweiterung</string> <string name="by_extension">Dateierweiterung</string>
<!-- Widgets -->
<string name="folder_on_widget">Ordner, der auf dem Widget angezeigt wird:</string>
<string name="show_folder_name">Ordnernamen anzeigen</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Videos automatisch abspielen</string> <string name="autoplay_videos">Videos automatisch abspielen</string>
<string name="remember_last_video_position">Letzte Videowiedergabeposition erinnern</string> <string name="remember_last_video_position">Letzte Videowiedergabeposition erinnern</string>
@ -140,7 +144,7 @@
<string name="animate_gifs">Kacheln von GIFs animieren</string> <string name="animate_gifs">Kacheln von GIFs animieren</string>
<string name="max_brightness">Helligkeit beim Betrachten maximieren</string> <string name="max_brightness">Helligkeit beim Betrachten maximieren</string>
<string name="crop_thumbnails">Kacheln quadratisch zuschneiden</string> <string name="crop_thumbnails">Kacheln quadratisch zuschneiden</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">Videodauer anzeigen</string>
<string name="screen_rotation_by">Im Vollbild ausrichten nach:</string> <string name="screen_rotation_by">Im Vollbild ausrichten nach:</string>
<string name="screen_rotation_system_setting">Systemeinstellung</string> <string name="screen_rotation_system_setting">Systemeinstellung</string>
<string name="screen_rotation_device_rotation">Gerätedrehung</string> <string name="screen_rotation_device_rotation">Gerätedrehung</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Τύπο αρχείου</string> <string name="by_file_type">Τύπο αρχείου</string>
<string name="by_extension">Επέκταση</string> <string name="by_extension">Επέκταση</string>
<!-- Widgets -->
<string name="folder_on_widget">Εμφάνιση φακέλου στο widget:</string>
<string name="show_folder_name">Εμφάνιση ονόματος φακέλου</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Αυτόματη αναπαραγωγή βίντεο</string> <string name="autoplay_videos">Αυτόματη αναπαραγωγή βίντεο</string>
<string name="remember_last_video_position">Απομνημόνευση της τελευταίας θέσης αναπαραγωγής βίντεο</string> <string name="remember_last_video_position">Απομνημόνευση της τελευταίας θέσης αναπαραγωγής βίντεο</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">Verticalmente</string> <string name="flip_vertically">Verticalmente</string>
<string name="edit_with">Editar con</string> <string name="edit_with">Editar con</string>
<string name="free_aspect_ratio">Libre</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">Libre</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">Otros</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">Fondos de pantalla Simple Gallery</string> <string name="simple_wallpaper">Fondos de pantalla Simple Gallery</string>
@ -132,6 +132,10 @@
<string name="by_file_type">Tipo de fichero</string> <string name="by_file_type">Tipo de fichero</string>
<string name="by_extension">Extensión</string> <string name="by_extension">Extensión</string>
<!-- Widgets -->
<string name="folder_on_widget">Carpeta mostrada en el widget:</string>
<string name="show_folder_name">Mostrar nombre de carpeta</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Reproducir vídeos automáticamente</string> <string name="autoplay_videos">Reproducir vídeos automáticamente</string>
<string name="remember_last_video_position">Recuerde la última posición de reproducción de video</string> <string name="remember_last_video_position">Recuerde la última posición de reproducción de video</string>
@ -140,7 +144,7 @@
<string name="animate_gifs">Animar las miniaturas de GIFs</string> <string name="animate_gifs">Animar las miniaturas de GIFs</string>
<string name="max_brightness">Brillo máximo cuando se muestra multimedia</string> <string name="max_brightness">Brillo máximo cuando se muestra multimedia</string>
<string name="crop_thumbnails">Recortar miniaturas en cuadrados</string> <string name="crop_thumbnails">Recortar miniaturas en cuadrados</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">Mostrar duración del video</string>
<string name="screen_rotation_by">Rotar multimedia en pantalla completa según</string> <string name="screen_rotation_by">Rotar multimedia en pantalla completa según</string>
<string name="screen_rotation_system_setting">Configuración del sistema</string> <string name="screen_rotation_system_setting">Configuración del sistema</string>
<string name="screen_rotation_device_rotation">Rotación del dispositivo</string> <string name="screen_rotation_device_rotation">Rotación del dispositivo</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Toista videot automaattisesti</string> <string name="autoplay_videos">Toista videot automaattisesti</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<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>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Lecture automatique des vidéos</string> <string name="autoplay_videos">Lecture automatique des vidéos</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Tipo de ficheior</string> <string name="by_file_type">Tipo de ficheior</string>
<string name="by_extension">Extensión</string> <string name="by_extension">Extensión</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Reproducir vídeos automticamente</string> <string name="autoplay_videos">Reproducir vídeos automticamente</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Tip datoteke</string> <string name="by_file_type">Tip datoteke</string>
<string name="by_extension">Vrsta datoteke</string> <string name="by_extension">Vrsta datoteke</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Automatsko pokretanje videa</string> <string name="autoplay_videos">Automatsko pokretanje videa</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -133,6 +133,10 @@
<string name="by_file_type">Fájl típus</string> <string name="by_file_type">Fájl típus</string>
<string name="by_extension">Kiterjesztés</string> <string name="by_extension">Kiterjesztés</string>
<!-- Widgets -->
<string name="folder_on_widget">Mappa mutatása a widgeten:</string>
<string name="show_folder_name">Mutassa a mappa nevét</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Automatikus videó lejátszás</string> <string name="autoplay_videos">Automatikus videó lejátszás</string>
<string name="remember_last_video_position">Emlékezzen a videó utolsó lejátszási pozícióra</string> <string name="remember_last_video_position">Emlékezzen a videó utolsó lejátszási pozícióra</string>

View file

@ -0,0 +1,252 @@
<?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">Edit</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 landscape</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>
<!-- 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 file 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 file \'.nomedia\' ke dalamnya, juga akan menyembunyikan semua subfolder. Anda bisa melihatnya dari opsi \'Tampilkan file tersembunyi\' di Setelan. 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 Setelan.</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 file \".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 file 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>
<!-- 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">Editor</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 mengedit gambar</string>
<string name="edit_image_with">Edit dengan:</string>
<string name="no_editor_found">Tidak ada aplikasi editor gambar</string>
<string name="unknown_file_location">Lokasi file tidak diketahui</string>
<string name="error_saving_file">Tidak dapat mengganti file 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="edit_with">Edit dengan</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 landscape</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="use_fade">Animasi memudar</string>
<string name="move_backwards">Mundur</string>
<string name="loop_slideshow">Slideshow tanpa henti</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 langsung subfolder</string>
<!-- Grouping at media thumbnails -->
<string name="group_by">Kelompokkan menurut</string>
<string name="do_not_group_files">Jangan kelompokkan file</string>
<string name="by_folder">Folder</string>
<string name="by_last_modified">Terakhir diubah</string>
<string name="by_date_taken">Tanggal diambil</string>
<string name="by_file_type">Jenis file</string>
<string name="by_extension">Ekstensi</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</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 file</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="replace_share_with_rotate">Ganti tombol Bagikan dengan Rotasi di menu layar penuh</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="do_extra_check">Lakukan pemeriksaan ulang untuk menghindari file yang tidak valid</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>
<!-- 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 di 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 file</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 Setelan 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, dimana Anda bisa memilih Simple Gallery dan menjadikannya default.</string>
<string name="faq_2_title">Saya mengunci aplikasi dengan password, tapi saya lupa. Apa yang harus dilakukan?</string>
<string name="faq_2_text">Anda bisa menyelesaikannya dengan 2 cara. Anda bisa instal ulang aplikasi, atau cari aplikasi ini di Setelan perangkat dan pilih \"Hapus data\". Ini akan menyetel ulang semua setelan Anda, dan tidak akan menghapus file 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">Anda bisa mengklik teks durasi saat ini/maksimal di dekat penggeser durasi, itu akan memajukan atau memundurkan video.</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 file \".nomedia\" kosong pada folder yang diinginkan, yang bisa Anda hapus juga dengan aplikasi file manager.</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 Setelan -> 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 Setelan -> Atur Folder yang Dikecualikan, lalu kecualikan folder root \"/\", lalu tambahkan folder yang diinginkan di Setelan -> 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_9_title">Gambar layar penuh terlihat pecah, bisakah ditingkatkan kualitasnya?</string>
<string name="faq_9_text">Ya, ada opsi di Setelan \"Ganti zoom mendalam dengan kualitas gambar yang lebih bagus\", Anda bisa menggunakannya. Ini akan meningkatkan kualitas gambar, namun gambar akan terlihat kabur jika Anda zoom terlalu banyak.</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 Editor, dengan menyeret sudut gambar. Anda bisa masuk ke editor dengan menekan lama thumbnail gambar dan memilih Edit, atau pilih Edit dari tampilan layar penuh.</string>
<string name="faq_11_title">Bisakah saya mengelompokkan thumbnail file media?</string>
<string name="faq_11_text">Bisa, gunakan menu \"Kelompokkan menurut\" pada tampilan thumbnail. Anda bisa mengelompokkan file 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 dapat mengurutkan berdasarkan Tanggal Diambil, bagaimana cara memperbaikinya?</string>
<string name="faq_12_text">Itu umumnya disebabkan karena file yang disalin dari tempat lain. Anda bisa memperbaikinya dengan memilih thumbnail file 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 setelan aplikasi, pada bagian \"Zoom gambar mendalam\".</string>
<string name="faq_14_title">Saya punya file/folder tersembunyi. Bagaimana cara memunculkannya?</string>
<string name="faq_14_text">Anda bisa memilih menu \"Tampilkan sementara file tersembunyi\" di layar utama, atau \"Tampilkan file tersembunyi\" di setelan aplikasi untuk menampilkannya. Jika Anda tidak ingin menyembunyikannya, tekan lama dan pilih \"Jangan sembunyikan\". Folder disembunyikan dengan menambahkan file \".nomedia\" di dalamnya, Anda bisa menghapus file tersebut dengan aplikasi file manager.</string>
<!-- Strings displayed only on Google Playstore. Optional, but good to have -->
<!-- Short description has to have less than 80 chars -->
<string name="app_short_description">Aplikasi galeri untuk melihat foto dan video tanpa iklan.</string>
<string name="app_long_description">
Aplikasi galeri dengan banyak kustomisasi dan mampu menampilkan banyak jenis gambar dan video termasuk SVG, RAW, panorama foto dan video.
Aplikasi ini open source, tidak berisi iklan atau izin yang tidak diperlukan.
Beberapa fiturnya antara lain:
1. Pencarian
2. Slideshow
3. Dukungan notch (layar berponi)
4. Pin folder di atas
5. Filter media berdasarkan jenis
6. Keranjang sampah untuk memulihkan file
7. Kunci orientasi layar penuh
8. Tandai file favorit agar mudah diakses
9. Keluar dari layar penuh dengan menggeser ke bawah
10. Editor bawaan untuk mengedit dan menambahkan filter
11. Perlindungan password untuk item tersembunyi atau mengunci aplikasi
12. Ubah jumlah kolom thumbnail lewat gerakan atau menu
13. Sesuaikan tombol tindakan di bawah layar penuh untuk akses cepat
14. Menampilkan detail tambahan di layar penuh dengan properti file yang diinginkan
15. Berbagai cara untuk mengurutkan atau mengelompokkan item, dengan naik atau turun
16. Sembunyikan folder (berpengaruh di aplikasi lain), kecualikan folder (hanya berpengaruh di Simple Gallery)
Izin sidik jari diperlukan untuk mengunci item tersembunyi, mengunci aplikasi, atau melindungi agar file tidak dihapus.
Aplikasi ini hanyalah bagian dari rangkaian aplikasi saya. Anda bisa menemukan aplikasi saya lainnya di https://www.simplemobiletools.com
</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

@ -132,6 +132,10 @@
<string name="by_file_type">Tipo di file</string> <string name="by_file_type">Tipo di file</string>
<string name="by_extension">Estensione</string> <string name="by_extension">Estensione</string>
<!-- Widgets -->
<string name="folder_on_widget">Cartella mostrata nel widget:</string>
<string name="show_folder_name">Mostra il nome della cartella</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Riproduci i video automaticamente</string> <string name="autoplay_videos">Riproduci i video automaticamente</string>
<string name="remember_last_video_position">Ricorda l\'ultimo stato di riproduzione dei video</string> <string name="remember_last_video_position">Ricorda l\'ultimo stato di riproduzione dei video</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">ファイル形式</string> <string name="by_file_type">ファイル形式</string>
<string name="by_extension">拡張子</string> <string name="by_extension">拡張子</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">ビデオを自動再生</string> <string name="autoplay_videos">ビデオを自動再生</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">비디오 자동재생</string> <string name="autoplay_videos">비디오 자동재생</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Groti vaizdo įrašus automatiškai</string> <string name="autoplay_videos">Groti vaizdo įrašus automatiškai</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<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>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Avspill videoer automatisk</string> <string name="autoplay_videos">Avspill videoer automatisk</string>
<string name="remember_last_video_position">Husk siste videoavspillingsposisjon</string> <string name="remember_last_video_position">Husk siste videoavspillingsposisjon</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Bestandstype</string> <string name="by_file_type">Bestandstype</string>
<string name="by_extension">Extensie</string> <string name="by_extension">Extensie</string>
<!-- Widgets -->
<string name="folder_on_widget">Map tonen in de widget:</string>
<string name="show_folder_name">Mapnaam tonen</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Video\'s automatisch afspelen</string> <string name="autoplay_videos">Video\'s automatisch afspelen</string>
<string name="remember_last_video_position">Laatste positie in video\'s onthouden</string> <string name="remember_last_video_position">Laatste positie in video\'s onthouden</string>
@ -160,7 +164,7 @@
<string name="allow_deep_zooming_images">Verder inzoomen mogelijk maken</string> <string name="allow_deep_zooming_images">Verder inzoomen mogelijk maken</string>
<string name="hide_extended_details">Uitgebreide informatie niet tonen als de statusbalk is verborgen</string> <string name="hide_extended_details">Uitgebreide informatie niet tonen als de statusbalk is verborgen</string>
<string name="do_extra_check">Ongeldige bestanden verbergen</string> <string name="do_extra_check">Ongeldige bestanden verbergen</string>
<string name="show_at_bottom">Enkele actieknoppen onderaan het scherm tonen</string> <string name="show_at_bottom">Enkele actieknoppen onder aan het scherm tonen</string>
<string name="show_recycle_bin">Prullenbak weergeven in de mapweergave</string> <string name="show_recycle_bin">Prullenbak weergeven in de mapweergave</string>
<string name="deep_zoomable_images">Afbeeldingen ver inzoomen</string> <string name="deep_zoomable_images">Afbeeldingen ver inzoomen</string>
<string name="show_highest_quality">Afbeeldingen in de hoogst mogelijke kwaliteit weergeven</string> <string name="show_highest_quality">Afbeeldingen in de hoogst mogelijke kwaliteit weergeven</string>
@ -171,7 +175,7 @@
<string name="thumbnails">Miniatuurvoorbeelden</string> <string name="thumbnails">Miniatuurvoorbeelden</string>
<string name="fullscreen_media">Volledig scherm</string> <string name="fullscreen_media">Volledig scherm</string>
<string name="extended_details">Uitgebreide informatie</string> <string name="extended_details">Uitgebreide informatie</string>
<string name="bottom_actions">Acties onderaan het scherm</string> <string name="bottom_actions">Acties onder aan het scherm</string>
<!-- Bottom actions --> <!-- Bottom actions -->
<string name="manage_bottom_actions">Actieknoppen onderaan beheren</string> <string name="manage_bottom_actions">Actieknoppen onderaan beheren</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Typu</string> <string name="by_file_type">Typu</string>
<string name="by_extension">Rozszerzenia</string> <string name="by_extension">Rozszerzenia</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Odtwarzaj filmy automatycznie</string> <string name="autoplay_videos">Odtwarzaj filmy automatycznie</string>
<string name="remember_last_video_position">Pamiętaj ostatni moment odtwarzania filmów</string> <string name="remember_last_video_position">Pamiętaj ostatni moment odtwarzania filmów</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Reproduzir vídeos automaticamente</string> <string name="autoplay_videos">Reproduzir vídeos automaticamente</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">Verticalmente</string> <string name="flip_vertically">Verticalmente</string>
<string name="edit_with">Editar com</string> <string name="edit_with">Editar com</string>
<string name="free_aspect_ratio">Livre</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">Other</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 Wallpaper</string>
@ -132,6 +132,10 @@
<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>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Reproduzir vídeos automaticamente</string> <string name="autoplay_videos">Reproduzir vídeos automaticamente</string>
<string name="remember_last_video_position">Memorizar posição da reprodução</string> <string name="remember_last_video_position">Memorizar posição da reprodução</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Тип файла</string> <string name="by_file_type">Тип файла</string>
<string name="by_extension">Расширение</string> <string name="by_extension">Расширение</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Воспроизводить видео автоматически</string> <string name="autoplay_videos">Воспроизводить видео автоматически</string>
<string name="remember_last_video_position">Запоминать позицию воспроизведения видео</string> <string name="remember_last_video_position">Запоминать позицию воспроизведения видео</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Typu súboru</string> <string name="by_file_type">Typu súboru</string>
<string name="by_extension">Prípony</string> <string name="by_extension">Prípony</string>
<!-- Widgets -->
<string name="folder_on_widget">Priečinok zobrazený vo widgete:</string>
<string name="show_folder_name">Zobraziť názov priečinka</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Spúšťať videá automaticky</string> <string name="autoplay_videos">Spúšťať videá automaticky</string>
<string name="remember_last_video_position">Zapamätať si pozíciu posledného prehraného videa</string> <string name="remember_last_video_position">Zapamätať si pozíciu posledného prehraného videa</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Tip datoteke</string> <string name="by_file_type">Tip datoteke</string>
<string name="by_extension">Končnica</string> <string name="by_extension">Končnica</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Avtomatično predvajaj videoposnetke</string> <string name="autoplay_videos">Avtomatično predvajaj videoposnetke</string>
<string name="remember_last_video_position">Zapomni si zadnji položaj predvajanja</string> <string name="remember_last_video_position">Zapomni si zadnji položaj predvajanja</string>

View file

@ -132,6 +132,10 @@
<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>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Spela upp videor automatiskt</string> <string name="autoplay_videos">Spela upp videor automatiskt</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -132,6 +132,10 @@
<string name="by_file_type">Dosya türü</string> <string name="by_file_type">Dosya türü</string>
<string name="by_extension">Uzantı</string> <string name="by_extension">Uzantı</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Videoları otomatik oynat</string> <string name="autoplay_videos">Videoları otomatik oynat</string>
<string name="remember_last_video_position">Son video oynatma konumunu hatırla</string> <string name="remember_last_video_position">Son video oynatma konumunu hatırla</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">Віддзеркалити вертикально</string> <string name="flip_vertically">Віддзеркалити вертикально</string>
<string name="edit_with">Редагувати за допомогою</string> <string name="edit_with">Редагувати за допомогою</string>
<string name="free_aspect_ratio">Вільне</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">Вільне</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">Інше</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 Wallpaper</string>
@ -132,6 +132,10 @@
<string name="by_file_type">типом файлу</string> <string name="by_file_type">типом файлу</string>
<string name="by_extension">розширенням</string> <string name="by_extension">розширенням</string>
<!-- Widgets -->
<string name="folder_on_widget">Тека, що відображається на віджеті:</string>
<string name="show_folder_name">Показувати ім\'я теки</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Відтворювати відео автоматично</string> <string name="autoplay_videos">Відтворювати відео автоматично</string>
<string name="remember_last_video_position">Запам\'ятовувати місце зупинки перегляду</string> <string name="remember_last_video_position">Запам\'ятовувати місце зупинки перегляду</string>
@ -140,7 +144,7 @@
<string name="animate_gifs">Анімувати ескізи GIF-файлів</string> <string name="animate_gifs">Анімувати ескізи GIF-файлів</string>
<string name="max_brightness">Максимальна яскравість екрану при повноекранному перегляді медіафайлу</string> <string name="max_brightness">Максимальна яскравість екрану при повноекранному перегляді медіафайлу</string>
<string name="crop_thumbnails">Обрізати ескізи у квадрат</string> <string name="crop_thumbnails">Обрізати ескізи у квадрат</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">Показувати тривалість відео</string>
<string name="screen_rotation_by">При повноекранному перегляді обертати за…</string> <string name="screen_rotation_by">При повноекранному перегляді обертати за…</string>
<string name="screen_rotation_system_setting">системними налаштуваннями</string> <string name="screen_rotation_system_setting">системними налаштуваннями</string>
<string name="screen_rotation_device_rotation">поворотом пристрою</string> <string name="screen_rotation_device_rotation">поворотом пристрою</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">垂直翻转</string> <string name="flip_vertically">垂直翻转</string>
<string name="edit_with">编辑方式</string> <string name="edit_with">编辑方式</string>
<string name="free_aspect_ratio">自由</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">自由</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">其他</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">简约壁纸</string> <string name="simple_wallpaper">简约壁纸</string>
@ -132,6 +132,10 @@
<string name="by_file_type">文件类型</string> <string name="by_file_type">文件类型</string>
<string name="by_extension">扩展</string> <string name="by_extension">扩展</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">自动播放</string> <string name="autoplay_videos">自动播放</string>
<string name="remember_last_video_position">记住上次视频播放位置</string> <string name="remember_last_video_position">记住上次视频播放位置</string>
@ -140,7 +144,7 @@
<string name="animate_gifs">GIF 缩略图</string> <string name="animate_gifs">GIF 缩略图</string>
<string name="max_brightness">浏览时最大亮度</string> <string name="max_brightness">浏览时最大亮度</string>
<string name="crop_thumbnails">裁剪缩略图</string> <string name="crop_thumbnails">裁剪缩略图</string>
<string name="show_thumbnail_video_duration">Show video durations</string> <string name="show_thumbnail_video_duration">显示视频时长</string>
<string name="screen_rotation_by">全屏方向</string> <string name="screen_rotation_by">全屏方向</string>
<string name="screen_rotation_system_setting">系统设置</string> <string name="screen_rotation_system_setting">系统设置</string>
<string name="screen_rotation_device_rotation">设备方向</string> <string name="screen_rotation_device_rotation">设备方向</string>

View file

@ -89,7 +89,7 @@
<string name="flip_vertically">垂直翻轉</string> <string name="flip_vertically">垂直翻轉</string>
<string name="edit_with">用其他程式編輯</string> <string name="edit_with">用其他程式編輯</string>
<string name="free_aspect_ratio">自由</string> <!-- available as an option: 1:1, 4:3, 16:9, free --> <string name="free_aspect_ratio">自由</string> <!-- available as an option: 1:1, 4:3, 16:9, free -->
<string name="other_aspect_ratio">Other</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other --> <string name="other_aspect_ratio">其它</string> <!-- available as an option: 1:1, 4:3, 16:9, free, other -->
<!-- Set wallpaper --> <!-- Set wallpaper -->
<string name="simple_wallpaper">簡易桌布</string> <string name="simple_wallpaper">簡易桌布</string>
@ -132,6 +132,10 @@
<string name="by_file_type">檔案類型</string> <string name="by_file_type">檔案類型</string>
<string name="by_extension">副檔名</string> <string name="by_extension">副檔名</string>
<!-- Widgets -->
<string name="folder_on_widget">在小工具顯示資料夾:</string>
<string name="show_folder_name">顯示資料夾名稱</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">自動播放影片</string> <string name="autoplay_videos">自動播放影片</string>
<string name="remember_last_video_position">記住影片上次撥放位置</string> <string name="remember_last_video_position">記住影片上次撥放位置</string>

View file

@ -15,4 +15,5 @@
<dimen name="bottom_filters_height">90dp</dimen> <dimen name="bottom_filters_height">90dp</dimen>
<dimen name="bottom_editor_actions_shadow_height">180dp</dimen> <dimen name="bottom_editor_actions_shadow_height">180dp</dimen>
<dimen name="default_status_action_height">86dp</dimen> <dimen name="default_status_action_height">86dp</dimen>
<dimen name="widget_initial_size">110dp</dimen>
</resources> </resources>

View file

@ -2,6 +2,10 @@
<resources> <resources>
<!-- Release notes --> <!-- Release notes -->
<string name="release_213">
Added an initial widget implementation for creating homescreen folder shortcuts\n
Added optional grouping of direct subfolders, as a check at the \"Change view type\" dialog
</string>
<string name="release_206">Added a new option for password protecting file deletion/move</string> <string name="release_206">Added a new option for password protecting file deletion/move</string>
<string name="release_202">Added a new option for showing the Recycle Bin as the last folder</string> <string name="release_202">Added a new option for showing the Recycle Bin as the last folder</string>
<string name="release_201"> <string name="release_201">

View file

@ -132,6 +132,10 @@
<string name="by_file_type">File type</string> <string name="by_file_type">File type</string>
<string name="by_extension">Extension</string> <string name="by_extension">Extension</string>
<!-- Widgets -->
<string name="folder_on_widget">Folder shown on the widget:</string>
<string name="show_folder_name">Show folder name</string>
<!-- Settings --> <!-- Settings -->
<string name="autoplay_videos">Play videos automatically</string> <string name="autoplay_videos">Play videos automatically</string>
<string name="remember_last_video_position">Remember last video playback position</string> <string name="remember_last_video_position">Remember last video playback position</string>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.simplemobiletools.gallery.pro.activities.WidgetConfigureActivity"
android:initialLayout="@layout/widget"
android:previewImage="@drawable/img_widget_preview"
android:minWidth="@dimen/widget_initial_size"
android:minHeight="40dp"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:resizeMode="horizontal|vertical"/>

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.10' ext.kotlin_version = '1.3.11'
repositories { repositories {
google() google()