diff --git a/CHANGELOG.md b/CHANGELOG.md
index 32bca140f..58136d1a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,21 @@
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)*
----------------------------
diff --git a/app/build.gradle b/app/build.gradle
index aa7e98b3c..d3c104ce3 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
applicationId "com.simplemobiletools.gallery.pro"
minSdkVersion 21
targetSdkVersion 28
- versionCode 212
- versionName "6.0.4"
+ versionCode 214
+ versionName "6.1.1"
multiDexEnabled true
setProperty("archivesBaseName", "gallery")
}
@@ -57,15 +57,15 @@ android {
}
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 'androidx.multidex:multidex:2.0.0'
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 'com.google.android.exoplayer:exoplayer-core:2.9.2'
- implementation 'com.google.vr:sdk-panowidget:1.170.0'
- implementation 'com.google.vr:sdk-videowidget:1.170.0'
+ implementation 'com.google.vr:sdk-panowidget:1.180.0'
+ implementation 'com.google.vr:sdk-videowidget:1.180.0'
implementation 'org.apache.sanselan:sanselan:0.97-incubator'
implementation 'info.androidhive:imagefilters:1.0.7'
implementation 'com.squareup.picasso:picasso:2.71828'
@@ -77,8 +77,9 @@ dependencies {
annotationProcessor 'androidx.room:room-compiler:2.0.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.tibbi:PhotoView:2.2.1-fork'
+ // implementation 'com.github.chrisbanes:PhotoView:2.3.0'
+ implementation 'com.github.tibbi:PhotoView:2.3.0-fork'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a33b0c153..b00e56d71 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -215,6 +215,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
) {
- // if hidden item showing is disabled but all Favorite items are hidden, hide the Favorites folder
mIsGettingDirs = false
mShouldStopFetching = false
+ // if hidden item showing is disabled but all Favorite items are hidden, hide the Favorites folder
if (!config.shouldShowHidden) {
val favoritesFolder = newDirs.firstOrNull { it.areFavorites() }
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
- if (directory == newDir) {
+ if (directory.copy(subfoldersCount = 0, subfoldersMediaCount = 0) == newDir) {
continue
}
@@ -835,7 +837,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
types = newDir.types
}
- showSortedDirs(dirs)
+ setupAdapter(dirs)
// update directories and media files in the local db, delete invalid items
updateDBDirectory(directory, mDirectoryDao)
@@ -862,7 +864,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
mDirectoryDao.deleteDirPath(it.path)
}
dirs.removeAll(dirsToRemove)
- showSortedDirs(dirs)
+ setupAdapter(dirs)
}
val foldersToScan = mediaFetcher.getFoldersToScan()
@@ -899,7 +901,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
val newDir = createDirectoryFromMedia(folder, newMedia, albumCovers, hiddenString, includedFolders, isSortingAscending)
dirs.add(newDir)
- showSortedDirs(dirs)
+ setupAdapter(dirs)
mDirectoryDao.insert(newDir)
if (folder != RECYCLE_BIN) {
mMediumDao.insertAll(newMedia)
@@ -936,18 +938,6 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
directories_grid.beVisibleIf(directories_empty_text_label.isGone())
}
- private fun showSortedDirs(dirs: ArrayList) {
- val updatedDirs = getUniqueSortedDirs(dirs).toMutableList() as ArrayList
- runOnUiThread {
- (directories_grid.adapter as? DirectoryAdapter)?.updateDirs(updatedDirs)
- }
- }
-
- private fun getUniqueSortedDirs(dirs: ArrayList): ArrayList {
- val distinctDirs = dirs.distinctBy { it.path.getDistinctPath() } as ArrayList
- return getSortedDirectories(distinctDirs)
- }
-
private fun createDirectoryFromMedia(path: String, curMedia: ArrayList, albumCovers: ArrayList, hiddenString: String,
includedFolders: MutableSet, isSortingAscending: Boolean): Directory {
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 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 dateTaken = if (isSortingAscending) Math.min(firstItem.taken, lastItem.taken) else Math.max(firstItem.taken, lastItem.taken)
val size = curMedia.sumByLong { it.size }
+ val mediaTypes = curMedia.getDirMediaTypes()
return Directory(null, path, thumbnail, dirName, curMedia.size, lastModified, dateTaken, size, getPathLocation(path), mediaTypes)
}
- private fun setupAdapter(dirs: ArrayList) {
+ private fun setupAdapter(dirs: ArrayList, textToSearch: String = "") {
val currAdapter = directories_grid.adapter
+ val distinctDirs = dirs.distinctBy { it.path.getDistinctPath() }.toMutableList() as ArrayList
+ val sortedDirs = getSortedDirectories(distinctDirs)
+ var dirsToShow = getDirsToShow(sortedDirs, mDirs, mCurrentPathPrefix).clone() as ArrayList
+
if (currAdapter == null) {
initZoomListener()
val fastscroller = if (config.scrollHorizontally) directories_horizontal_fastscroller else directories_vertical_fastscroller
- DirectoryAdapter(this, dirs.clone() as ArrayList, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) {
- val path = (it as Directory).path
- if (path != config.tempFolderPath) {
- itemClicked(path)
+ DirectoryAdapter(this, dirsToShow, this, directories_grid, isPickIntent(intent) || isGetAnyContentIntent(intent), fastscroller) {
+ val clickedDir = it as Directory
+ val path = clickedDir.path
+ if (clickedDir.subfoldersCount == 1 || !config.groupDirectSubfolders) {
+ if (path != config.tempFolderPath) {
+ itemClicked(path)
+ }
+ } else {
+ mCurrentPathPrefix = path
+ mOpenedSubfolders.add(path)
+ setupAdapter(mDirs, "")
}
}.apply {
setupZoomListener(mZoomListener)
- directories_grid.adapter = this
+ runOnUiThread {
+ directories_grid.adapter = this
+ setupScrollDirection()
+ }
}
+ measureRecyclerViewContent(dirsToShow)
} 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 {
- measureRecyclerViewContent(this)
- }
- setupScrollDirection()
+ // recyclerview sometimes becomes empty at init/update, triggering an invisible refresh like this seems to work fine
+ directories_grid.postDelayed({
+ directories_grid.scrollBy(0, 0)
+ }, 500)
}
private fun setupScrollDirection() {
@@ -1051,7 +1057,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
if (invalidDirs.isNotEmpty()) {
dirs.removeAll(invalidDirs)
- showSortedDirs(dirs)
+ setupAdapter(dirs)
invalidDirs.forEach {
mDirectoryDao.deleteDirPath(it.path)
}
@@ -1223,6 +1229,7 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
add(Release(201, R.string.release_201))
add(Release(202, R.string.release_202))
add(Release(206, R.string.release_206))
+ add(Release(213, R.string.release_213))
checkWhatsNew(this, BuildConfig.VERSION_CODE)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
index 791cabd78..536e05245 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/MediaActivity.kt
@@ -118,6 +118,8 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
media_empty_text.setOnClickListener {
showFilterMediaDialog()
}
+
+ updateWidgets()
}
override fun onStart() {
@@ -339,7 +341,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
val dirName = when {
mPath == FAVORITES -> getString(R.string.favorites)
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('/')
else -> getHumanizedFilename(mPath)
}
@@ -585,7 +587,15 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
mCurrAsyncTask?.stopFetching()
mCurrAsyncTask = GetMediaAsynctask(applicationContext, mPath, mIsGetImageIntent, mIsGetVideoIntent, mShowAll) {
Thread {
- gotMedia(it)
+ val oldMedia = mMedia.clone() as ArrayList
+ 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()
}
@@ -689,8 +699,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
val pathToCheck = if (mPath.isEmpty()) SHOW_ALL else mPath
val hasSections = config.getFolderGrouping(pathToCheck) and GROUP_BY_NONE == 0 && !config.scrollHorizontally
val sectionTitleHeight = if (hasSections) layoutManager.getChildAt(0)?.height ?: 0 else 0
- val thumbnailHeight = if (hasSections) layoutManager.getChildAt(1)?.height ?: 0 else layoutManager.getChildAt(0)?.height
- ?: 0
+ val thumbnailHeight = if (hasSections) layoutManager.getChildAt(1)?.height ?: 0 else layoutManager.getChildAt(0)?.height ?: 0
var fullHeight = 0
var curSectionItems = 0
@@ -820,7 +829,7 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
}
- private fun gotMedia(media: ArrayList, isFromCache: Boolean = false) {
+ private fun gotMedia(media: ArrayList, isFromCache: Boolean) {
mIsGettingMedia = false
checkLastMediaChanged()
mMedia = media
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
index 55dc39a86..9c96ec30e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt
@@ -80,6 +80,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
var screenHeight = 0
}
+ @TargetApi(Build.VERSION_CODES.P)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
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() {
@@ -936,8 +955,16 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
private fun askConfirmDelete() {
- val message = if (config.useRecycleBin && !getCurrentMedium()!!.getIsInRecycleBin()) R.string.are_you_sure_recycle_bin else R.string.are_you_sure_delete
- DeleteWithRememberDialog(this, getString(message)) {
+ val filename = "\"${getCurrentPath().getFilenameFromPath()}\""
+
+ 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
deleteConfirmed()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt
new file mode 100644
index 000000000..3a9050af2
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/WidgetConfigureActivity.kt
@@ -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()
+
+ 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()
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
index b4241f18e..80ec519f3 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/DirectoryAdapter.kt
@@ -38,6 +38,7 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList deleteFolders()
else -> {
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 baseString = if (!config.useRecycleBin || (isOneItemSelected() && fileDirItem.isRecycleBin()) || (isOneItemSelected() && fileDirItem.areFavorites())) {
R.string.deletion_confirmation
@@ -501,9 +507,9 @@ class DirectoryAdapter(activity: BaseSimpleActivity, var dirs: ArrayList TYPE_VIDEOS
directory.tmb.isGif() -> TYPE_GIFS
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
index 8731f0a30..e20ea1351 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/adapters/MediaAdapter.kt
@@ -372,8 +372,15 @@ class MediaAdapter(activity: BaseSimpleActivity, var media: MutableList 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()
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/CustomAspectRatioDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/CustomAspectRatioDialog.kt
new file mode 100644
index 000000000..830c839de
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/CustomAspectRatioDialog.kt
@@ -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?, val callback: (aspectRatio: Pair) -> 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()
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/OtherAspectRatioDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/OtherAspectRatioDialog.kt
index 60cd259b6..4fe770c8c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/OtherAspectRatioDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/OtherAspectRatioDialog.kt
@@ -17,6 +17,7 @@ class OtherAspectRatioDialog(val activity: BaseSimpleActivity, val lastOtherAspe
other_aspect_ratio_5_3.setOnClickListener { ratioPicked(Pair(5, 3)) }
other_aspect_ratio_16_9.setOnClickListener { ratioPicked(Pair(16, 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_2_3.setOnClickListener { ratioPicked(Pair(2, 3)) }
@@ -46,6 +47,10 @@ class OtherAspectRatioDialog(val activity: BaseSimpleActivity, val lastOtherAspe
else -> 0
}
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)
@@ -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) {
callback(pair)
dialog.dismiss()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
index 3bf2aa3d4..2adcb6835 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickDirectoryDialog.kt
@@ -1,5 +1,6 @@
package com.simplemobiletools.gallery.pro.dialogs
+import android.view.KeyEvent
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView
import com.simplemobiletools.commons.activities.BaseSimpleActivity
@@ -8,20 +9,20 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.views.MyGridLayoutManager
import com.simplemobiletools.gallery.pro.R
import com.simplemobiletools.gallery.pro.adapters.DirectoryAdapter
-import com.simplemobiletools.gallery.pro.extensions.addTempFolderIfNeeded
-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.extensions.*
import com.simplemobiletools.gallery.pro.helpers.VIEW_TYPE_GRID
import com.simplemobiletools.gallery.pro.models.Directory
import kotlinx.android.synthetic.main.dialog_directory_picker.view.*
-class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: String, val callback: (path: String) -> Unit) {
- var dialog: AlertDialog
- var shownDirectories = ArrayList()
- var view = activity.layoutInflater.inflate(R.layout.dialog_directory_picker, null)
- var isGridViewType = activity.config.viewTypeFolders == VIEW_TYPE_GRID
- var showHidden = activity.config.shouldShowHidden
+class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: String, showOtherFolderButton: Boolean, val callback: (path: String) -> Unit) {
+ private var dialog: AlertDialog
+ private var shownDirectories = ArrayList()
+ private var allDirectories = ArrayList()
+ private var openedSubfolders = arrayListOf("")
+ 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 {
(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
}
- dialog = AlertDialog.Builder(activity)
+ val builder = AlertDialog.Builder(activity)
.setPositiveButton(R.string.ok, null)
.setNegativeButton(R.string.cancel, null)
- .setNeutralButton(R.string.other_folder) { dialogInterface, i -> showOtherFolder() }
- .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)
- }
- }
+ .setOnKeyListener { dialogInterface, i, keyEvent ->
+ if (keyEvent.action == KeyEvent.ACTION_UP && i == KeyEvent.KEYCODE_BACK) {
+ backPressed()
+ }
+ true
+ }
+
+ if (showOtherFolderButton) {
+ 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)
}
@@ -52,6 +63,10 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
private fun fetchDirectories(forceShowHidden: Boolean) {
activity.getCachedDirectories(forceShowHidden = forceShowHidden) {
if (it.isNotEmpty()) {
+ it.forEach {
+ it.subfoldersMediaCount = it.mediaCnt
+ }
+
activity.runOnUiThread {
gotDirectories(activity.addTempFolderIfNeeded(it))
}
@@ -66,18 +81,32 @@ class PickDirectoryDialog(val activity: BaseSimpleActivity, val sourcePath: Stri
}
private fun gotDirectories(newDirs: ArrayList) {
- val dirs = activity.getSortedDirectories(newDirs)
- if (dirs.hashCode() == shownDirectories.hashCode())
+ if (allDirectories.isEmpty()) {
+ allDirectories = newDirs.clone() as ArrayList
+ }
+ val distinctDirs = newDirs.distinctBy { it.path.getDistinctPath() }.toMutableList() as ArrayList
+ val sortedDirs = activity.getSortedDirectories(distinctDirs)
+ val dirs = activity.getDirsToShow(sortedDirs, allDirectories, currentPathPrefix).clone() as ArrayList
+ if (dirs.hashCode() == shownDirectories.hashCode()) {
return
+ }
shownDirectories = dirs
val adapter = DirectoryAdapter(activity, dirs.clone() as ArrayList, null, view.directories_grid, true) {
- if ((it as Directory).path.trimEnd('/') == sourcePath) {
- activity.toast(R.string.source_and_destination_same)
- return@DirectoryAdapter
+ val clickedDir = it as Directory
+ val path = clickedDir.path
+ 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 {
- callback(it.path)
- dialog.dismiss()
+ currentPathPrefix = path
+ 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()
+ }
+ }
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
index ae5675356..b1f83527b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/PickMediumDialog.kt
@@ -53,7 +53,7 @@ class PickMediumDialog(val activity: BaseSimpleActivity, val path: String, val c
}
private fun showOtherFolder() {
- PickDirectoryDialog(activity, path) {
+ PickDirectoryDialog(activity, path, true) {
callback(it)
dialog.dismiss()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ResizeDialog.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ResizeDialog.kt
index c7c10050e..96ef3b50b 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ResizeDialog.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/dialogs/ResizeDialog.kt
@@ -6,11 +6,11 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
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) {
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 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
return if (textValue.isEmpty()) 0 else textValue.toInt()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
index 21cf823ce..0c8458d92 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt
@@ -149,6 +149,7 @@ fun BaseSimpleActivity.removeNoMedia(path: String, callback: (() -> Unit)? = nul
}
tryDeleteFileDirItem(file.toFileDirItem(applicationContext), false, false) {
+ scanPathRecursively(file.parent)
callback?.invoke()
}
}
@@ -183,7 +184,7 @@ fun BaseSimpleActivity.tryCopyMoveFilesTo(fileDirItems: ArrayList,
}
val source = fileDirItems[0].getParentPath()
- PickDirectoryDialog(this, source) {
+ PickDirectoryDialog(this, source, true) {
copyMoveFilesTo(fileDirItems, source.trimEnd('/'), it, isCopyOperation, true, config.shouldShowHidden, callback)
}
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
index d7430f161..c8a7f5b58 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Context.kt
@@ -1,5 +1,7 @@
package com.simplemobiletools.gallery.pro.extensions
+import android.appwidget.AppWidgetManager
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
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.interfaces.DirectoryDao
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.Medium
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 pl.droidsonroids.gif.GifDrawable
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.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.widgetsDB: WidgetsDao get() = GalleryDatabase.getInstance(applicationContext).WidgetsDao()
+
+val Context.directoryDB: DirectoryDao get() = GalleryDatabase.getInstance(applicationContext).DirectoryDao()
+
val Context.recycleBin: File get() = filesDir
val Context.recycleBinPath: String get() = filesDir.absolutePath
@@ -159,6 +170,10 @@ fun Context.getSortedDirectories(source: ArrayList): ArrayList o1.taken.compareTo(o2.taken)
}
+ if (result == 0) {
+ result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
+ }
+
if (sorting and SORT_DESCENDING != 0) {
result *= -1
}
@@ -168,6 +183,120 @@ fun Context.getSortedDirectories(source: ArrayList): ArrayList, allDirs: ArrayList, currentPathPrefix: String): ArrayList {
+ return if (config.groupDirectSubfolders) {
+ dirs.forEach {
+ it.subfoldersCount = 0
+ it.subfoldersMediaCount = it.mediaCnt
+ }
+
+ val dirFolders = dirs.map { it.path }.sorted().toMutableSet() as HashSet
+ val foldersToShow = getDirectParentSubfolders(dirFolders, currentPathPrefix)
+ val parentDirs = dirs.filter { foldersToShow.contains(it.path) } as ArrayList
+ 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, currentPathPrefix: String): HashSet {
+ val internalPath = internalStoragePath
+ val sdPath = sdCardPath
+ val currentPaths = LinkedHashSet()
+
+ 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, parentDirs: ArrayList) {
+ 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) -> Unit) {
Thread {
val folders = ArrayList()
@@ -234,10 +363,21 @@ fun Context.storeDirectoryItems(items: ArrayList, directoryDao: Direc
}
fun Context.checkAppendingHidden(path: String, hidden: String, includedFolders: MutableSet): 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)
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 -> {
if (path.startsWith(OTG_PATH)) {
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) {
@@ -482,3 +616,14 @@ fun Context.getUpdatedDeletedMedia(mediumDao: MediumDao): ArrayList {
fun Context.deleteDBPath(mediumDao: MediumDao, path: String) {
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)
+ }
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
index 0580e2a48..372bc7b0c 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/fragments/PhotoFragment.kt
@@ -26,6 +26,9 @@ import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.davemorrissey.labs.subscaleview.ImageSource
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.helpers.OTG_PATH
import com.simplemobiletools.gallery.pro.R
@@ -377,18 +380,26 @@ class PhotoFragment : ViewPagerFragment() {
val path = getPathToLoad(medium)
isSubsamplingVisible = true
+ val bitmapDecoder = object : DecoderFactory {
+ override fun make() = PicassoDecoder(path, Picasso.get(), rotation)
+ }
+
+ val regionDecoder = object : DecoderFactory {
+ override fun make() = PicassoRegionDecoder()
+ }
+
view.subsampling_view.apply {
setMaxTileSize(if (context!!.config.showHighestQuality) Integer.MAX_VALUE else 4096)
setMinimumTileDpi(if (context!!.config.showHighestQuality) -1 else getMinTileDpi())
background = ColorDrawable(Color.TRANSPARENT)
- setBitmapDecoderFactory { PicassoDecoder(path, Picasso.get(), rotation) }
- setRegionDecoderFactory { PicassoRegionDecoder() }
+ setBitmapDecoderFactory(bitmapDecoder)
+ setRegionDecoderFactory(regionDecoder)
maxScale = 10f
beVisible()
isQuickScaleEnabled = context.config.oneFingerZoom
setResetScaleOnSizeChange(false)
setImage(ImageSource.uri(path))
- orientation = rotation
+ setOrientation(rotation)
setEagerLoadingEnabled(false)
setOnImageEventListener(object : SubsamplingScaleImageView.OnImageEventListener {
override fun onImageLoaded() {
@@ -402,7 +413,7 @@ class PhotoFragment : ViewPagerFragment() {
mOriginalSubsamplingScale = scale
}
- override fun onTileLoadError(e: Exception?) {
+ override fun onTileLoadError(e: Exception) {
}
override fun onPreviewReleased() {
@@ -415,7 +426,7 @@ class PhotoFragment : ViewPagerFragment() {
beGone()
}
- override fun onPreviewLoadError(e: Exception?) {
+ override fun onPreviewLoadError(e: Exception) {
background = ColorDrawable(Color.TRANSPARENT)
isSubsamplingVisible = false
beGone()
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
index e25a4073d..cdb7ef840 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Config.kt
@@ -423,4 +423,12 @@ class Config(context: Context) : BaseConfig(context) {
var lastEditorCropOtherAspectRatioY: Int
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()
+
+ 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()
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
index f868a1747..95a068eb0 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/Constants.kt
@@ -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_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 GROUP_DIRECT_SUBFOLDERS = "group_direct_subfolders"
+const val SHOW_WIDGET_FOLDER_NAME = "show_widget_folder_name"
// slideshow
const val SLIDESHOW_INTERVAL = "slideshow_interval"
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
index 24d571dfa..b57e37c70 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MediaFetcher.kt
@@ -364,6 +364,10 @@ class MediaFetcher(val context: Context) {
else -> o1.taken.compareTo(o2.taken)
}
+ if (result == 0) {
+ result = AlphanumericComparator().compare(o1.path.toLowerCase(), o2.path.toLowerCase())
+ }
+
if (sorting and SORT_DESCENDING != 0) {
result *= -1
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt
new file mode 100644
index 000000000..2af024791
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/helpers/MyWidgetProvider.kt
@@ -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()
+ }
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/DirectoryDao.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/DirectoryDao.kt
index 78641ebf9..57d6807c2 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/DirectoryDao.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/DirectoryDao.kt
@@ -29,4 +29,7 @@ interface DirectoryDao {
@Query("DELETE FROM directories WHERE path = \'$RECYCLE_BIN\' COLLATE NOCASE")
fun deleteRecycleBin()
+
+ @Query("SELECT thumbnail FROM directories WHERE path = :path")
+ fun getDirectoryThumbnail(path: String): String?
}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/WidgetsDao.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/WidgetsDao.kt
new file mode 100644
index 000000000..b6ecb2492
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/interfaces/WidgetsDao.kt
@@ -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
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insertOrUpdate(widget: Widget): Long
+
+ @Query("DELETE FROM widgets WHERE widget_id = :widgetId")
+ fun deleteWidgetId(widgetId: Int)
+}
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Directory.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Directory.kt
index c5b90b860..fd320050e 100644
--- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Directory.kt
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Directory.kt
@@ -1,9 +1,6 @@
package com.simplemobiletools.gallery.pro.models
-import androidx.room.ColumnInfo
-import androidx.room.Entity
-import androidx.room.Index
-import androidx.room.PrimaryKey
+import androidx.room.*
import com.simplemobiletools.commons.extensions.formatDate
import com.simplemobiletools.commons.extensions.formatSize
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.gallery.pro.helpers.FAVORITES
import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN
-import java.io.Serializable
@Entity(tableName = "directories", indices = [Index(value = ["path"], unique = true)])
data class Directory(
@@ -24,12 +20,14 @@ data class Directory(
@ColumnInfo(name = "last_modified") var modified: Long,
@ColumnInfo(name = "date_taken") var taken: Long,
@ColumnInfo(name = "size") var size: Long,
- @ColumnInfo(name = "location") val location: Int,
- @ColumnInfo(name = "media_types") var types: Int) : Serializable {
+ @ColumnInfo(name = "location") var location: Int,
+ @ColumnInfo(name = "media_types") var types: Int,
- companion object {
- private const val serialVersionUID = -6553345863555455L
- }
+ // used with "Group direct subfolders" enabled
+ @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 {
sorting and SORT_BY_NAME != 0 -> name
diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Widget.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Widget.kt
new file mode 100644
index 000000000..2ef525334
--- /dev/null
+++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/models/Widget.kt
@@ -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)
diff --git a/app/src/main/res/drawable-hdpi/img_widget_preview.png b/app/src/main/res/drawable-hdpi/img_widget_preview.png
new file mode 100644
index 000000000..625e39531
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/img_widget_preview.png differ
diff --git a/app/src/main/res/drawable-xhdpi/img_widget_preview.png b/app/src/main/res/drawable-xhdpi/img_widget_preview.png
new file mode 100644
index 000000000..481681a63
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_widget_preview.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/img_widget_preview.png b/app/src/main/res/drawable-xxhdpi/img_widget_preview.png
new file mode 100644
index 000000000..c400e88e9
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/img_widget_preview.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/img_widget_preview.png b/app/src/main/res/drawable-xxxhdpi/img_widget_preview.png
new file mode 100644
index 000000000..ffe566b2d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/img_widget_preview.png differ
diff --git a/app/src/main/res/layout/activity_widget_config.xml b/app/src/main/res/layout/activity_widget_config.xml
new file mode 100644
index 000000000..ae762ab01
--- /dev/null
+++ b/app/src/main/res/layout/activity_widget_config.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_change_view_type.xml b/app/src/main/res/layout/dialog_change_view_type.xml
new file mode 100644
index 000000000..003692bb9
--- /dev/null
+++ b/app/src/main/res/layout/dialog_change_view_type.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_custom_aspect_ratio.xml b/app/src/main/res/layout/dialog_custom_aspect_ratio.xml
new file mode 100644
index 000000000..3f9180ae0
--- /dev/null
+++ b/app/src/main/res/layout/dialog_custom_aspect_ratio.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/dialog_other_aspect_ratio.xml b/app/src/main/res/layout/dialog_other_aspect_ratio.xml
index 76fbb1b4a..61487c688 100644
--- a/app/src/main/res/layout/dialog_other_aspect_ratio.xml
+++ b/app/src/main/res/layout/dialog_other_aspect_ratio.xml
@@ -84,6 +84,16 @@
android:text="19:9"
android:textSize="@dimen/bigger_text_size"/>
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 97f79e6c7..4f9e5a2c7 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -136,6 +136,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
تشغيل الفديوهات تلقائيا
Remember last video playback position
diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml
index 9bf9ff4b5..372505031 100644
--- a/app/src/main/res/values-az/strings.xml
+++ b/app/src/main/res/values-az/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Play videos automatically
Remember last video playback position
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 25833a288..df1bbe48b 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -89,7 +89,7 @@
Verticalment
Editar amb
Lliure
- Other
+ Altres
Fons de pantalla de Simple Gallery
@@ -132,6 +132,10 @@
Tipus de fitxer
Extensió
+
+ Carpeta que es mostra a l\'estri:
+ Mostra el nom de la carpeta
+
Reproduir vídeos automàticament
Recordeu la posició de la darrera reproducció de vídeo
@@ -140,7 +144,7 @@
Animar les miniatures dels GIFs
Brillantor màxima quan es mostra multimèdia
Retallar miniatures en quadrats
- Show video durations
+ Mostra les durades del vídeo
Gira els mitjans a pantalla completa segons
Configuració del sistema
Rotació del dispositiu
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 291bda22e..e8706c85b 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -132,6 +132,10 @@
Typu souboru
Přípony
+
+ Folder shown on the widget:
+ Show folder name
+
Automaticky přehrávat videa
Zapamatovat pozici posledního přehraného videa
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index a2f85f704..0557e2732 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -6,9 +6,9 @@
Åbn kamera
(skjult)
(ekskluderet)
- Pin folder
- Unpin folder
- Pin to the top
+ Fastgør mappe
+ Fjern fastgørelse af mappe
+ Fastgør til toppen
Vis indholdet af alle mapper
Alle mapper
Skift til mappevisning
@@ -17,19 +17,19 @@
Ukendt placering
Flere kolonner
Færre kolonner
- Change cover image
- Select photo
- Use default
- Volume
- Brightness
+ Skift cover billede
+ Vælg billede
+ Brug standard
+ Lydstyrke
+ Lysstyrke
Lås orientering
Lås orientering op
- Change orientation
- Force portrait
- Force landscape
- Use default orientation
- Fix Date Taken value
- Fixing…
+ Skift orientering
+ Tving portræt
+ Tving landskab
+ Brug standard orientering
+ Fiks Dato Taget værdi
+ Fikser…
Dates fixed successfully
@@ -63,17 +63,17 @@
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.
- Skaler
- Resize selection and save
- Width
- Height
- Keep aspect ratio
- Please enter a valid resolution
+ Skalér
+ Skalér valgte elementer og gem
+ Bredde
+ Højde
+ Bevar billedeforhold
+ Indtast en gyldig opløsning
Editor
Gem
- Roter
+ Rotér
Sti
Ugyldig sti til billede
Redigering af billede mislykkedes
@@ -81,9 +81,9 @@
Der blev ikke fundet en editor til billedbehandling
Ukendt filplacering
Kunne ikke overskrive kildefilen
- Roter mod venstre
- Roter mod højre
- Roter 180º
+ Rotér mod venstre
+ Rotér mod højre
+ Rotér 180º
Spejlvend
Spejlvend vandret
Spejlvend lodret
@@ -121,27 +121,31 @@
Skift visning
Gitter
Liste
- Group direct subfolders
+ Gruppér direkte undermapper
- Group by
- Do not group files
- Folder
- Last modified
- Date taken
- File type
- Extension
+ Gruppér efter
+ Gruppér ikke filer
+ Mappe
+ Sidst ændret
+ Dato taget
+ Filtype
+ Filudvidelse
+
+
+ Mappe vist på widget:
+ Vis mappenavn
Afspil automatisk videoer
- Remember last video playback position
- Toggle filename visibility
+ Husk sidste position ved videoafspilning
+ Skift filnavnets synlighed
Kør videoer i sløjfe
Animér GIF\'er i miniaturer
Maksimal lysstyrke ved fuldskærmsvisning af medier
Beskær miniaturer til kvadrater
- Show video durations
- Roter fuldskærmsmedier efter
+ Vis varighed på video
+ Rotér fuldskærmsmedier efter
Systemindstilling
Enhedens orientering
Billedformat
@@ -150,33 +154,33 @@
Skjul automatisk systemets brugerflade ved fuldskærmsvisning af medier
Slet tomme mapper efter sletning af deres indhold
Tillad kontrol af lysstyrke på billeder med lodrette bevægelser
- Tillad kontrol af videolyd og lysstyrke med lodrette bevægelser
+ Tillad kontrol af lyd- og lysstyrke på videoer med lodrette bevægelser
Vis antal filer i hver mappe i oversigten
- Erstat Del med Roter i fuldskærmsmenuen
+ Erstat Del med Rotér i fuldskærmsmenuen
Vis udvidede oplysninger over medier i fuldskærm
- Manage extended details
+ Administrer udvidede oplysninger
Tillad zoom med en finger når medier er i fuldskærm
Tillad skift af medie ved klik på skærmens sider
Allow deep zooming images
Skjul udvidede oplysninger når statuslinjen er skjult
Tjek en ekstra gang for at undgå visning af ugyldige filer
- Show some action buttons at the bottom of the screen
- Show the Recycle Bin at the folders screen
+ Vis handlingsknapper i bunden af skærmen
+ Vis papirkurven ved mappevisning
Deep zoomable images
- Show images in the highest possible quality
- Show the Recycle Bin as the last item on the main screen
+ Vis billeder i den højst mulige kvalitet
+ Vis papirkurven som sidste element på hovedskærmen
Allow closing the fullscreen view with a down gesture
- Thumbnails
- Fullscreen media
+ Miniaturer
+ Fuldskærmsmedier
Flere oplysninger
- Bottom actions
+ Handlingsknapper
- Manage visible bottom actions
- Toggle favorite
- Toggle file visibility
+ Administrer synlige handlingsknapper
+ Favorit
+ Synlighed
How can I make Simple Gallery the default device gallery?
@@ -212,7 +216,7 @@
- A gallery for viewing photos and videos without ads.
+ Et galleri til visning af billeder og videoer uden reklamer.
A highly customizable gallery capable of displaying many different image and video types including SVGs, RAWs, panoramic photos and videos.
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 141cad8b7..0237128fb 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -89,7 +89,7 @@
Vertikal spiegeln
Bearbeiten mit:
Beliebiges
- Other
+ Anderes
Schlichter Hintergrund
@@ -132,6 +132,10 @@
Dateityp (Bilder/Videos)
Dateierweiterung
+
+ Ordner, der auf dem Widget angezeigt wird:
+ Ordnernamen anzeigen
+
Videos automatisch abspielen
Letzte Videowiedergabeposition erinnern
@@ -140,7 +144,7 @@
Kacheln von GIFs animieren
Helligkeit beim Betrachten maximieren
Kacheln quadratisch zuschneiden
- Show video durations
+ Videodauer anzeigen
Im Vollbild ausrichten nach:
Systemeinstellung
Gerätedrehung
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 0226ad203..3c29ab646 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -132,6 +132,10 @@
Τύπο αρχείου
Επέκταση
+
+ Εμφάνιση φακέλου στο widget:
+ Εμφάνιση ονόματος φακέλου
+
Αυτόματη αναπαραγωγή βίντεο
Απομνημόνευση της τελευταίας θέσης αναπαραγωγής βίντεο
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 80c2796c0..b10955ebc 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -89,7 +89,7 @@
Verticalmente
Editar con
Libre
- Other
+ Otros
Fondos de pantalla Simple Gallery
@@ -132,6 +132,10 @@
Tipo de fichero
Extensión
+
+ Carpeta mostrada en el widget:
+ Mostrar nombre de carpeta
+
Reproducir vídeos automáticamente
Recuerde la última posición de reproducción de video
@@ -140,7 +144,7 @@
Animar las miniaturas de GIFs
Brillo máximo cuando se muestra multimedia
Recortar miniaturas en cuadrados
- Show video durations
+ Mostrar duración del video
Rotar multimedia en pantalla completa según
Configuración del sistema
Rotación del dispositivo
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index e26cef2a7..0ebaef866 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Toista videot automaattisesti
Remember last video playback position
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index c2c905a9f..5af44b0a6 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -132,6 +132,10 @@
Type de fichier
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Lecture automatique des vidéos
Remember last video playback position
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index 07e7df693..79e7592bc 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -132,6 +132,10 @@
Tipo de ficheior
Extensión
+
+ Folder shown on the widget:
+ Show folder name
+
Reproducir vídeos automticamente
Remember last video playback position
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 6090e559b..8fee29889 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -132,6 +132,10 @@
Tip datoteke
Vrsta datoteke
+
+ Folder shown on the widget:
+ Show folder name
+
Automatsko pokretanje videa
Remember last video playback position
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 65468b93e..bdfeb0610 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -133,6 +133,10 @@
Fájl típus
Kiterjesztés
+
+ Mappa mutatása a widgeten:
+ Mutassa a mappa nevét
+
Automatikus videó lejátszás
Emlékezzen a videó utolsó lejátszási pozícióra
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
new file mode 100644
index 000000000..319a68155
--- /dev/null
+++ b/app/src/main/res/values-id/strings.xml
@@ -0,0 +1,252 @@
+
+
+ Simple Gallery
+ Galeri
+ Edit
+ Buka kamera
+ (tersembunyi)
+ (dikecualikan)
+ Pin folder
+ Lepas pin folder
+ Pin ke atas
+ Tampilkan semua isi folder
+ Semua folder
+ Beralih ke tampilan folder
+ Folder lain
+ Tampilkan di peta
+ Lokasi tidak diketahui
+ Tambah jumlah kolom
+ Kurangi jumlah kolom
+ Ubah sampul
+ Pilih foto
+ Gunakan default
+ Volume
+ Kecerahan
+ Kunci rotasi
+ Aktifkan rotasi
+ Ubah orientasi
+ Paksa potret
+ Paksa landscape
+ Gunakan orientasi default
+ Perbaiki Tanggal Diambil
+ Memperbaiki…
+ Tanggal berhasil diperbaiki
+
+
+ Filter media
+ Gambar
+ Video
+ GIF
+ Gambar RAW
+ SVG
+ Tidak ada file media ditemukan dari filter ini.
+ Ubah filter
+
+
+ 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?
+ Kecualikan
+ Folder yang dikecualikan
+ Atur folder yang dikecualikan
+ Ini hanya akan mengecualikan pilihan bersama dengan subfoldernya di Simple Gallery. Anda bisa mengatur pengecualian di Setelan.
+ Kecualikan folder induk?
+ Mengecualikan folder akan membuatnya bersama subfoldernya tersembunyi hanya di Simple Gallery, namun masih bisa dilihat di aplikasi lain.\n\nJika Anda ingin menyembunyikannya dari aplikasi lain juga, gunakan fitur Sembunyikan.
+ Bersihkan daftar
+ Hapus semua folder dari daftar pengecualian? Ini tidak akan menghapus folder tersebut.
+ Folder tersembunyi
+ Atur folder tersembunyi
+ Sepertinya tidak ada folder tersembunyi dengan file \".nomedia\" didalamnya.
+
+
+ Folder yang disertakan
+ Atur folder yang disertakan
+ Tambah folder
+ 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.
+
+
+ Ubah ukuran
+ Ubah ukuran terpilih dan simpan
+ Lebar
+ Tinggi
+ Jaga aspek rasio
+ Harap masukkan resolusi dengan benar
+
+
+ Editor
+ Simpan
+ Rotasi
+ Jalur
+ Jalur gambar tidak valid
+ Gagal mengedit gambar
+ Edit dengan:
+ Tidak ada aplikasi editor gambar
+ Lokasi file tidak diketahui
+ Tidak dapat mengganti file sumber
+ Putar ke kiri
+ Putar ke kanan
+ Putar 180º
+ Balik
+ Balik horizontal
+ Balik vertikal
+ Edit dengan
+ Bebas
+ Lainnya
+
+
+ Simple Wallpaper
+ Setel wallpaper
+ Gagal menyetel sebagai wallpaper
+ Setel wallpaper dengan:
+ Menyetel wallpaper…
+ Wallpaper berhasil disetel
+ Aspek rasio potret
+ Aspek rasio landscape
+ Layar beranda
+ Layar kunci
+ Beranda dan layar kunci
+
+
+ Slideshow
+ Interval (detik):
+ Sertakan foto
+ Sertakan video
+ Sertakan GIF
+ Urutan acak
+ Animasi memudar
+ Mundur
+ Slideshow tanpa henti
+ Slideshow berakhir
+ Tidak ditemukan media untuk slideshow
+
+
+ Ubah jenis tampilan
+ Kotak
+ Daftar
+ Kelompokkan langsung subfolder
+
+
+ Kelompokkan menurut
+ Jangan kelompokkan file
+ Folder
+ Terakhir diubah
+ Tanggal diambil
+ Jenis file
+ Ekstensi
+
+
+ Folder shown on the widget:
+ Show folder name
+
+
+ Putar video otomatis
+ Ingat posisi pemutaran terakhir
+ Tampil/sembunyikan nama file
+ Ulangi video
+ Animasi GIF di thumbnail
+ Kecerahan maksimal saat melihat di layar penuh
+ Pangkas thumbnail menjadi persegi
+ Tampilkan durasi video
+ Rotasi layar penuh dari
+ Pengaturan sistem
+ Rotasi perangkat
+ Aspek rasio
+ Background dan status bar hitam saat layar penuh
+ Gulir thumbnail secara horizontal
+ Otomatis sembunyikan sistem UI saat layar penuh
+ Hapus folder kosong setelah menghapus isinya
+ Izinkan mengontrol kecerahan foto dengan gerakan vertikal
+ Izinkan mengontrol kecerahan dan volume video dengan gerakan vertikal
+ Tampilkan jumlah folder media di tampilan utama
+ Ganti tombol Bagikan dengan Rotasi di menu layar penuh
+ Tampilkan detail tambahan saat layar penuh
+ Atur detail tambahan
+ Izinkan zoom satu jari di layar penuh
+ Izinkan mengganti media dengan mengklik sisi layar
+ Izinkan zoom gambar lebih dalam
+ Sembunyikan detail tambahan ketika status bar disembunyikan
+ Lakukan pemeriksaan ulang untuk menghindari file yang tidak valid
+ Tampilkan beberapa tombol tindakan dibawah layar
+ Tampilkan Sampah di layar folder
+ Zoom gambar mendalam
+ Tampilkan gambar dalam kualitas tertinggi
+ Tampilkan Sampah sebagai item terakhir di layar utama
+ Izinkan keluar dari layar penuh dengan menggeser kebawah
+
+
+ Thumbnail
+ Media layar penuh
+ Detail tambahan
+ Tindakan di bawah
+
+
+ Sesuaikan tombol tindakan bawah
+ Favorit
+ Tampil/sembunyikan file
+
+
+ Bagaimana cara menjadikan Simple Gallery sebagai aplikasi galeri default?
+ 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.
+ Saya mengunci aplikasi dengan password, tapi saya lupa. Apa yang harus dilakukan?
+ 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.
+ Bagaimana agar sebuah album selalu muncul paling atas di daftar?
+ Anda bisa menekan lama album tersebut dan pilih ikon Pin di menu tindakan, itu akan menaruhnya di atas daftar. Anda juga bisa menyematkan beberapa folder, item yang di-pin akan diurutkan berdasarkan metode urutan default.
+ Bagaimana cara mempercepat laju video?
+ Anda bisa mengklik teks durasi saat ini/maksimal di dekat penggeser durasi, itu akan memajukan atau memundurkan video.
+ Apa perbedaan antara menyembunyikan dan mengecualikan folder?
+ Mengecualikan tidak akan menampilkan folder di Simple Gallery, sedangkan Sembunyikan bekerja sesuai aturan sistem dan akan menyembunyikan folder juga dari aplikasi galeri yang lain. Cara kerjanya dengan membuat file \".nomedia\" kosong pada folder yang diinginkan, yang bisa Anda hapus juga dengan aplikasi file manager.
+ Mengapa folder dengan gambar album musik atau stiker muncul?
+ Kadang Anda melihat beberapa album yang tidak biasa muncul. Anda bisa dengan mudah menyembunyikannya dengan menekan lama dan pilih Kecualikan. Pada dialog berikutnya, Anda lalu bisa memilih folder induk, yang akan mencegah album terkait muncul kembali.
+ Ada folder berisi gambar namun tidak muncul, apa yang harus dilakukan?
+ Itu bisa disebabkan berbagai alasan, namun solusinya mudah. Pergi ke Setelan -> Atur folder yang disertakan, pilih Tambah dan cari folder yang diinginkan.
+ Bagaimana jika saya hanya ingin beberapa folder saja yang terlihat?
+ Menambahkan folder di Folder yang Disertakan tidak otomatis mengecualikan folder yang lain. Yang bisa Anda lakukan adalah pergi ke 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.
+ Gambar layar penuh terlihat pecah, bisakah ditingkatkan kualitasnya?
+ 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.
+ Bisakah saya meng-crop gambar dengan aplikasi ini?
+ 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.
+ Bisakah saya mengelompokkan thumbnail file media?
+ 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.
+ Tidak dapat mengurutkan berdasarkan Tanggal Diambil, bagaimana cara memperbaikinya?
+ Itu umumnya disebabkan karena file yang disalin dari tempat lain. Anda bisa memperbaikinya dengan memilih thumbnail file dan pilih \"Perbaiki Tanggal Diambil\".
+ Saya melihat beberapa pita warna pada gambar. Bagaimana saya meningkatkan kualitasnya?
+ Solusi saat ini untuk menampilkan gambar berfungsi dengan baik dalam sebagian besar kasus, namun jika Anda ingin kualitas gambar yang lebih baik, Anda bisa mengaktifkan \"Tampilkan gambar dalam kualitas tertinggi\" di setelan aplikasi, pada bagian \"Zoom gambar mendalam\".
+ Saya punya file/folder tersembunyi. Bagaimana cara memunculkannya?
+ 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.
+
+
+
+ Aplikasi galeri untuk melihat foto dan video tanpa iklan.
+
+ 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
+
+
+
+
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 95b22925f..fc126811d 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -132,6 +132,10 @@
Tipo di file
Estensione
+
+ Cartella mostrata nel widget:
+ Mostra il nome della cartella
+
Riproduci i video automaticamente
Ricorda l\'ultimo stato di riproduzione dei video
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index d1a8bc92e..397e4e88f 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -132,6 +132,10 @@
ファイル形式
拡張子
+
+ Folder shown on the widget:
+ Show folder name
+
ビデオを自動再生
Remember last video playback position
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index 974054786..aef49c472 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
비디오 자동재생
Remember last video playback position
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index f0f73e1a1..d791865cf 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Groti vaizdo įrašus automatiškai
Remember last video playback position
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index a866ca6e4..6b42ebde8 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -132,6 +132,10 @@
Filtype
Endelse
+
+ Folder shown on the widget:
+ Show folder name
+
Avspill videoer automatisk
Husk siste videoavspillingsposisjon
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 0e3a92429..df6819783 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -132,6 +132,10 @@
Bestandstype
Extensie
+
+ Map tonen in de widget:
+ Mapnaam tonen
+
Video\'s automatisch afspelen
Laatste positie in video\'s onthouden
@@ -160,7 +164,7 @@
Verder inzoomen mogelijk maken
Uitgebreide informatie niet tonen als de statusbalk is verborgen
Ongeldige bestanden verbergen
- Enkele actieknoppen onderaan het scherm tonen
+ Enkele actieknoppen onder aan het scherm tonen
Prullenbak weergeven in de mapweergave
Afbeeldingen ver inzoomen
Afbeeldingen in de hoogst mogelijke kwaliteit weergeven
@@ -171,7 +175,7 @@
Miniatuurvoorbeelden
Volledig scherm
Uitgebreide informatie
- Acties onderaan het scherm
+ Acties onder aan het scherm
Actieknoppen onderaan beheren
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 991c22e7b..42ba52f06 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -132,6 +132,10 @@
Typu
Rozszerzenia
+
+ Folder shown on the widget:
+ Show folder name
+
Odtwarzaj filmy automatycznie
Pamiętaj ostatni moment odtwarzania filmów
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 027f9a086..cb971ca18 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Reproduzir vídeos automaticamente
Remember last video playback position
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 681704fec..bff249a51 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -89,7 +89,7 @@
Verticalmente
Editar com
Livre
- Other
+ Outro
Simple Wallpaper
@@ -132,6 +132,10 @@
Tipo de ficheiro
Extensão
+
+ Folder shown on the widget:
+ Show folder name
+
Reproduzir vídeos automaticamente
Memorizar posição da reprodução
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index ed4adfa28..0b45427f3 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -132,6 +132,10 @@
Тип файла
Расширение
+
+ Folder shown on the widget:
+ Show folder name
+
Воспроизводить видео автоматически
Запоминать позицию воспроизведения видео
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index a081eb7a5..f6592eb1d 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -132,6 +132,10 @@
Typu súboru
Prípony
+
+ Priečinok zobrazený vo widgete:
+ Zobraziť názov priečinka
+
Spúšťať videá automaticky
Zapamätať si pozíciu posledného prehraného videa
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 3dfff7213..e8b8941e8 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -132,6 +132,10 @@
Tip datoteke
Končnica
+
+ Folder shown on the widget:
+ Show folder name
+
Avtomatično predvajaj videoposnetke
Zapomni si zadnji položaj predvajanja
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 04dd09abc..45da7bafb 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -132,6 +132,10 @@
Filtyp
Filnamnstillägg
+
+ Folder shown on the widget:
+ Show folder name
+
Spela upp videor automatiskt
Remember last video playback position
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index cabbb3093..33bdcfecb 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -132,6 +132,10 @@
Dosya türü
Uzantı
+
+ Folder shown on the widget:
+ Show folder name
+
Videoları otomatik oynat
Son video oynatma konumunu hatırla
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 273982f7d..24bd7ead0 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -89,7 +89,7 @@
Віддзеркалити вертикально
Редагувати за допомогою
Вільне
- Other
+ Інше
Simple Wallpaper
@@ -132,6 +132,10 @@
типом файлу
розширенням
+
+ Тека, що відображається на віджеті:
+ Показувати ім\'я теки
+
Відтворювати відео автоматично
Запам\'ятовувати місце зупинки перегляду
@@ -140,7 +144,7 @@
Анімувати ескізи GIF-файлів
Максимальна яскравість екрану при повноекранному перегляді медіафайлу
Обрізати ескізи у квадрат
- Show video durations
+ Показувати тривалість відео
При повноекранному перегляді обертати за…
системними налаштуваннями
поворотом пристрою
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 6dfe0a550..e77503681 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -89,7 +89,7 @@
垂直翻转
编辑方式
自由
- Other
+ 其他
简约壁纸
@@ -132,6 +132,10 @@
文件类型
扩展
+
+ Folder shown on the widget:
+ Show folder name
+
自动播放
记住上次视频播放位置
@@ -140,7 +144,7 @@
GIF 缩略图
浏览时最大亮度
裁剪缩略图
- Show video durations
+ 显示视频时长
全屏方向
系统设置
设备方向
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 423570191..d6304564d 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -89,7 +89,7 @@
垂直翻轉
用其他程式編輯
自由
- Other
+ 其它
簡易桌布
@@ -132,6 +132,10 @@
檔案類型
副檔名
+
+ 在小工具顯示資料夾:
+ 顯示資料夾名稱
+
自動播放影片
記住影片上次撥放位置
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 2edafe611..89072fb3e 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -15,4 +15,5 @@
90dp
180dp
86dp
+ 110dp
diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml
index 2c669f7a8..2e6a8223d 100644
--- a/app/src/main/res/values/donottranslate.xml
+++ b/app/src/main/res/values/donottranslate.xml
@@ -2,6 +2,10 @@
+
+ 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
+
Added a new option for password protecting file deletion/move
Added a new option for showing the Recycle Bin as the last folder
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c66b10185..808d89d8b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -132,6 +132,10 @@
File type
Extension
+
+ Folder shown on the widget:
+ Show folder name
+
Play videos automatically
Remember last video playback position
diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml
new file mode 100644
index 000000000..3f70a3268
--- /dev/null
+++ b/app/src/main/res/xml/widget_info.xml
@@ -0,0 +1,11 @@
+
+
diff --git a/build.gradle b/build.gradle
index 1cfbb3a29..d93366c1c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.10'
+ ext.kotlin_version = '1.3.11'
repositories {
google()