From ccee5bf8e53da54fe42a7a9e803ab84da4d61471 Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Sat, 8 Sep 2018 15:49:46 +0200 Subject: [PATCH 01/11] 127: Folderpicker: moving pathbar makes it discoverable. stop animation once the pathbar is touched --- .../k3b/android/androFotoFinder/Global.java | 3 + .../directory/DirectoryPickerFragment.java | 62 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/Global.java b/app/src/main/java/de/k3b/android/androFotoFinder/Global.java index 51f14584..c307438f 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/Global.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/Global.java @@ -82,6 +82,9 @@ public class Global { /** true every time a .nomedia dir/file is opend remeove items from db. */ public static final boolean mustRemoveNOMEDIAfromDB = true; + // #127: Folderpicker: moving pathbar makes it discoverable. stop animation once the pathbar is touched + public static final boolean showPathBarAnimation = true; + private static final File externalStorageDirectory = Environment.getExternalStorageDirectory(); /** defines the filesystem's directory where [Bookmark files](Bookmarks) are stored and loaded from. */ diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/directory/DirectoryPickerFragment.java b/app/src/main/java/de/k3b/android/androFotoFinder/directory/DirectoryPickerFragment.java index 93558e54..263d5521 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/directory/DirectoryPickerFragment.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/directory/DirectoryPickerFragment.java @@ -19,6 +19,7 @@ package de.k3b.android.androFotoFinder.directory; +import android.animation.ValueAnimator; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -29,12 +30,14 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Handler; import android.support.annotation.NonNull; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; @@ -147,6 +150,10 @@ protected void onProgressUpdate(Integer... values) { private Button mCmdOk = null; private Button mCmdPopup = null; + // #127: Folderpicker: moving pathbar makes it discoverable. stop animation once the pathbar is touched + private boolean showPathBarAnimation = Global.showPathBarAnimation; + private ValueAnimator mPathbarAnimation = null; + private View.OnClickListener mPathButtonClickHandler; private View.OnLongClickListener mPathButtonLongClickHandler = null; // local data @@ -227,6 +234,7 @@ public void onClick(View v) { mPathButtonLongClickHandler = new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { + showPathBarAnimation = false; onShowPopUp(v, (IDirectory) v.getTag()); return true; } @@ -235,6 +243,15 @@ public boolean onLongClick(View v) { this.mParentPathBar = (LinearLayout) view.findViewById(R.id.parent_owner); this.mParentPathBarScroller = (HorizontalScrollView) view.findViewById(R.id.parent_scroller); + this.mParentPathBarScroller.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + animationPathBarStop(); + // #127: stop animation once the pathbar is touched + showPathBarAnimation = false; + return false; // assume that the event is not handled yet so button can do it-s function + } + }); mTreeView = (ExpandableListView)view.findViewById(R.id.directory_tree); mTreeView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @@ -825,6 +842,9 @@ private void onParentPathBarButtonClick(IDirectory selectedChild) { Log.d(TAG, debugPrefix + "onParentPathBarButtonClick(" + selectedChild.getAbsolute() + ")"); + showPathBarAnimation = false; + animationPathBarStop(); + // naviationchange only if there are children below child IDirectory newGrandParent = ((selectedChild != null) && (Directory.getChildCount(selectedChild) > 0)) ? selectedChild.getParent() : null; List siblings = (newGrandParent != null) ? newGrandParent.getChildren() : null; @@ -915,6 +935,7 @@ private void updateParentPathBar(IDirectory selectedChild) { // scroll to right where deepest child is mParentPathBarScroller.requestChildFocus(mParentPathBar, first); + } if (mImage != null) { @@ -924,6 +945,47 @@ private void updateParentPathBar(IDirectory selectedChild) { this.mCurrentSelection = selectedChild; updateStatus(); + + if (showPathBarAnimation) { + new Handler().postDelayed(new Runnable() { + public void run() { + // start animation after some delay + animationPathBarInit(); + } + }, 800); + } + } + + // #127: Folderpicker: moving pathbar makes it discoverable. stop animation once the pathbar is touched + private void animationPathBarInit() { + animationPathBarStop(); + + if (showPathBarAnimation) { + int delta = mParentPathBar.getWidth() - mParentPathBarScroller.getWidth(); + if (delta > 0) { + mPathbarAnimation = ValueAnimator.ofInt(delta, 0); + mPathbarAnimation.setDuration(5000); // 5 from right to left seconds + mPathbarAnimation.setRepeatCount(ValueAnimator.INFINITE); + mPathbarAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator updatedAnimation) { + int x = (int) updatedAnimation.getAnimatedValue(); + mParentPathBarScroller.smoothScrollTo(x, 0); + } + }); + mPathbarAnimation.setRepeatMode(ValueAnimator.REVERSE); + mPathbarAnimation.start(); + } + } + } + + // #127: Folderpicker: moving pathbar makes it discoverable. stop animation once the pathbar is touched + private void animationPathBarStop() { + if (mPathbarAnimation != null) { + mPathbarAnimation.end(); + mPathbarAnimation.removeAllUpdateListeners(); + mPathbarAnimation = null; + } } private void updateBitmap(int iconID) { From 6851f24584da86356861ae3d389907d6897c422c Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Sun, 23 Sep 2018 11:36:11 +0200 Subject: [PATCH 02/11] Fixed: Could not start media scanner from gallery menu --- app/src/main/java/de/k3b/android/util/AndroidFileCommands.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/de/k3b/android/util/AndroidFileCommands.java b/app/src/main/java/de/k3b/android/util/AndroidFileCommands.java index 67c026c1..9a829140 100644 --- a/app/src/main/java/de/k3b/android/util/AndroidFileCommands.java +++ b/app/src/main/java/de/k3b/android/util/AndroidFileCommands.java @@ -342,10 +342,10 @@ private static class MediaScannerDirectoryPickerFragment extends DirectoryPicker @Override protected void onDirectoryPick(IDirectory selection) { - dismiss(); if ((mParent != null) && (selection != null)) { mParent.onMediaScannerAnswer(selection.getAbsolute()); } + dismiss(); } @Override From dd3836f826d51de85022a2daa6180a2c4d8b1cdb Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Sun, 30 Sep 2018 16:15:10 +0200 Subject: [PATCH 03/11] #21: ru by Sergey (LegionAnon) --- app/src/main/res/values-ru/strings.xml | 184 ++++++++++++------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1d59fab2..e3063a6f 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -41,109 +41,109 @@ Удалить фото? Удалено %1$d/%2$d файлов Копирование направления - Move destination + Переместить пункт назначения Детали Выберите редактор фотографий Редактор фотографий не найден Редактировать - "writeprotected \'%1$s\'. + "права защищены\" \'%1$s\'. -\'%2$s\' is not possible." - \'%1$s\' is not a valid date. - \'%1$s\' is not a valid coordinate. +\'%2$s\' это невозможно." + \'%1$s\' некорректная дата. + \'%1$s\' некорректные координаты. Фильтр - Select %1$s - Loading folder %1$s failed + Выбрано %1$s + Загрузка папки %1$s не удалась Фильтр папок Фото Показать на карте - View in external geo app - Set geo - Changing geo info in selected photos - No geo picker found - Select new geo for photo + Просмотр во внешнем геоприложении + Установить гео + Изменение геоинформации на выбранных фотографиях + Не найдено ни одного геосборщика + Выберите новое геоположение для фото Ошибка SQL \'%1$s\' \n\n%2$s - Invalid SQL. Reloading default - System error. Exiting + Недопустимый SQL. Перезагрузка по умолчанию + Системная ошибка. Выход Файл «%1$s» уже существует. \n Вы действительно хотите перезаписать его? Не удается переименовать файл «%1$s». - No photos found for %1$s. - Photo not found in media database %1$s yet. Scanning %2$d new files. The missing photo will be available soon. + Нет фотографий в %1$s. + Фото пока не найдено в базе данных мультимедиа% %1$s. Сканирование %2$d новых файлов. Отсутствующее фото будет доступно в ближайшее время. "Загрузка (%1$d)…" - Updated %1$d photos. + Обновлены фотографии %1$d. Дата Шир Долг - Path - With no geo info + Путь + Без геоинформации новая_папка Создать папку - Cannot create %1$s - Created %1$s + Невозможно создать %1$s + Создано %1$s Подробнее… Переместить - Moved %1$d/%2$d files - Map Tiles © OpenStreetMap contributors + Перемещенные файлы %1$d/%2$d + Карта плитки © OpenStreetMap авторы Перезаписать? Переименовать - Renamed %1$d/%2$d files - Where to start scanning? - Cannot process photo files while Android-s media scanner is busy. Try again later. + Переименованные файлы %1$d/%2$d + С чего начать сканирование? + Не удается обработать файлы фотографий, пока сканер мультимедиа Android занят. Попробуйте позже. Медиа-сканер - Updated %1$d Media Database Items - %1$d Selected - Select folder to load pictures from and click ok + Обновлено %1$d Объекты базы данных мультимедиа + Выбрано %1$d + Выберите папку для загрузки изображений и нажмите Ок Только выбранные - Selection: Add all visible - Selection: Remove all visible + Выбор: добавить все видимые + Выбор: Удалить все видимые Диагностика - … containing executed SQL. - … containing gridview/listview Items. + … содержащий выполненный SQL. + … содержащие элементы gridview/listview. Логировать потребление памяти - LogCat jpg/xmp metadata read/write + Чтение/запись метаданных LogCat jpg/xmp … of 3rd party libraries. - LogCat misc. - … containing other log messages. + LogCat разное. + … содержащие другие сообщения журнала. Очистить лог Сохранить лог в файл - Errorlog folder - Auto hide actionbar after millisecs - Initial photo-view in better quality (slow, needs more memory) - Improve initial photo-view quality - Slideshow interval in millisecs + Ошибка журнала ошибок папки + Автоматическое скрытие панели действий после миллисекунды + Первоначальный фото-просмотр в лучшем качестве (медленный, требуется больше памяти) + Улучшение начального качества фотосъемки + Интервал слайд-шоу в миллисекундах Язык По умолчанию - Max. selected markers in map - Set geo history count - Set geo history file - Clear multi-selection after action - Copy, move, rename, etc. + Максимум выбранных маркеров на карте + Задать счет геоистории + Установить файл геоинформации + Очистить мултивыбор после действия + Копировать, переместить, переименовать и т. Д. Настройки - No share/send provider found - Too many items selected to share at once - Share/Send - Show in new gallery + Не найдено ни одного поставщика отправки + Слишком много элементов, выбранных для совместного использования + Поделиться/Отправить + Показать в новой галерее Слайд-шоу Дата - Folder - Name - File path length - Unsorted - Place - Sort - Updated %1$d/%2$d files - Zoom to fit - Show thumbnail for big images - Show thumbnail in image detail view if image width or height is bigger than this value (pixels). Memory efficient, fast, but low quality. - Thumbnail folder + Папка + Имя + Длина пути к файлу + Без сортировки + Место + Сортировать + Обновление %1$d/%2$d файлов + Масштаб по размеру + Показать эскиз для больших изображений + Показывать эскиз изображения в изображении, если ширина или высота изображения больше этого значения (в пикселях). Память эффективная, быстрая, но низкая. + Режим миниатюр Использовать оффлайн-карту Mapsforge ... которую вы вручную загрузили с ПК - Mapsforge offline Folder - Show Photo(s) - Repair duplicates + Оффлайн папка Mapsforge + Показать фото(ы) + Восстановить дубликаты Pick Geo from Photo Pick Geo from Map - Hide Images + Скрыть изображения "Are you sure? Do you want to make all media files (photo, video, audio) below @@ -156,42 +156,42 @@ You can undo hiding by calling the mediascanner from gallery-menu." Part of Folder or Filename. %=Wildcard Найти Part of Tags, Title, Description or Path - Public Image + Общедоступное изображение Приватное изображение Без тегов - +Tags - -Tags - Tag - Tag Filter - Type here to filter ... - No matching tags found - Set Tags + +Теги + -Теги + Тег + Фильтр По Метке + Введите здесь для фильтрации... + Не найдено совпадающих тегов + Установить тег Создать новый тег новый_тег - Delete children - Update tags in affected photos - Long-Tap on tagname opens menu - Activities,People,Places,Themes,Projects - Write changes to + Удаление дочерних объектов + Обновление тегов в затронутых фотографиях + Долгое нажатие открывает меню имени тега + Виды деятельности, Люди, Места, Темы, Проекты + Внести изменения в jpg and xmp (Create if not found) jpg (and xmp if exists) - jpg file only - xmp file only + только jpg файл + только xmp файл Long Xmp Sidecar File Name? Long: file.jpg.xmp; Short: file.xmp Load Context ... - Edit Exif - Title - Description + Редактировать Exif + Название + Описание Рейтинг Рейтинг Последнее изменение Edit Photo Autoprocessing - Filename Pattern + Шаблон имени файла Exif Видимость - App protected/pinned - App unprotect/unpinned + Приложение защищено/закреплено + Приложение незащищено/откреплено Rename private *.jpg to *.jpg-p Очистить - Open in Filemanager + Открыть в файловом менеджере - Searchbar - Date Picker: use decades - I.E. Put 2010, 2011,...2019 below 2010* - Date Filter + Панель поиска + Выбор даты: используйте десятилетия + I.E. Положите 2010, 2011,... 2019 ниже 2010 * + По дате - Edit Virtual Album + Редактировать виртуальный альбом - Load Context ... + Загрузка Контекста ... Редактировать Exif Название @@ -190,7 +176,6 @@ You can undo hiding by calling the mediascanner from gallery-menu." Рейтинг Последнее изменение - Edit Photo Autoprocessing Шаблон имени файла Exif - "%1$s %2$d Photos\n\t%3$s (%4$s), …\nTo %5$s\n\t%6$s" Размер Ширина @@ -208,7 +192,7 @@ You can undo hiding by calling the mediascanner from gallery-menu." Приложение защищено/закреплено Приложение незащищено/откреплено - Rename private *.jpg to *.jpg-p + Переименуйте приватное *.jpg в *.jpg-p Очистить Открыть в файловом менеджере From e160493238e56306ee83af64460cc83da808c7b6 Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Wed, 24 Oct 2018 16:34:00 +0200 Subject: [PATCH 09/11] #129: GalleryView fixed wrong image orientation for non-cached thumbnails --- .../androFotoFinder/ThumbNailUtils.java | 40 +++++++++++++++++-- .../gallery/cursor/GalleryCursorAdapter.java | 8 +++- .../cursor/GalleryCursorAdapterFromArray.java | 8 +++- .../ImagePagerAdapterFromCursor.java | 4 +- .../androFotoFinder/queries/FotoSql.java | 5 ++- .../java/de/k3b/android/util/DBUtils.java | 5 +++ .../java/de/k3b/media/ExifInterfaceEx.java | 33 ++++++--------- .../java/de/k3b/media/JpgMetaWorkflow.java | 21 +--------- .../src/main/java/de/k3b/media/MediaUtil.java | 21 ++++++++++ 9 files changed, 97 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/ThumbNailUtils.java b/app/src/main/java/de/k3b/android/androFotoFinder/ThumbNailUtils.java index a6bf692f..628d009c 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/ThumbNailUtils.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/ThumbNailUtils.java @@ -21,6 +21,8 @@ import android.content.Context; import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.util.Log; import android.widget.ImageView; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; @@ -36,6 +38,7 @@ import java.io.IOException; import de.k3b.android.androFotoFinder.queries.FotoSql; +import de.k3b.media.MediaUtil; /** * Service facade hiding com.nostra13.universalimageloader @@ -47,7 +50,7 @@ public class ThumbNailUtils { public static final String LOG_TAG = "ImageLoader"; public static final int MAX_CACHE_SIZE_50MB = 50 * 1024 * 1024; public static final int MAX_FILE_COUNT = 1024; - public static boolean DEBUG = false; + public static boolean DEBUG = false; // in settings via debugEnableLibs public static void init(Context context, File previousCacheRoot) { @@ -104,14 +107,45 @@ private static DisplayImageOptions createThumbnailOptions() { private static final DisplayImageOptions mDisplayImageOptions = ThumbNailUtils.createThumbnailOptions(); public static void getThumb(int iconID, ImageView imageView) { - ImageLoader.getInstance().displayImage( FotoSql.getUriString(iconID), imageView, mDisplayImageOptions); + String uriString = FotoSql.getUriString(iconID); + displayImageImpl(uriString, imageView, "iconID:", iconID); } public static void getThumb(String fullPath, ImageView imageView) { if ((imageView != null) && (fullPath != null) && (fullPath.length() > 0)) { - ImageLoader.getInstance().displayImage("file://" + fullPath, imageView, mDisplayImageOptions); + String uriString = "file://" + fullPath; + displayImageImpl(uriString, imageView, "fullPath:" , fullPath); } } + private static void displayImageImpl(String uriString, ImageView imageView, String debugContext, Object debugParam) { + if (ThumbNailUtils.DEBUG && Global.debugEnabledViewItem) { + Log.i(ThumbNailUtils.LOG_TAG, "displayImageImpl " + uriString + + " because of " + debugContext + debugParam); + } + + ImageLoader.getInstance().displayImage(uriString, imageView, mDisplayImageOptions); + } + + /** @param exifOrientationCode either code 0..8 or rotation angle 0, 90, 180, 270 */ + public static Bitmap rotateBitmap(Bitmap source, int exifOrientationCode) { + if (exifOrientationCode != 0) { + int angle = MediaUtil.exifOrientationCode2RotationDegrees(exifOrientationCode, exifOrientationCode); + + if (ThumbNailUtils.DEBUG && Global.debugEnabledViewItem) { + Log.i(ThumbNailUtils.LOG_TAG, "rotateBitmap code=" + exifOrientationCode + + " ==> " + angle); + } + + if (angle != 0) { + Matrix matrix = new Matrix(); + matrix.postRotate(angle); + return Bitmap.createBitmap(source, 0, 0, source.getWidth(), + source.getHeight(), matrix, true); + } + } + return source; + } + } diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapter.java b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapter.java index 2b95486d..d6cfef76 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapter.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapter.java @@ -22,7 +22,9 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; +import android.graphics.Bitmap; import android.net.Uri; +import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -128,6 +130,9 @@ public void bindView(View view, Context context, Cursor cursor) { imageSize = DBUtils.getLong(cursor, FotoSql.SQL_COL_SIZE, 0); } + // either code 0..8 or rotation angle 0, 90, 180, 270 + int exifOrientationCode = DBUtils.getInt(cursor, FotoSql.SQL_COL_ORIENTATION, 0); + holder.filter = DBUtils.getString(cursor, FotoSql.SQL_COL_WHERE_PARAM, null); String description = DBUtils.getString(cursor, FotoSql.SQL_COL_DISPLAY_TEXT, ""); @@ -143,7 +148,8 @@ public void bindView(View view, Context context, Cursor cursor) { if ((imageSize > 0) && (imageSize <= Global.imageDetailThumbnailIfBiggerThan)) { try { // #53, #83 Optimisation: no need for thumbnail - saves cache memory but may throw OutOfMemoryError - holder.image.setImageBitmap(HugeImageLoader.loadImage(new File(uri), MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION)); + Bitmap bitmap = HugeImageLoader.loadImage(new File(uri), MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION); + holder.image.setImageBitmap(ThumbNailUtils.rotateBitmap(bitmap, exifOrientationCode)); } catch (OutOfMemoryError err) { ThumbNailUtils.getThumb(uri, holder.image); } diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapterFromArray.java b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapterFromArray.java index 0da48219..c364f7cc 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapterFromArray.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/gallery/cursor/GalleryCursorAdapterFromArray.java @@ -22,6 +22,7 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; +import android.graphics.Bitmap; import android.net.Uri; import android.util.Log; import android.view.View; @@ -36,6 +37,8 @@ import de.k3b.android.util.MediaScanner; import de.k3b.io.collections.SelectedFiles; import de.k3b.io.collections.SelectedItems; +import de.k3b.media.ExifInterface; +import de.k3b.media.ExifInterfaceEx; /** * Created by k3b on 30.05.2016. @@ -108,8 +111,9 @@ public View getView(int position, View convertView, ViewGroup parent) { holder.url = fullPhotoPathFromArray; final File file = new File(fullPhotoPathFromArray); - ThumbNailUtils.getThumb(fullPhotoPathFromArray, holder.image); - holder.image.setImageBitmap(HugeImageLoader.loadImage(file, 32,32)); + int exifOrientationCode = ExifInterfaceEx.getOrientationId (fullPhotoPathFromArray); + Bitmap bitmap = HugeImageLoader.loadImage(file, 32, 32); + holder.image.setImageBitmap(ThumbNailUtils.rotateBitmap(bitmap, exifOrientationCode)); holder.image.setImageURI(Uri.parse(holder.url)); holder.imageID = this.getImageId(position); diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/imagedetail/ImagePagerAdapterFromCursor.java b/app/src/main/java/de/k3b/android/androFotoFinder/imagedetail/ImagePagerAdapterFromCursor.java index 7ffbd4a4..57a8aea0 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/imagedetail/ImagePagerAdapterFromCursor.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/imagedetail/ImagePagerAdapterFromCursor.java @@ -308,7 +308,9 @@ protected View createViewWithContent(int position, ViewGroup container, String f try { // #53 Optimisation: no need for thumbnail - saves cache memory but may throw OutOfMemoryError loadType = "image small enough "; - photoView.setImageBitmap(HugeImageLoader.loadImage(imageFile, MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION)); + Bitmap bitmap = HugeImageLoader.loadImage(imageFile, MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION); + // rotation is done by photoView + photoView.setImageBitmap(bitmap); photoView.setImageReloadFile(null); photoView.setDebugPrefix(imageFile.getName()); } catch (OutOfMemoryError err) { diff --git a/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java b/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java index 0e8281d3..bb88513d 100644 --- a/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java +++ b/app/src/main/java/de/k3b/android/androFotoFinder/queries/FotoSql.java @@ -126,6 +126,8 @@ public class FotoSql extends FotoSqlBase { public static final String SQL_COL_EXT_RATING = MediaStore.Video.Media.BOOKMARK; public static final String SQL_COL_PATH = MediaStore.Images.Media.DATA; + // either code 0..8 or rotation angle 0, 90, 180, 270 + public static final String SQL_COL_ORIENTATION = MediaStore.Images.ImageColumns.ORIENTATION; // only works with api >= 16 public static final String SQL_COL_MAX_WITH = @@ -289,7 +291,8 @@ public static QueryParameter getQueryGroupByPlace(double groupingFactor) { SQL_COL_MAX_WITH + " AS " + SQL_COL_WIDTH, SQL_COL_GPS, SQL_COL_DATE_TAKEN, - SQL_COL_PATH}; + SQL_COL_PATH, + SQL_COL_ORIENTATION}; public static final QueryParameter queryDetail = new QueryParameter() .setID(QUERY_TYPE_GALLERY) diff --git a/app/src/main/java/de/k3b/android/util/DBUtils.java b/app/src/main/java/de/k3b/android/util/DBUtils.java index 9dc5abda..aefac9a2 100644 --- a/app/src/main/java/de/k3b/android/util/DBUtils.java +++ b/app/src/main/java/de/k3b/android/util/DBUtils.java @@ -55,4 +55,9 @@ public static long getLong(Cursor cursor, String colId, long notFoundValue) { int columnIndex = (cursor == null) ? -1 : cursor.getColumnIndex(colId); return (columnIndex == -1) ? notFoundValue : cursor.getLong(columnIndex); } + + public static int getInt(Cursor cursor, String colId, int notFoundValue) { + int columnIndex = (cursor == null) ? -1 : cursor.getColumnIndex(colId); + return (columnIndex == -1) ? notFoundValue : cursor.getInt(columnIndex); + } } diff --git a/fotolib2/src/main/java/de/k3b/media/ExifInterfaceEx.java b/fotolib2/src/main/java/de/k3b/media/ExifInterfaceEx.java index 15e6c0e7..cd080098 100644 --- a/fotolib2/src/main/java/de/k3b/media/ExifInterfaceEx.java +++ b/fotolib2/src/main/java/de/k3b/media/ExifInterfaceEx.java @@ -379,33 +379,24 @@ public IMetaApi setRating(Integer value) { return this; } + public static int getOrientationId(String fullPath) { + try { + return new ExifInterfaceEx(fullPath, null, null, "getOrientationId").getOrientationId(); + } catch (IOException e) { + } + return 0; + } + /** return the image orinentation as id (one of the ORIENTATION_ROTATE_XXX constants) */ - private int getOrientationId() { + public int getOrientationId() { return getAttributeInt( - ExifInterfaceEx.TAG_ORIENTATION, -1); + ExifInterfaceEx.TAG_ORIENTATION, 0); } - private static final int ORIENTATION_ROTATE_180 = 3; - private static final int ORIENTATION_ROTATE_90 = 6; // rotate 90 cw to right it - private static final int ORIENTATION_ROTATE_270 = 8; // rotate 270 to right it - /** return image orinentation in degrees (0, 90,180,270) or 0 if inknown */ public int getOrientationInDegrees() { - int orientation = getOrientationId(); - if (orientation != -1) { - // We only recognize a subset of orientation tag values. - int degree; - switch (orientation) { - case ExifInterfaceEx.ORIENTATION_ROTATE_90: - return 90; - case ExifInterfaceEx.ORIENTATION_ROTATE_180: - return 180; - case ExifInterfaceEx.ORIENTATION_ROTATE_270: - return 270; - default: - } - } - return 0; + int orientationId = getOrientationId(); + return MediaUtil.exifOrientationCode2RotationDegrees(orientationId, orientationId); } protected Date getAttributeDate(String tag) { diff --git a/fotolib2/src/main/java/de/k3b/media/JpgMetaWorkflow.java b/fotolib2/src/main/java/de/k3b/media/JpgMetaWorkflow.java index b4573848..f2280e4c 100644 --- a/fotolib2/src/main/java/de/k3b/media/JpgMetaWorkflow.java +++ b/fotolib2/src/main/java/de/k3b/media/JpgMetaWorkflow.java @@ -210,20 +210,6 @@ private StringBuilder createDebugStringBuilder(File filePath) { return new StringBuilder(); } - - // Translate exif-orientation code (0..8) to exifOrientationCode2RotationDegrees (clockwise) - // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html - private static final short[] exifOrientationCode2RotationDegrees = { - 0, // EXIF Orientation constants: - 0, // 1 = Horizontal (normal) - 0, // 2 = (!) Mirror horizontal - 180, // 3 = Rotate 180 - 180, // 4 = (!) Mirror vertical - 90, // 5 = (!) Mirror horizontal and rotate 270 CW - 90, // 6 = Rotate 90 CW - 270, // 7 = (!) Mirror horizontal and rotate 90 CW - 270}; // 8 = Rotate 270 CW - /** * Get necessary rotation for image file from exif. * @@ -234,15 +220,12 @@ public static int getRotationFromExifOrientation(String fullPathToImageFile) { try { ExifInterfaceEx exif = new ExifInterfaceEx(fullPathToImageFile, null, null, "getRotationFromExifOrientation"); if (exif.isValidJpgExifFormat()) { - int orientation = exif.getAttributeInt(ExifInterfaceEx.TAG_ORIENTATION, 0); - if ((orientation >= 0) && (orientation < exifOrientationCode2RotationDegrees.length)) - return exifOrientationCode2RotationDegrees[orientation]; + + return MediaUtil.exifOrientationCode2RotationDegrees(exif.getAttributeInt(ExifInterfaceEx.TAG_ORIENTATION, 0), 0); } } catch (Exception e) { } return 0; } - - } diff --git a/fotolib2/src/main/java/de/k3b/media/MediaUtil.java b/fotolib2/src/main/java/de/k3b/media/MediaUtil.java index 371bb179..b78b473f 100644 --- a/fotolib2/src/main/java/de/k3b/media/MediaUtil.java +++ b/fotolib2/src/main/java/de/k3b/media/MediaUtil.java @@ -69,6 +69,20 @@ public static enum FieldID { visibility, }; + + // Translate exif-orientation code (0..8) to EXIF_ORIENTATION_CODE_2_ROTATION_DEGREES (clockwise) + // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html + private static final short[] EXIF_ORIENTATION_CODE_2_ROTATION_DEGREES = { + 0, // EXIF Orientation constants: + 0, // 1 = Horizontal (normal) + 0, // 2 = (!) Mirror horizontal + 180, // 3 = Rotate 180 + 180, // 4 = (!) Mirror vertical + 90, // 5 = (!) Mirror horizontal and rotate 270 CW + 90, // 6 = Rotate 90 CW + 270, // 7 = (!) Mirror horizontal and rotate 90 CW + 270}; // 8 = Rotate 270 CW + /** translates FieldID to text. In android this is implemented via resource id */ public interface ILabelGenerator { String get(FieldID id); @@ -400,4 +414,11 @@ public boolean accept(File dir, String filename) { } }; + /** @param exifOrientationCode either code 0..8 or rotation angle 0, 90, 180, 270 */ + public static int exifOrientationCode2RotationDegrees(int exifOrientationCode, int notFoundValue) { + if ((exifOrientationCode >= 0) && (exifOrientationCode < EXIF_ORIENTATION_CODE_2_ROTATION_DEGREES.length)) { + return EXIF_ORIENTATION_CODE_2_ROTATION_DEGREES[exifOrientationCode]; + } + return notFoundValue; + } } \ No newline at end of file From a377924ccf509f559ca9e5ba0424d47d7094d87c Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Wed, 24 Oct 2018 17:13:07 +0200 Subject: [PATCH 10/11] fixed build error --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e45fde73..ad47ec8e 100644 --- a/build.gradle +++ b/build.gradle @@ -2,8 +2,8 @@ buildscript { repositories { - jcenter() google() + jcenter() // mavenCentral() } dependencies { From 61fa7293a543bcd56fc2b36920745159a372efa1 Mon Sep 17 00:00:00 2001 From: k3b <1374583+k3b@users.noreply.github.com> Date: Wed, 24 Oct 2018 19:15:00 +0200 Subject: [PATCH 11/11] prepare v0.7.2.181027 (40) Bugfixes: image orientation, media scanner --- README.md | 2 +- app/build.gradle | 5 ++-- app/src/main/res/values/donottranslate.xml | 28 +++++++++++-------- .../metadata/android/en-US/changelogs/39.txt | 2 +- .../metadata/android/en-US/changelogs/40.txt | 6 ++++ .../metadata/android/en-US/changelogs/41.txt | 2 ++ translation-history.ini | 10 +++---- 7 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/40.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/41.txt diff --git a/README.md b/README.md index 29fa6625..1a925f94 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Privacy: * Geotagging: Shows photos in a [geographic map](https://github.com/k3b/APhotoManager/wiki/geographic-map) from [openstreetmap](http://www.openstreetmap.org) * Buildin file manager for photos: find, sort, view, copy, delete, Show in map, set gps exif data, send, edit exif, ... . * Fast [find](https://github.com/k3b/APhotoManager/wiki/Filter-View) local photos by (sub-)folder, date, [geographic map](https://github.com/k3b/APhotoManager/wiki/geographic-map)or [tags (keywords)](https://github.com/k3b/APhotoManager/wiki/Tags). -* [Translations](https://crowdin.com/project/AndroFotoFinder):  ar, deenitfrja, nl, pl, ro, ru trzh-CNzh-TW +* [Translations](https://crowdin.com/project/AndroFotoFinder):  ar, deenitfrja, nl, pl, ro, ru trukzh-CNzh-TW * [![Crowdin](https://d322cqt584bo4o.cloudfront.net/androFotoFinder/localized.svg)](https://crowdin.com/project/androFotoFinder)Help us to translate into other languages. --- diff --git a/app/build.gradle b/app/build.gradle index f787f61a..a427725f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,9 +51,10 @@ android { // 0.6.9.180813 (37) public betta: Searchbar, vitual-folder, new icons // 0.7.0.180823 (38) Searchbar, vitual-folder, new icons // 0.7.1.180830 (39) Bugfix for 38; translation uk + // 0.7.2.181027 (40) Bugfixes: image orientation, media scanner - versionCode = 39 - versionName = '0.7.1.180830' + versionCode = 40 + versionName = '0.7.2.181027' } compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 7b71f5ef..875bad4d 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -181,17 +181,23 @@ this program. If not, see
Translations supported crowdin.com
Android is a trademark of Google Inc. Use of this trademark is subject to Google Permissions.
diff --git a/fastlane/metadata/android/en-US/changelogs/39.txt b/fastlane/metadata/android/en-US/changelogs/39.txt index 9e0ef423..980651d6 100644 --- a/fastlane/metadata/android/en-US/changelogs/39.txt +++ b/fastlane/metadata/android/en-US/changelogs/39.txt @@ -8,4 +8,4 @@ Changes from 0.6.4 to 0.7.0 * New Logo/Icons. * New Virutal Albums/".album" files. * New search bar and "Filter by Date". -* Translation updates: ar,de,en,es,fr,it,ja,ru,tr,zh-CN (7 = 100%, 5 > 90%, 5 < 65% \ No newline at end of file +* Translation updates: ar,de,en,es,fr,it,ja,ru,tr,zh-CN (7 = 100%, 5 > 90%, 5 < 65%) \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/40.txt b/fastlane/metadata/android/en-US/changelogs/40.txt new file mode 100644 index 00000000..9a8c07d0 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40.txt @@ -0,0 +1,6 @@ +Changes from 0.7.1 to 0.7.2 + +* Fixed: Some images where shown with wrong orientation +* Fixed: Could not start media scanner from gallery menu +* Folderpicker: animated pathbar makes it discoverable. +* updated translation: uk (100%), ru (95%) diff --git a/fastlane/metadata/android/en-US/changelogs/41.txt b/fastlane/metadata/android/en-US/changelogs/41.txt new file mode 100644 index 00000000..88af999e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/41.txt @@ -0,0 +1,2 @@ +Changes from 0.7.2 to 0.7.3 + diff --git a/translation-history.ini b/translation-history.ini index d7c8da07..58304250 100644 --- a/translation-history.ini +++ b/translation-history.ini @@ -8,11 +8,12 @@ # ignore filedates before this. ignore=2099-08-20 -# generated on 2018-08-21 with de.k3b.translations.TranslationStatisticsTests#dupmpAsIni +# generated on 2018-10-24 with de.k3b.translations.TranslationStatisticsTests#dupmpAsIni # language;changed;translated by;app;fdroid;aboutbox;missing + ar=2018-08-20;Vitality, medowill;100%;100%;1; de=2018-04-08;k3b;100%;100%;1; -en=2018-08-13;;100%;100%;1; +en=2018-08-21;;100%;100%;1; es=2018-08-02;Andreaevangelina, Dani Certad (daniconejito);100%;100%;1; fr=2018-08-02;Poussinou, tuuux;100%;100%;1; hi=2018-03-12;jznsamuel (jasonsamuel88);3% (6/170);0% (0/3);0;about_summary, area_menu_title, background, bookmark, bookmark_delete_answer_format, bookmark_delete_error_format, bookmark_delete_question, bookmark_file_comment_format, bookmark_save_as_menu_title, btn_change, btn_pause, clear_menu_title, copy_result_format, date_picker_menu_title, delete_menu_title, delete_question_message_format, delete_question_title, delete_result_format, destination_copy, destination_move, details_menu_title, edit_chooser_title, edit_err_editor_not_found, edit_menu_title, exif_menu_title, file_err_writeprotected, filter_any_hint, filter_err_invalid_date_format, filter_err_invalid_location_format, filter_menu_title, filter_menu_title_album, filter_path_hint, fix_link_menu_title, folder_dialog_title_format, folder_err_load_failed_format, folder_hide_images_menu_title, folder_hide_images_question_message_format, folder_menu_title, gallery_title, geo_picker_err_not_found, geo_picker_title, geo_show_as_menu_title, global_err_sql_message_format, global_err_sql_title_reload, global_err_system, image_err_file_exists_format, image_err_file_rename_format, image_err_not_found_format, image_err_not_in_db_format, image_loading_at_position_format, image_success_update_format, lbl_any, lbl_date, lbl_description, lbl_exif, lbl_file_name_pattern, lbl_image_visibility, lbl_images_private, lbl_images_public, lbl_latitude_short, lbl_longitude_short, lbl_path, lbl_rating, lbl_tag, lbl_tags_exclude, lbl_tags_include, lbl_title, lbl_with_no_tags, menu_title_app_pinnend, menu_title_app_unpinnend, mk_dir_default, mk_dir_menu_title, mk_err_failed_format, mk_success_format, more_menu_title, move_menu_title, move_result_format, osm_cright_title, overwrite_question_title, photo_autoprocessing_edit_menu_title, preview_message_format, rename_menu_title, rename_result_format, scanner_dir_question, scanner_err_busy, scanner_menu_title, scanner_update_result_format, searchbar_menu_title, selected_only_menu_title, selection_add_all_menu_title, selection_none_hint, selection_remove_menu_title, selection_status_format, settings_bookmark_dir_title, settings_debug_clear_title, settings_debug_libs_summary, settings_debug_memory_title, settings_debug_meta_io, settings_debug_save_title, settings_debug_sql_summary, settings_debug_summary, settings_debug_title, settings_debug_view_item_summary, settings_geo_history_file_title, settings_geo_history_max_title, settings_group_debug_title, settings_image_hide_time_title, settings_image_initialImageDetailResolutionHigh_summary, settings_image_initialImageDetailResolutionHigh_title, settings_image_slideshow_intervall_title, settings_image_thumb_dir_title, settings_image_thumb_if_bigger_than_summary, settings_image_thumb_if_bigger_than_title, settings_locale_os_language, settings_locale_title, settings_log_folder_title, settings_map_selmarker_max_title, settings_maps_forge_dir_title, settings_maps_forge_enable_summary, settings_maps_forge_enable_tile, settings_media_update_strategy_jpg, settings_media_update_strategy_jpg_xmp_create, settings_media_update_strategy_jpg_xmp_update, settings_media_update_strategy_title, settings_media_update_strategy_xmp, settings_multisel_clear_summary, settings_multisel_clear_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, settings_title, settings_xmp_file_schema_summary, settings_xmp_file_schema_title, share_err_not_found, share_err_to_many, share_menu_title, show_in_filemanager_menu_title, show_in_gallery_menu_title, show_photo, slideshow_menu_title, sort_by_date, sort_by_file_size, sort_by_folder, sort_by_modification, sort_by_name, sort_by_name_len, sort_by_none, sort_by_place, sort_by_rating, sort_by_width, sort_menu_title, tags_activity_title, tags_add_default, tags_add_menu_title, tags_defaults, tags_delete_children_title, tags_edit_menu_title, tags_hint, tags_search_hint, tags_search_no_matching_items_found, tags_update_photos, update_result_format, view_context_menu_title, zoom_to_fit_menu_title @@ -23,9 +24,8 @@ nl=2017-09-11;ookikgavertalen, keunes;90% (153/170);0% (0/3);0;bookmark, clear_m pl=2018-03-12;Maselkowicz;64% (109/170);0% (0/3);0;bookmark, clear_menu_title, date_picker_menu_title, exif_menu_title, filter_any_hint, filter_menu_title_album, filter_path_hint, fix_link_menu_title, folder_hide_images_menu_title, folder_hide_images_question_message_format, geo_picker_from_map_title, geo_picker_from_photo_title, lbl_any, lbl_description, lbl_exif, lbl_file_name_pattern, lbl_image_visibility, lbl_images_private, lbl_images_public, lbl_rating, lbl_tag, lbl_tags_exclude, lbl_tags_include, lbl_title, lbl_with_no_tags, menu_title_app_pinnend, menu_title_app_unpinnend, photo_autoprocessing_edit_menu_title, preview_message_format, searchbar_menu_title, settings_debug_libs_summary, settings_debug_meta_io, settings_maps_forge_dir_title, settings_maps_forge_enable_summary, settings_maps_forge_enable_tile, settings_media_update_strategy_jpg, settings_media_update_strategy_jpg_xmp_create, settings_media_update_strategy_jpg_xmp_update, settings_media_update_strategy_title, settings_media_update_strategy_xmp, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, settings_xmp_file_schema_summary, settings_xmp_file_schema_title, show_in_filemanager_menu_title, show_photo, sort_by_file_size, sort_by_modification, sort_by_rating, sort_by_width, tags_activity_title, tags_add_default, tags_add_menu_title, tags_defaults, tags_delete_children_title, tags_edit_menu_title, tags_hint, tags_search_hint, tags_search_no_matching_items_found, tags_update_photos, view_context_menu_title pt-rBR=2017-03-18;thiagonkami, Nana13;22% (38/170);0% (0/3);0;bookmark, clear_menu_title, date_picker_menu_title, exif_menu_title, filter_any_hint, filter_menu_title_album, filter_path_hint, fix_link_menu_title, folder_hide_images_menu_title, folder_hide_images_question_message_format, geo_picker_from_map_title, geo_picker_from_photo_title, geo_picker_title, global_err_sql_message_format, global_err_sql_title_reload, image_err_file_exists_format, image_err_not_found_format, image_err_not_in_db_format, image_success_update_format, lbl_any, lbl_date, lbl_description, lbl_exif, lbl_file_name_pattern, lbl_image_visibility, lbl_images_private, lbl_images_public, lbl_latitude_short, lbl_longitude_short, lbl_path, lbl_rating, lbl_tag, lbl_tags_exclude, lbl_tags_include, lbl_title, lbl_with_no_geo, lbl_with_no_tags, menu_title_app_pinnend, menu_title_app_unpinnend, mk_dir_default, mk_dir_menu_title, mk_err_failed_format, mk_success_format, more_menu_title, move_menu_title, move_result_format, osm_cright_title, overwrite_question_title, photo_autoprocessing_edit_menu_title, preview_message_format, rename_menu_title, rename_result_format, scanner_dir_question, scanner_err_busy, scanner_menu_title, scanner_update_result_format, searchbar_menu_title, selected_only_menu_title, selection_add_all_menu_title, selection_none_hint, selection_remove_menu_title, selection_status_format, settings_bookmark_dir_title, settings_debug_clear_title, settings_debug_libs_summary, settings_debug_memory_title, settings_debug_meta_io, settings_debug_save_title, settings_debug_sql_summary, settings_debug_summary, settings_debug_title, settings_debug_view_item_summary, settings_geo_history_file_title, settings_geo_history_max_title, settings_group_debug_title, settings_image_hide_time_title, settings_image_initialImageDetailResolutionHigh_summary, settings_image_initialImageDetailResolutionHigh_title, settings_image_slideshow_intervall_title, settings_image_thumb_dir_title, settings_image_thumb_if_bigger_than_summary, settings_image_thumb_if_bigger_than_title, settings_locale_os_language, settings_locale_title, settings_log_folder_title, settings_map_selmarker_max_title, settings_maps_forge_dir_title, settings_maps_forge_enable_summary, settings_maps_forge_enable_tile, settings_media_update_strategy_jpg, settings_media_update_strategy_jpg_xmp_create, settings_media_update_strategy_jpg_xmp_update, settings_media_update_strategy_title, settings_media_update_strategy_xmp, settings_multisel_clear_summary, settings_multisel_clear_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, settings_title, settings_xmp_file_schema_summary, settings_xmp_file_schema_title, share_err_not_found, share_err_to_many, share_menu_title, show_in_filemanager_menu_title, show_in_gallery_menu_title, show_photo, slideshow_menu_title, sort_by_date, sort_by_file_size, sort_by_folder, sort_by_modification, sort_by_name, sort_by_name_len, sort_by_none, sort_by_place, sort_by_rating, sort_by_width, sort_menu_title, tags_activity_title, tags_add_default, tags_add_menu_title, tags_defaults, tags_delete_children_title, tags_edit_menu_title, tags_hint, tags_search_hint, tags_search_no_matching_items_found, tags_update_photos, update_result_format, view_context_menu_title, zoom_to_fit_menu_title ro=2016-01-20;mironeasav;30% (52/170);0% (0/3);1;bookmark, clear_menu_title, date_picker_menu_title, exif_menu_title, file_err_writeprotected, filter_any_hint, filter_menu_title_album, filter_path_hint, fix_link_menu_title, folder_hide_images_menu_title, folder_hide_images_question_message_format, geo_picker_from_map_title, geo_picker_from_photo_title, geo_show_as_menu_title, lbl_any, lbl_description, lbl_exif, lbl_file_name_pattern, lbl_image_visibility, lbl_images_private, lbl_images_public, lbl_latitude_short, lbl_longitude_short, lbl_path, lbl_rating, lbl_tag, lbl_tags_exclude, lbl_tags_include, lbl_title, lbl_with_no_geo, lbl_with_no_tags, menu_title_app_pinnend, menu_title_app_unpinnend, mk_dir_default, mk_dir_menu_title, mk_err_failed_format, mk_success_format, more_menu_title, move_menu_title, move_result_format, osm_cright_title, overwrite_question_title, photo_autoprocessing_edit_menu_title, preview_message_format, rename_menu_title, rename_result_format, scanner_dir_question, scanner_err_busy, scanner_menu_title, scanner_update_result_format, searchbar_menu_title, selected_only_menu_title, selection_add_all_menu_title, selection_none_hint, selection_remove_menu_title, selection_status_format, settings_bookmark_dir_title, settings_debug_clear_title, settings_debug_libs_summary, settings_debug_memory_title, settings_debug_meta_io, settings_debug_save_title, settings_debug_sql_summary, settings_debug_summary, settings_debug_title, settings_debug_view_item_summary, settings_geo_history_file_title, settings_geo_history_max_title, settings_group_debug_title, settings_image_hide_time_title, settings_image_initialImageDetailResolutionHigh_summary, settings_image_initialImageDetailResolutionHigh_title, settings_image_slideshow_intervall_title, settings_image_thumb_dir_title, settings_image_thumb_if_bigger_than_summary, settings_image_thumb_if_bigger_than_title, settings_locale_os_language, settings_locale_title, settings_log_folder_title, settings_map_selmarker_max_title, settings_maps_forge_dir_title, settings_maps_forge_enable_summary, settings_maps_forge_enable_tile, settings_media_update_strategy_jpg, settings_media_update_strategy_jpg_xmp_create, settings_media_update_strategy_jpg_xmp_update, settings_media_update_strategy_title, settings_media_update_strategy_xmp, settings_multisel_clear_summary, settings_multisel_clear_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, settings_title, settings_xmp_file_schema_summary, settings_xmp_file_schema_title, share_err_not_found, share_err_to_many, share_menu_title, show_in_filemanager_menu_title, show_in_gallery_menu_title, show_photo, slideshow_menu_title, sort_by_date, sort_by_file_size, sort_by_modification, sort_by_rating, sort_by_width, tags_activity_title, tags_add_default, tags_add_menu_title, tags_defaults, tags_delete_children_title, tags_edit_menu_title, tags_hint, tags_search_hint, tags_search_no_matching_items_found, tags_update_photos, view_context_menu_title -ru=2018-07-28;Dmitry Zhgun (trupizzza), ku ku(2ku), "divizdev";34% (58/170);0% (0/3);0;bookmark, date_picker_menu_title, destination_copy, destination_move, exif_menu_title, file_err_writeprotected, filter_any_hint, filter_err_invalid_date_format, filter_err_invalid_location_format, filter_menu_title_album, filter_path_hint, fix_link_menu_title, folder_dialog_title_format, folder_err_load_failed_format, folder_hide_images_menu_title, folder_hide_images_question_message_format, folder_menu_title, geo_edit_menu_title, geo_edit_update_in_progress, geo_picker_err_not_found, geo_picker_from_map_title, geo_picker_from_photo_title, geo_picker_title, geo_show_as_menu_title, global_err_sql_title_reload, global_err_system, image_err_not_found_format, image_err_not_in_db_format, image_success_update_format, lbl_description, lbl_exif, lbl_file_name_pattern, lbl_images_private, lbl_images_public, lbl_path, lbl_tag, lbl_tags_exclude, lbl_tags_include, lbl_title, lbl_with_no_geo, menu_title_app_pinnend, menu_title_app_unpinnend, mk_err_failed_format, mk_success_format, more_menu_title, move_result_format, osm_cright_title, photo_autoprocessing_edit_menu_title, preview_message_format, rename_result_format, scanner_dir_question, scanner_err_busy, scanner_menu_title, scanner_update_result_format, searchbar_menu_title, selected_only_menu_title, selection_add_all_menu_title, selection_none_hint, selection_remove_menu_title, selection_status_format, settings_debug_libs_summary, settings_debug_meta_io, settings_debug_sql_summary, settings_debug_summary, settings_debug_title, settings_debug_view_item_summary, settings_geo_history_file_title, settings_geo_history_max_title, settings_image_hide_time_title, settings_image_initialImageDetailResolutionHigh_summary, settings_image_initialImageDetailResolutionHigh_title, settings_image_slideshow_intervall_title, settings_image_thumb_dir_title, settings_image_thumb_if_bigger_than_summary, settings_image_thumb_if_bigger_than_title, settings_map_selmarker_max_title, settings_maps_forge_dir_title, settings_media_update_strategy_jpg, settings_media_update_strategy_jpg_xmp_create, settings_media_update_strategy_jpg_xmp_update, settings_media_update_strategy_title, settings_media_update_strategy_xmp, settings_multisel_clear_summary, settings_multisel_clear_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, settings_xmp_file_schema_summary, settings_xmp_file_schema_title, share_err_not_found, share_err_to_many, share_menu_title, show_in_filemanager_menu_title, show_in_gallery_menu_title, show_photo, sort_by_folder, sort_by_name, sort_by_name_len, sort_by_none, sort_by_place, sort_by_width, sort_menu_title, tags_activity_title, tags_defaults, tags_delete_children_title, tags_edit_menu_title, tags_hint, tags_search_hint, tags_search_no_matching_items_found, tags_update_photos, update_result_format, view_context_menu_title, zoom_to_fit_menu_title +ru=2018-10-18;Dmitry Zhgun (trupizzza), ku ku(2ku), divizdev, Sergey (LegionAnon);95% (162/170);0% (0/3);0;filter_any_hint, filter_path_hint, folder_hide_images_question_message_format, photo_autoprocessing_edit_menu_title, preview_message_format, settings_media_update_strategy_jpg_xmp_create, settings_xmp_file_schema_summary, settings_xmp_file_schema_title tr=2018-03-12;Boyut, srkns, erdenerr;90% (154/170);0% (0/3);1;bookmark, clear_menu_title, date_picker_menu_title, filter_menu_title_album, lbl_exif, lbl_file_name_pattern, lbl_image_visibility, menu_title_app_pinnend, menu_title_app_unpinnend, photo_autoprocessing_edit_menu_title, preview_message_format, searchbar_menu_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, show_in_filemanager_menu_title, sort_by_width +uk=2018-08-27;Sergey (LegionAnon);100%;100%;1; zh-rCN=2018-08-20;Forbidden (cptbl00dra1n), Liu Feng (pitumaomao);100%;100%;1; zh-rTW=2017-11-22;Liu Feng (pitumaomao), rosatravels;92% (157/170);100%;1;bookmark, clear_menu_title, date_picker_menu_title, filter_menu_title_album, lbl_image_visibility, menu_title_app_pinnend, menu_title_app_unpinnend, searchbar_menu_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, settings_rename_private_jpg_title, show_in_filemanager_menu_title, sort_by_file_size, sort_by_width -zz=2018-03-12;k3b;95% (163/170);0% (0/3);0;bookmark, clear_menu_title, date_picker_menu_title, filter_menu_title_album, searchbar_menu_title, settings_pick_date_decade4year_summary, settings_pick_date_decade4year_title, show_in_filemanager_menu_title -