summaryrefslogtreecommitdiff
path: root/android/source
diff options
context:
space:
mode:
Diffstat (limited to 'android/source')
-rw-r--r--android/source/AndroidManifest.xml37
-rw-r--r--android/source/Makefile11
-rw-r--r--android/source/build.gradle105
-rw-r--r--android/source/gradle.properties3
-rw-r--r--android/source/gradle/wrapper/gradle-wrapper.jarbin49896 -> 63375 bytes
-rw-r--r--android/source/gradle/wrapper/gradle-wrapper.properties5
-rwxr-xr-xandroid/source/gradlew310
-rwxr-xr-xandroid/source/gradlew.bat66
-rw-r--r--android/source/ic_launcher-web.pngbin23194 -> 26399 bytes
-rw-r--r--android/source/lint-baseline.xml2341
-rw-r--r--android/source/lint.xml9
-rw-r--r--android/source/res/drawable-hdpi/action_search.pngbin1759 -> 0 bytes
-rw-r--r--android/source/res/drawable-hdpi/action_search_light.pngbin1764 -> 0 bytes
-rw-r--r--android/source/res/drawable-hdpi/ic_folder_48dp.xml5
-rw-r--r--android/source/res/drawable-hdpi/ic_keyboard.xml4
-rw-r--r--android/source/res/drawable-hdpi/lo_icon.pngbin1950 -> 0 bytes
-rw-r--r--android/source/res/drawable-mdpi/lo_icon.pngbin1180 -> 0 bytes
-rw-r--r--android/source/res/drawable-xxxhdpi/decrementindent.pngbin0 -> 962 bytes
-rw-r--r--android/source/res/drawable-xxxhdpi/ic_keyboard_black__24dp.png (renamed from android/source/res/drawable-xxxhdpi/ic_keyboard_black_24dp.png)bin301 -> 301 bytes
-rw-r--r--android/source/res/drawable-xxxhdpi/incrementindent.pngbin0 -> 912 bytes
-rw-r--r--android/source/res/drawable/calc.pngbin14818 -> 13611 bytes
-rw-r--r--android/source/res/drawable/draw.pngbin18445 -> 17013 bytes
-rw-r--r--android/source/res/drawable/ic_add_24dp.xml (renamed from android/source/res/drawable/ic_add_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_arrow_back_24dp.xml (renamed from android/source/res/drawable/ic_arrow_back_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_auto_color.xml10
-rw-r--r--android/source/res/drawable/ic_cloud_black_24dp.xml9
-rw-r--r--android/source/res/drawable/ic_content_copy_24dp.xml (renamed from android/source/res/drawable/ic_content_copy_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_content_cut_24dp.xml (renamed from android/source/res/drawable/ic_content_cut_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_content_paste_24dp.xml (renamed from android/source/res/drawable/ic_content_paste_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_decrementindent.xml3
-rw-r--r--android/source/res/drawable/ic_filter_list_24dp.xml (renamed from android/source/res/drawable/ic_filter_list_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_folder_24dp.xml (renamed from android/source/res/drawable/ic_folder_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_format_clear_24dp.xml (renamed from android/source/res/drawable/ic_format_clear_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_grid_off_24dp.xml (renamed from android/source/res/drawable/ic_grid_off_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_grid_on_24dp.xml (renamed from android/source/res/drawable/ic_grid_on_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_incrementindent.xml3
-rw-r--r--android/source/res/drawable/ic_insert_drive_file_black_24dp.xml7
-rw-r--r--android/source/res/drawable/ic_keyboard_backspace_black_24dp.xml9
-rw-r--r--android/source/res/drawable/ic_line.xml2
-rw-r--r--android/source/res/drawable/ic_menu_back.pngbin1900 -> 0 bytes
-rw-r--r--android/source/res/drawable/ic_rect.xml2
-rw-r--r--android/source/res/drawable/ic_sd_card_black_24dp.xml9
-rw-r--r--android/source/res/drawable/ic_settings_24dp.xml (renamed from android/source/res/drawable/ic_settings_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_sort_24dp.xml (renamed from android/source/res/drawable/ic_sort_black_24dp.xml)2
-rw-r--r--android/source/res/drawable/ic_storage_black_24dp.xml9
-rw-r--r--android/source/res/drawable/ic_usb_black_24dp.xml7
-rw-r--r--android/source/res/drawable/impress.pngbin13936 -> 15005 bytes
-rw-r--r--android/source/res/drawable/label_background.xml4
-rw-r--r--android/source/res/drawable/writer.pngbin15878 -> 15781 bytes
-rw-r--r--android/source/res/layout/about.xml11
-rw-r--r--android/source/res/layout/activity_directory_browser.xml6
-rw-r--r--android/source/res/layout/activity_document_browser.xml95
-rw-r--r--android/source/res/layout/activity_main.xml28
-rw-r--r--android/source/res/layout/file_explorer_grid_item.xml42
-rw-r--r--android/source/res/layout/file_grid.xml25
-rw-r--r--android/source/res/layout/file_list.xml20
-rw-r--r--android/source/res/layout/file_list_item.xml58
-rw-r--r--android/source/res/layout/fragment_directory_browser.xml71
-rw-r--r--android/source/res/layout/item_recent_files.xml1
-rw-r--r--android/source/res/layout/number_picker.xml4
-rw-r--r--android/source/res/layout/toolbar_bottom.xml47
-rw-r--r--android/source/res/layout/toolbar_color_picker.xml46
-rw-r--r--android/source/res/menu/context_menu.xml7
-rw-r--r--android/source/res/menu/main.xml28
-rw-r--r--android/source/res/menu/navigation_menu.xml35
-rw-r--r--android/source/res/menu/view_menu.xml54
-rw-r--r--android/source/res/mipmap-hdpi/ic_launcher.pngbin1529 -> 6202 bytes
-rw-r--r--android/source/res/mipmap-mdpi/ic_launcher.pngbin950 -> 1310 bytes
-rw-r--r--android/source/res/mipmap-xhdpi/ic_launcher.pngbin2158 -> 7033 bytes
-rw-r--r--android/source/res/mipmap-xxhdpi/ic_launcher.pngbin5007 -> 8868 bytes
-rw-r--r--android/source/res/mipmap-xxxhdpi/ic_launcher.pngbin7896 -> 11149 bytes
-rw-r--r--android/source/res/values-ab/strings.xml2
-rw-r--r--android/source/res/values-ast/strings.xml121
-rw-r--r--android/source/res/values-ca/strings.xml121
-rw-r--r--android/source/res/values-cs/strings.xml121
-rw-r--r--android/source/res/values-cy/strings.xml121
-rw-r--r--android/source/res/values-de/strings.xml128
-rw-r--r--android/source/res/values-dsb/strings.xml121
-rw-r--r--android/source/res/values-el/strings.xml121
-rw-r--r--android/source/res/values-es/strings.xml121
-rw-r--r--android/source/res/values-eu/strings.xml121
-rw-r--r--android/source/res/values-fa/strings.xml121
-rw-r--r--android/source/res/values-fi/strings.xml2
-rw-r--r--android/source/res/values-fr/strings.xml121
-rw-r--r--android/source/res/values-gl/strings.xml121
-rw-r--r--android/source/res/values-hsb/strings.xml121
-rw-r--r--android/source/res/values-hu/strings.xml121
-rw-r--r--android/source/res/values-hy/strings.xml121
-rw-r--r--android/source/res/values-ia/strings.xml78
-rw-r--r--android/source/res/values-in/strings.xml91
-rw-r--r--android/source/res/values-is/strings.xml121
-rw-r--r--android/source/res/values-it/strings.xml121
-rw-r--r--android/source/res/values-ja/strings.xml2
-rw-r--r--android/source/res/values-kk/strings.xml2
-rw-r--r--android/source/res/values-ne/strings.xml23
-rw-r--r--android/source/res/values-night/colors.xml6
-rw-r--r--android/source/res/values-nl/strings.xml121
-rw-r--r--android/source/res/values-pa/strings.xml118
-rw-r--r--android/source/res/values-pl/strings.xml121
-rw-r--r--android/source/res/values-pt-rBR/strings.xml121
-rw-r--r--android/source/res/values-pt/strings.xml121
-rw-r--r--android/source/res/values-sk/strings.xml22
-rw-r--r--android/source/res/values-sl/strings.xml121
-rw-r--r--android/source/res/values-tr/strings.xml128
-rw-r--r--android/source/res/values-uk/strings.xml121
-rw-r--r--android/source/res/values-zh-rTW/strings.xml121
-rw-r--r--android/source/res/values/arrays.xml47
-rw-r--r--android/source/res/values/colors.xml6
-rw-r--r--android/source/res/values/dimens.xml1
-rw-r--r--android/source/res/values/integers.xml6
-rw-r--r--android/source/res/values/strings.xml113
-rw-r--r--android/source/res/values/themes.xml7
-rw-r--r--android/source/res/xml/documentprovider_preferences.xml38
-rw-r--r--android/source/res/xml/libreoffice_preferences.xml31
-rw-r--r--android/source/src/java/org/libreoffice/AboutDialogFragment.java67
-rw-r--r--android/source/src/java/org/libreoffice/ColorPaletteAdapter.java20
-rw-r--r--android/source/src/java/org/libreoffice/ColorPickerAdapter.java86
-rw-r--r--android/source/src/java/org/libreoffice/DocumentPartViewListAdapter.java1
-rw-r--r--android/source/src/java/org/libreoffice/FontController.java91
-rw-r--r--android/source/src/java/org/libreoffice/FormattingController.java153
-rw-r--r--android/source/src/java/org/libreoffice/InvalidationHandler.java66
-rw-r--r--android/source/src/java/org/libreoffice/LOEvent.java9
-rw-r--r--android/source/src/java/org/libreoffice/LOKitInputConnectionHandler.java2
-rw-r--r--android/source/src/java/org/libreoffice/LOKitShell.java12
-rw-r--r--android/source/src/java/org/libreoffice/LOKitThread.java106
-rw-r--r--android/source/src/java/org/libreoffice/LOKitTileProvider.java217
-rw-r--r--android/source/src/java/org/libreoffice/LibreOfficeApplication.java4
-rw-r--r--android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java517
-rw-r--r--android/source/src/java/org/libreoffice/LocaleHelper.java3
-rw-r--r--android/source/src/java/org/libreoffice/PasswordDialogFragment.java6
-rw-r--r--android/source/src/java/org/libreoffice/PresentationActivity.java27
-rw-r--r--android/source/src/java/org/libreoffice/SearchController.java13
-rw-r--r--android/source/src/java/org/libreoffice/ThumbnailCreator.java2
-rw-r--r--android/source/src/java/org/libreoffice/TileProvider.java24
-rw-r--r--android/source/src/java/org/libreoffice/ToolbarController.java174
-rw-r--r--android/source/src/java/org/libreoffice/UNOCommandsController.java8
-rw-r--r--android/source/src/java/org/libreoffice/canvas/BitmapHandle.java2
-rw-r--r--android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java38
-rw-r--r--android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java2
-rw-r--r--android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java18
-rw-r--r--android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java128
-rw-r--r--android/source/src/java/org/libreoffice/storage/DocumentProviderSettingsActivity.java102
-rw-r--r--android/source/src/java/org/libreoffice/storage/IDocumentProvider.java70
-rw-r--r--android/source/src/java/org/libreoffice/storage/IFile.java116
-rw-r--r--android/source/src/java/org/libreoffice/storage/IOUtils.java56
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/BrowserSelectorActivity.java153
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserActivity.java42
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserFragment.java199
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/ExternalFile.java163
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/ExtsdDocumentsProvider.java175
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/IExternalDocumentProvider.java22
-rw-r--r--android/source/src/java/org/libreoffice/storage/external/OTGDocumentsProvider.java90
-rw-r--r--android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java73
-rw-r--r--android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java60
-rw-r--r--android/source/src/java/org/libreoffice/storage/local/LocalFile.java103
-rw-r--r--android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java178
-rw-r--r--android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java192
-rw-r--r--android/source/src/java/org/libreoffice/ui/FileUtilities.java206
-rw-r--r--android/source/src/java/org/libreoffice/ui/FolderIconView.java204
-rw-r--r--android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java1139
-rw-r--r--android/source/src/java/org/libreoffice/ui/PageView.java18
-rw-r--r--android/source/src/java/org/libreoffice/ui/RecentFile.java25
-rw-r--r--android/source/src/java/org/libreoffice/ui/RecentFilesAdapter.java18
-rw-r--r--android/source/src/java/org/mozilla/gecko/ZoomConstraints.java14
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/GLController.java78
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java16
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java34
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/LayerRenderer.java83
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/LayerView.java128
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/PointUtils.java4
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/RenderControllerThread.java9
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java2
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/SubTile.java14
173 files changed, 7203 insertions, 5585 deletions
diff --git a/android/source/AndroidManifest.xml b/android/source/AndroidManifest.xml
index 58da19119828..0a11a1d3654b 100644
--- a/android/source/AndroidManifest.xml
+++ b/android/source/AndroidManifest.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- android:installLocation="${installLocation}"
- package="org.libreoffice">
+ android:installLocation="${installLocation}">
<!-- App requires OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
@@ -9,13 +8,10 @@
<uses-feature android:name="android.hardware.usb.host" android:required="false"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.INTERNET" />
- <!-- extractNativeLibs="true" needed e.g. for NSS to load modules at runtime -->
<application
android:name=".LibreOfficeApplication"
android:allowBackup="true"
- android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/LibreOfficeTheme"
@@ -26,9 +22,9 @@
<!-- When changing android:windowSoftInputMode, please don't specify multiple "adjust..." or "state...". -->
<activity
android:name=".LibreOfficeMainActivity"
- android:label="@string/app_name"
android:configChanges="orientation|keyboard|keyboardHidden|screenLayout|uiMode|screenSize|smallestScreenSize"
- android:windowSoftInputMode="adjustResize" >
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
@@ -49,9 +45,7 @@
<data android:mimeType="application/vnd.oasis.opendocument.text-flat-xml" />
<data android:mimeType="application/vnd.oasis.opendocument.graphics-flat-xml" />
<data android:mimeType="application/vnd.oasis.opendocument.presentation-flat-xml" />
- <!-- TODO: opening FODS documents crashes currently
<data android:mimeType="application/vnd.oasis.opendocument.spreadsheet-flat-xml" />
- -->
<!-- ODF templates -->
<data android:mimeType="application/vnd.oasis.opendocument.text-template"/>
@@ -73,7 +67,7 @@
<!-- OOXML -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
- <!-- Currently crashes. <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow"/> -->
+ <data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.slideshow" />
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<!-- OOXML templates -->
@@ -98,36 +92,19 @@
<activity
android:name=".SettingsActivity"
- android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
+ android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar"
android:label="@string/app_name_settings">
</activity>
<!-- Document Browser Activity -->
<activity android:name="org.libreoffice.ui.LibreOfficeUIActivity"
- android:label="@string/app_name" >
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <!-- Document Provider Settings Activity -->
- <activity android:name=".storage.DocumentProviderSettingsActivity"
- android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
- android:label="@string/storage_provider_settings">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- </activity>
-
- <activity android:name=".storage.external.BrowserSelectorActivity" >
- </activity>
-
- <activity android:name=".storage.external.DirectoryBrowserActivity"
- android:label="@string/directory_browser_label"
- android:windowSoftInputMode="stateHidden">
- </activity>
-
<activity android:name=".PresentationActivity"
android:screenOrientation="landscape" >
<meta-data
@@ -136,7 +113,7 @@
</activity>
<provider
- android:name="android.support.v4.content.FileProvider"
+ android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
diff --git a/android/source/Makefile b/android/source/Makefile
index 5d6603f94738..2c1d6f9f1cca 100644
--- a/android/source/Makefile
+++ b/android/source/Makefile
@@ -3,11 +3,12 @@ gb_Side:=host
include ../../config_host.mk
endif
-# The default target just builds.
+# The default target builds the APK and runs lint.
all: build-gradle
DISABLE_UI=TRUE
+BUILD_VARIANT=$(if $(DISABLE_UI),StrippedUI,FullUI)$(if $(ENABLE_ANDROID_EDITING),Editing)$(if $(ENABLE_RELEASE_BUILD),Release,Debug)
BOOTSTRAPDIR=../Bootstrap
include $(BOOTSTRAPDIR)/Makefile.shared
@@ -20,20 +21,20 @@ install:
@if test "$$ENABLE_ANDROID_LOK" != "TRUE" ; then echo ; echo 'Run it with "make run"' ; echo ; fi
uninstall:
- $(ANDROID_SDK_HOME)/platform-tools/adb uninstall $(ANDROID_PACKAGE_NAME)
+ $(ANDROID_SDK_DIR)/platform-tools/adb uninstall $(ANDROID_PACKAGE_NAME)
clean:
- rm -rf assets assets_fullUI assets_strippedUI jniLibs jniLibs_debug $(OBJLOCAL)
+ rm -rf assets assets_fullUI assets_strippedUI build jniLibs jniLibs_debug res_generated $(OBJLOCAL)
rm -f native-code.cxx
rm -f liboSettings.gradle
build-gradle: liboSettings.gradle local.properties link-so
ifeq ($(ENABLE_JAVA),TRUE)
- if test "$$ENABLE_ANDROID_LOK" != "TRUE" ; then ./gradlew $(if $(verbose),--info) $(if $(versionCode),-PcmdVersionCode=$(versionCode)) assemble$(if $(DISABLE_UI),StrippedUI,FullUI)$(if $(ENABLE_ANDROID_EDITING),Editing)$(if $(ENABLE_RELEASE_BUILD),Release,Debug) ; fi
+ if test "$$ENABLE_ANDROID_LOK" != "TRUE" ; then ./gradlew $(if $(verbose),--info) $(if $(versionCode),-PcmdVersionCode=$(versionCode)) assemble$(BUILD_VARIANT) lint$(BUILD_VARIANT) ; fi
endif
run:
- if test "$$ENABLE_ANDROID_LOK" != "TRUE" ; then $(ANDROID_SDK_HOME)/platform-tools/adb shell am start -n $(ANDROID_PACKAGE_NAME)/org.libreoffice.ui.LibreOfficeUIActivity ; fi
+ if test "$$ENABLE_ANDROID_LOK" != "TRUE" ; then $(ANDROID_SDK_DIR)/platform-tools/adb shell am start -n $(ANDROID_PACKAGE_NAME)/org.libreoffice.ui.LibreOfficeUIActivity ; fi
debugrun:
@echo "please debug with lldb from within Android Studio, or setup ndk-gdb manually (see android/README for details)"
diff --git a/android/source/build.gradle b/android/source/build.gradle
index 32de09f84749..8cbef7744d8e 100644
--- a/android/source/build.gradle
+++ b/android/source/build.gradle
@@ -2,24 +2,26 @@ apply plugin: 'com.android.application'
// buildhost settings - paths and the like
apply from: 'liboSettings.gradle'
-project.ext.set("archivesBaseName", "LibreOfficeViewer")
allprojects {
repositories {
- jcenter()
- google()
- flatDir {
- dirs "${liboWorkdir}/UnpackedTarball/owncloud_android_lib/build/outputs/aar"
+ mavenCentral()
+ maven {
+ url "https://ipv6.repo1.maven.org/maven2"
}
+ google()
}
}
//build-time dependencies - android plugin for gradle
buildscript {
repositories {
- jcenter()
+ mavenCentral()
+ maven {
+ url "https://ipv6.repo1.maven.org/maven2"
+ }
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.1'
+ classpath 'com.android.tools.build:gradle:8.3.2'
}
}
@@ -30,34 +32,36 @@ dependencies {
"libreoffice.jar",
"unoloader.jar"
])
- implementation(name:'owncloud_android_lib', ext:'aar')
- implementation 'com.android.support:design:27.1.1' // also pulls-in corresponding support libraries
- implementation 'com.android.support.constraint:constraint-layout:1.1.2'
+ implementation 'com.google.android.material:material:1.11.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+ implementation "androidx.multidex:multidex:2.0.1"
}
android {
- compileSdkVersion 28
- compileOptions {
- // silence some java-language features hints
- sourceCompatibility 6
+ namespace 'org.libreoffice'
+ compileSdk 34
+ buildFeatures {
+ buildConfig = true
}
// uses non-conventional source layout, so need to reconfigure accordingly
// ToDo move to conventional layout, so stuff can be stripped down.
sourceSets {
main.manifest.srcFile 'AndroidManifest.xml'
main.assets.srcDirs = ['assets']
- main.res.srcDirs = ['res']
+ main.res.srcDirs = ['res', 'res_generated']
main.java.srcDirs = ['../Bootstrap/src', 'src/java']
main.jniLibs.srcDirs = ["${liboJniLibsdir}"]
- main.jni.srcDirs = [] // don't attempt to build native-lib via gradle
// the configuration data that might be stripped or not
fullUI.assets.srcDirs 'assets_fullUI'
strippedUI.assets.srcDirs 'assets_strippedUI'
strippedUIEditing.assets.srcDirs 'assets_strippedUI'
}
defaultConfig {
- minSdkVersion 16
- targetSdkVersion 28
+ // minSdkVersion is set in liboSettings.gradle
+ targetSdkVersion 34
+ // multidex needed when > 65,536 methods referenced with minSdKVersion < 21
+ // s. https://developer.android.com/studio/build/multidex
+ multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
buildTypes {
@@ -81,16 +85,31 @@ android {
strippedUIEditing {
dimension "default"
buildConfigField 'boolean', 'ALLOW_EDITING', 'true'
- versionNameSuffix "-editing"
}
fullUI.dimension "default"
}
- lintOptions {
- // don't error-out on missing translations
- warning 'MissingTranslation'
+ lint {
+ warningsAsErrors true
+ // ignore missing or extra translations, since these are tracked/managed via Weblate
+ ignore 'ExtraTranslation', 'MissingTranslation'
+ // don't error-out on external updates (new gradle plugin, library versions
+ // or target API become available)
+ // don't error-out on TypographyEllipsis, since this can be introduced with
+ // new translations, and those are handled in Weblate
+ informational 'AndroidGradlePluginVersion', 'GradleDependency', 'NewerVersionAvailable', 'OldTargetApi', 'TypographyEllipsis'
+ // don't fail on pre-existing issues
+ // These should be dealt with at some point, though.
+ // To update lint-baseline.xml, just remove the file and run the build again.
+ baseline file("lint-baseline.xml")
+ // s.a. lint.xml that contains further config
}
}
+// show warnings about use of deprecated API
+tasks.withType(JavaCompile).configureEach {
+ options.deprecation = true
+}
+
/* remark inherited from makefile:
Then "assets". Let the directory structure under assets mimic
that under solver for now.
@@ -148,20 +167,21 @@ task copyUnpackAssets(type: Copy) {
task copyAssets(type: Copy) {
description "copies assets that can be accessed within the installed apk"
into 'assets'
- from("${liboInstdir}") {
- includes = ["LICENSE", "NOTICE"]
- rename "LICENSE", "license.txt"
- rename "NOTICE", "notice.txt"
- }
- from("${liboExampleDocument}") {
- rename ".*", "example.odt"
- }
- // include icons
+ // include icons, Impress styles and required .ui files
into ('share') {
into ('config') {
from ("${liboInstdir}/share/config")
- includes = ['images_**.zip']
+ includes = ['images_**.zip',
+ '**/simpress/**.xml',
+ '**/annotation.ui',
+ '**/hfmenubutton.ui',
+ '**/inforeadonlydialog.ui',
+ '**/pbmenubutton.ui',
+ '**/scrollbars.ui',
+ '**/tabbuttons.ui',
+ '**/tabviewbar.ui'
+ ]
}
}
@@ -186,14 +206,15 @@ task copyAssets(type: Copy) {
include '*.data'
}
}
- // documents with manual page break trigger attempt to read the ui file 'pagebreakmenu.ui'
- // would trigger a css::container::NoSuchElementException with osl_File_E_NOENT
- // if not present and since it is not caught would crash the app;
- // 'annotationmenu.ui' required to handle documents containing comments,
- // 'headerfootermenu.ui' when clicking inside header/footer of document
- into('config') {
- from "${liboInstdir}/share/config"
- include '**/pagebreakmenu.ui', '**/annotationmenu.ui', '**/headerfootermenu.ui'
+}
+
+task copyAppResources(type: Copy) {
+ description "copies documents to make them available as app resources"
+ into 'res_generated/raw'
+ from("${liboInstdir}") {
+ includes = ["LICENSE", "NOTICE"]
+ rename "LICENSE", "license.txt"
+ rename "NOTICE", "notice.txt"
}
}
@@ -263,6 +284,7 @@ task createRCfiles {
[Bootstrap]
LO_LIB_DIR=file://$APP_DATA_DIR/lib/
BRAND_BASE_DIR=file:///assets
+ BRAND_SHARE_SUBDIR=share
CONFIGURATION_LAYERS=xcsxcu:${BRAND_BASE_DIR}/share/registry res:${BRAND_BASE_DIR}/share/registry
URE_BIN_DIR=file:///assets/ure/bin/dir/nothing-here/we-can/exec-anyway
'''.stripIndent()
@@ -294,7 +316,8 @@ task createRCfiles {
preBuild.dependsOn 'createRCfiles',
'createStrippedConfigMain',
'createStrippedConfigRegistry',
- 'createFullConfig'
+ 'createFullConfig',
+ 'copyAppResources'
clean.dependsOn 'cleanCopyAssets',
'cleanCreateStrippedConfig',
diff --git a/android/source/gradle.properties b/android/source/gradle.properties
index ad1671ef57fd..19f2d673e497 100644
--- a/android/source/gradle.properties
+++ b/android/source/gradle.properties
@@ -1 +1,4 @@
+android.nonFinalResIds=false
+android.nonTransitiveRClass=false
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx3072m
diff --git a/android/source/gradle/wrapper/gradle-wrapper.jar b/android/source/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a8698..033e24c4cdf4 100644
--- a/android/source/gradle/wrapper/gradle-wrapper.jar
+++ b/android/source/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/android/source/gradle/wrapper/gradle-wrapper.properties b/android/source/gradle/wrapper/gradle-wrapper.properties
index 7d1cfd365805..cdea548c75ee 100644
--- a/android/source/gradle/wrapper/gradle-wrapper.properties
+++ b/android/source/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
-#Tue Mar 03 14:01:57 CET 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionSha256Sum=c16d517b50dd28b3f5838f0e844b7520b8f1eb610f2f29de7e4e04a1b7c9c79b
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/android/source/gradlew b/android/source/gradlew
index 91a7e269e19d..fcb6fca147c0 100755
--- a/android/source/gradlew
+++ b/android/source/gradlew
@@ -1,79 +1,126 @@
-#!/usr/bin/env bash
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
-warn ( ) {
+warn () {
echo "$*"
-}
+} >&2
-die ( ) {
+die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
-APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -82,83 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=$((i+1))
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
-}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/android/source/gradlew.bat b/android/source/gradlew.bat
index 72d362dafd89..6689b85beecd 100755
--- a/android/source/gradlew.bat
+++ b/android/source/gradlew.bat
@@ -1,4 +1,20 @@
-@if "%DEBUG%" == "" @echo off
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -8,20 +24,24 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +55,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,44 +65,26 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/android/source/ic_launcher-web.png b/android/source/ic_launcher-web.png
index e9dcfcacf844..82497c1ac299 100644
--- a/android/source/ic_launcher-web.png
+++ b/android/source/ic_launcher-web.png
Binary files differ
diff --git a/android/source/lint-baseline.xml b/android/source/lint-baseline.xml
new file mode 100644
index 000000000000..01fdd6f8d234
--- /dev/null
+++ b/android/source/lint-baseline.xml
@@ -0,0 +1,2341 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.3.2" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.2)" variant="all" version="8.3.2">
+
+ <issue
+ id="ScopedStorage"
+ message="WRITE_EXTERNAL_STORAGE is deprecated (and is not granted) when targeting Android 13+. If you need to write to shared storage, use the `MediaStore.createWriteRequest` intent."
+ errorLine1=" &lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="AndroidManifest.xml"
+ line="10"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="ScrollViewSize"
+ message="This LinearLayout should use `android:layout_height=&quot;wrap_content&quot;`"
+ errorLine1=" android:layout_height=&quot;match_parent&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="311"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="ScrollViewSize"
+ message="This LinearLayout should use `android:layout_height=&quot;wrap_content&quot;`"
+ errorLine1=" android:layout_height=&quot;match_parent&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="378"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="CanvasSize"
+ message="Calling `Canvas.getWidth()` is usually wrong; you should be calling `getWidth()` instead"
+ errorLine1=" int horizontalMargin = (int) (canvas.getWidth()*0.1);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="55"
+ column="43"/>
+ </issue>
+
+ <issue
+ id="CanvasSize"
+ message="Calling `Canvas.getWidth()` is usually wrong; you should be calling `getWidth()` instead"
+ errorLine1=" new Rect(horizontalMargin,verticalMargin,canvas.getWidth()-horizontalMargin,"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="59"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="CanvasSize"
+ message="Calling `Canvas.getHeight()` is usually wrong; you should be calling `getHeight()` instead"
+ errorLine1=" canvas.getHeight()-verticalMargin),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="60"
+ column="25"/>
+ </issue>
+
+ <issue
+ id="CommitPrefEdits"
+ message="`SharedPreferences.edit()` without a corresponding `commit()` or `apply()` call"
+ errorLine1=" preferences.edit().putString(SELECTED_LANG, lang);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/LocaleHelper.java"
+ line="49"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="DefaultLocale"
+ message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
+ errorLine1=" return String.format(&quot;TileIdentifier (%d, %d) z=%f s=(%d, %d)&quot;, x, y, zoom, size.width, size.height);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/TileIdentifier.java"
+ line="88"
+ column="16"/>
+ </issue>
+
+ <issue
+ id="AppBundleLocaleChanges"
+ message="Found dynamic locale changes, but did not find corresponding Play Core library calls for downloading languages and splitting by language is not disabled in the `bundle` configuration"
+ errorLine1=" cfg.locale = locale;"
+ errorLine2=" ~~~~~~">
+ <location
+ file="src/java/org/libreoffice/LocaleHelper.java"
+ line="40"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="InflateParams"
+ message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout&apos;s root element)"
+ errorLine1=" final View headerPopupView = inflater.inflate(R.layout.calc_header_popup, null);"
+ errorLine2=" ~~~~">
+ <location
+ file="src/java/org/libreoffice/overlay/CalcHeadersController.java"
+ line="118"
+ column="87"/>
+ </issue>
+
+ <issue
+ id="InflateParams"
+ message="Avoid passing `null` as the view root (needed to resolve layout parameters on the inflated layout&apos;s root element)"
+ errorLine1=" view = layoutInflater.inflate(R.layout.document_part_list_layout, null);"
+ errorLine2=" ~~~~">
+ <location
+ file="src/java/org/libreoffice/DocumentPartViewListAdapter.java"
+ line="36"
+ column="79"/>
+ </issue>
+
+ <issue
+ id="QueryPermissionsNeeded"
+ message="Consider adding a `&lt;queries>` declaration to your manifest when calling this \&#xA;method; see https://g.co/dev/packagevisibility for details"
+ errorLine1=" if (takePictureIntent.resolveActivity(mContext.getPackageManager()) != null) {"
+ errorLine2=" ~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/FormattingController.java"
+ line="370"
+ column="31"/>
+ </issue>
+
+ <issue
+ id="QueryPermissionsNeeded"
+ message="Consider adding a `&lt;queries>` declaration to your manifest when calling this \&#xA;method; see https://g.co/dev/packagevisibility for details"
+ errorLine1=" .queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/FormattingController.java"
+ line="386"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="UnsupportedChromeOsCameraSystemFeature"
+ message="You should look for any camera available on the device, not just the rear"
+ errorLine1=" if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/FormattingController.java"
+ line="363"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="SpUsage"
+ message="Should use &quot;`sp`&quot; instead of &quot;`dp`&quot; for text sizes"
+ errorLine1=" android:textSize=&quot;14dp&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="77"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="DiscouragedApi"
+ message="Should not restrict activity to fixed orientation. This may not be suitable for different form factors, causing the app to be letterboxed."
+ errorLine1=" android:screenOrientation=&quot;landscape&quot; >"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="AndroidManifest.xml"
+ line="109"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="DiscouragedApi"
+ message="Use of this function is discouraged because resource reflection makes it harder to perform build optimizations and compile-time verification of code. It is much more efficient to retrieve resources by identifier (e.g. `R.foo.bar`) than by name (e.g. `getIdentifier(&quot;bar&quot;, &quot;foo&quot;, null)`)."
+ errorLine1=" int resourceID = resources.getIdentifier(name, &quot;drawable&quot;, packageName);"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/mozilla/gecko/gfx/LayerView.java"
+ line="227"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="SetJavaScriptEnabled"
+ message="Using `setJavaScriptEnabled` can introduce XSS vulnerabilities into your application, review carefully"
+ errorLine1=" mWebView.getSettings().setJavaScriptEnabled(true);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/PresentationActivity.java"
+ line="39"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="DrawAllocation"
+ message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)"
+ errorLine1=" mLayerClient.setViewportSize(new FloatSize(right - left, bottom - top), true);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/mozilla/gecko/gfx/LayerView.java"
+ line="293"
+ column="42"/>
+ </issue>
+
+ <issue
+ id="DrawAllocation"
+ message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)"
+ errorLine1=" canvas.drawBitmap(bmp, new Rect(0, 0, bmp.getWidth(), bmp.getHeight()),"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="58"
+ column="36"/>
+ </issue>
+
+ <issue
+ id="DrawAllocation"
+ message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)"
+ errorLine1=" new Rect(horizontalMargin,verticalMargin,canvas.getWidth()-horizontalMargin,"
+ errorLine2=" ^">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="59"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="DrawAllocation"
+ message="Avoid object allocations during draw/layout operations (preallocate and reuse instead)"
+ errorLine1=" canvas.drawText(getContext().getString(R.string.bmp_null), 100, 100, new Paint());"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/PageView.java"
+ line="64"
+ column="82"/>
+ </issue>
+
+ <issue
+ id="NotifyDataSetChanged"
+ message="It will always be more efficient to use more specific change events if you can. Rely on `notifyDataSetChanged` as a last resort."
+ errorLine1=" ColorPaletteAdapter.this.notifyDataSetChanged();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ColorPaletteAdapter.java"
+ line="118"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="NotifyDataSetChanged"
+ message="It will always be more efficient to use more specific change events if you can. Rely on `notifyDataSetChanged` as a last resort."
+ errorLine1=" ColorPickerAdapter.this.notifyDataSetChanged();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ColorPickerAdapter.java"
+ line="147"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="ObsoleteLayoutParam"
+ message="Invalid layout param in a `ScrollView`: `layout_weight`"
+ errorLine1=" android:layout_weight=&quot;0.25&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="312"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="ObsoleteLayoutParam"
+ message="Invalid layout param in a `ScrollView`: `layout_weight`"
+ errorLine1=" android:layout_weight=&quot;0.5&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="379"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="ObsoleteLayoutParam"
+ message="Invalid layout param in a `LinearLayout`: `layout_below`"
+ errorLine1=" android:layout_below=&quot;@id/fontColorView&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="63"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="ObsoleteLayoutParam"
+ message="Invalid layout param in a `LinearLayout`: `layout_alignParentBottom`"
+ errorLine1=" android:layout_alignParentBottom=&quot;true&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="64"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="ObsoleteSdkInt"
+ message="Unnecessary; SDK_INT is always >= 19"
+ errorLine1="@TargetApi(19)"
+ errorLine2="~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/PDFDocumentAdapter.java"
+ line="20"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UseCompoundDrawables"
+ message="This tag and its children can be replaced by one `&lt;TextView/>` and a compound drawable"
+ errorLine1="&lt;LinearLayout"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="res/layout/document_part_list_layout.xml"
+ line="2"
+ column="2"/>
+ </issue>
+
+ <issue
+ id="VectorPath"
+ message="Very long vector path (871 characters), which is bad for performance. Considering reducing precision, removing minor details or rasterizing vector."
+ errorLine1=" android:pathData=&quot;M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z&quot;/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/drawable/ic_settings_24dp.xml"
+ line="8"
+ column="27"/>
+ </issue>
+
+ <issue
+ id="InefficientWeight"
+ message="Use a `layout_height` of `0dp` instead of `wrap_content` for better performance"
+ errorLine1=" android:layout_height=&quot;wrap_content&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="73"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="InefficientWeight"
+ message="Use a `layout_height` of `0dp` instead of `match_parent` for better performance"
+ errorLine1=" android:layout_height=&quot;match_parent&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="66"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NestedWeights"
+ message="Nested weights are bad for performance"
+ errorLine1=" android:layout_weight=&quot;0.25&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="74"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="Overdraw"
+ message="Possible overdraw: Root element paints background `#fff` with a theme that also paints a background (inferred theme is `@style/LibreOfficeTheme`)"
+ errorLine1=" android:background=&quot;#fff&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_main.xml"
+ line="8"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="Overdraw"
+ message="Possible overdraw: Root element paints background `@color/doorhanger_background_dark` with a theme that also paints a background (inferred theme is `@style/LibreOfficeTheme`)"
+ errorLine1=" android:background=&quot;@color/doorhanger_background_dark&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/calc_header_popup.xml"
+ line="5"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="Overdraw"
+ message="Possible overdraw: Root element paints background `#aaa` with a theme that also paints a background (inferred theme is `@style/LibreOfficeTheme`)"
+ errorLine1=" android:background=&quot;#aaa&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/main.xml"
+ line="12"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="Overdraw"
+ message="Possible overdraw: Root element paints background `?attr/colorPrimary` with a theme that also paints a background (inferred theme is `@style/LibreOfficeTheme`)"
+ errorLine1=" android:background=&quot;?attr/colorPrimary&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="10"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="Overdraw"
+ message="Possible overdraw: Root element paints background `?attr/colorPrimary` with a theme that also paints a background (inferred theme is `@style/LibreOfficeTheme`)"
+ errorLine1=" android:background=&quot;?attr/colorPrimary&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="9"
+ column="5"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.background` appears to be unused">
+ <location
+ file="res/drawable-mdpi/background.png"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.background_light` appears to be unused"
+ errorLine1=" &lt;color name=&quot;background_light&quot;>#FAFAFA&lt;/color> &lt;!--Material Grey 50-->"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="12"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.background_normal` appears to be unused"
+ errorLine1=" &lt;color name=&quot;background_normal&quot;>#F5F5F5&lt;/color> &lt;!--Material Grey 100-->"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="13"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.background_private` appears to be unused"
+ errorLine1=" &lt;color name=&quot;background_private&quot;>#FF292C29&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="14"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.background_tabs` appears to be unused"
+ errorLine1=" &lt;color name=&quot;background_tabs&quot;>#FF363B40&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="15"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight&quot;>#33000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="16"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_focused` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_focused&quot;>#1A000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="17"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_dark` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_dark&quot;>#33FFFFFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="18"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_dark_focused` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_dark_focused&quot;>#1AFFFFFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="19"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_shaped` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_shaped&quot;>#FF696D71&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="22"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_shaped_focused` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_shaped_focused&quot;>#FF565B60&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="25"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_nav` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_nav&quot;>#FFA5ACB2&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="28"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_nav_focused` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_nav_focused&quot;>#FFB9C1C7&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="31"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_nav_pb` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_nav_pb&quot;>#FF545654&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="34"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.highlight_nav_focused_pb` appears to be unused"
+ errorLine1=" &lt;color name=&quot;highlight_nav_focused_pb&quot;>#FF3F423F&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="37"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_primary` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_primary&quot;>#222222&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="43"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_secondary` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_secondary&quot;>#777777&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="44"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_tertiary` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_tertiary&quot;>#9198A1&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="45"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_primary_inverse` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_primary_inverse&quot;>#FFFFFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="48"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_secondary_inverse` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_secondary_inverse&quot;>#DDDDDD&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="49"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_tertiary_inverse` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_tertiary_inverse&quot;>#A4A7A9&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="50"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_primary_disable_only` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_primary_disable_only&quot;>#999999&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="53"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_hint` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_hint&quot;>#666666&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="56"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_hint_inverse` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_hint_inverse&quot;>#7F828A&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="57"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_highlight` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_highlight&quot;>#FF9500&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="60"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_highlight_inverse` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_highlight_inverse&quot;>#D06BFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="61"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.text_color_link` appears to be unused"
+ errorLine1=" &lt;color name=&quot;text_color_link&quot;>#22629E&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="64"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.splash_background` appears to be unused"
+ errorLine1=" &lt;color name=&quot;splash_background&quot;>#000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="66"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.splash_msgfont` appears to be unused"
+ errorLine1=" &lt;color name=&quot;splash_msgfont&quot;>#ffffff&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="67"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.splash_urlfont` appears to be unused"
+ errorLine1=" &lt;color name=&quot;splash_urlfont&quot;>#000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="68"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.splash_content` appears to be unused"
+ errorLine1=" &lt;color name=&quot;splash_content&quot;>#ffffff&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="69"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.doorhanger_text` appears to be unused"
+ errorLine1=" &lt;color name=&quot;doorhanger_text&quot;>#FF222222&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="71"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.doorhanger_link` appears to be unused"
+ errorLine1=" &lt;color name=&quot;doorhanger_link&quot;>#FF2AA1FE&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="72"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.doorhanger_divider_dark` appears to be unused"
+ errorLine1=" &lt;color name=&quot;doorhanger_divider_dark&quot;>#FFB3C2CE&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="74"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.validation_message_text` appears to be unused"
+ errorLine1=" &lt;color name=&quot;validation_message_text&quot;>#ffffff&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="77"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_text_highlight` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_text_highlight&quot;>#FFFF9500&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="78"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_text_highlight_pb` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_text_highlight_pb&quot;>#FFD06BFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="79"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.suggestion_primary` appears to be unused"
+ errorLine1=" &lt;color name=&quot;suggestion_primary&quot;>#dddddd&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="80"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.suggestion_pressed` appears to be unused"
+ errorLine1=" &lt;color name=&quot;suggestion_pressed&quot;>#bbbbbb&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="81"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.tab_row_pressed` appears to be unused"
+ errorLine1=" &lt;color name=&quot;tab_row_pressed&quot;>#4D000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="82"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.dialogtitle_textcolor` appears to be unused"
+ errorLine1=" &lt;color name=&quot;dialogtitle_textcolor&quot;>#ffffff&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="83"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.textbox_background` appears to be unused"
+ errorLine1=" &lt;color name=&quot;textbox_background&quot;>#FFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="85"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.textbox_background_disabled` appears to be unused"
+ errorLine1=" &lt;color name=&quot;textbox_background_disabled&quot;>#DDD&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="86"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.textbox_stroke` appears to be unused"
+ errorLine1=" &lt;color name=&quot;textbox_stroke&quot;>#000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="87"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.textbox_stroke_disabled` appears to be unused"
+ errorLine1=" &lt;color name=&quot;textbox_stroke_disabled&quot;>#666&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="88"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_urltext` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_urltext&quot;>#A6A6A6&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="90"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_domaintext` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_domaintext&quot;>#000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="91"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_domaintext_private` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_domaintext_private&quot;>#FFF&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="92"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_blockedtext` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_blockedtext&quot;>#b14646&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="93"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.url_bar_shadow` appears to be unused"
+ errorLine1=" &lt;color name=&quot;url_bar_shadow&quot;>#12000000&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="94"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.home_last_tab_bar_bg` appears to be unused"
+ errorLine1=" &lt;color name=&quot;home_last_tab_bar_bg&quot;>#FFF5F7F9&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="96"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.color.panel_grid_item_image_background` appears to be unused"
+ errorLine1=" &lt;color name=&quot;panel_grid_item_image_background&quot;>#D1D9E1&lt;/color>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/colors.xml"
+ line="98"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.activity_horizontal_margin` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;activity_horizontal_margin&quot;>16dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="3"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.activity_vertical_margin` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;activity_vertical_margin&quot;>16dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="4"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.text_selection_handle_width` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;text_selection_handle_width&quot;>30dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="5"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.text_selection_handle_height` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;text_selection_handle_height&quot;>44dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="6"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.text_selection_handle_shadow` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;text_selection_handle_shadow&quot;>2dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="7"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.dimen.file_icon_width` appears to be unused"
+ errorLine1=" &lt;dimen name=&quot;file_icon_width&quot;>32dp&lt;/dimen>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/dimens.xml"
+ line="10"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.layout.document_viewer` appears to be unused"
+ errorLine1="&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
+ errorLine2="^">
+ <location
+ file="res/layout/document_viewer.xml"
+ line="8"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.ic_menu` appears to be unused"
+ errorLine1="&lt;bitmap xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
+ errorLine2="^">
+ <location
+ file="res/drawable-hdpi/ic_menu.xml"
+ line="3"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.ic_menu_black_24dp` appears to be unused">
+ <location
+ file="res/drawable-xxxhdpi/ic_menu_black_24dp.png"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.ic_settings_24dp` appears to be unused"
+ errorLine1="&lt;vector xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
+ errorLine2="^">
+ <location
+ file="res/drawable/ic_settings_24dp.xml"
+ line="1"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.ic_sort_24dp` appears to be unused"
+ errorLine1="&lt;vector android:autoMirrored=&quot;true&quot; android:height=&quot;24dp&quot;"
+ errorLine2="^">
+ <location
+ file="res/drawable/ic_sort_24dp.xml"
+ line="9"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.light_view_as_grid` appears to be unused">
+ <location
+ file="res/drawable-hdpi/light_view_as_grid.png"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.light_view_as_list` appears to be unused">
+ <location
+ file="res/drawable-hdpi/light_view_as_list.png"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.layout.main` appears to be unused"
+ errorLine1="&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
+ errorLine2="^">
+ <location
+ file="res/layout/main.xml"
+ line="9"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.drawable.shadow` appears to be unused">
+ <location
+ file="res/drawable-mdpi/shadow.png"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.layout.text_selection_handles` appears to be unused"
+ errorLine1="&lt;merge xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;"
+ errorLine2="^">
+ <location
+ file="res/layout/text_selection_handles.xml"
+ line="6"
+ column="1"/>
+ </issue>
+
+ <issue
+ id="UnusedResources"
+ message="The resource `R.style.LibreOfficeTheme_NavigationView` appears to be unused"
+ errorLine1=" &lt;style name=&quot;LibreOfficeTheme.NavigationView&quot;>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/values/themes.xml"
+ line="17"
+ column="12"/>
+ </issue>
+
+ <issue
+ id="UselessParent"
+ message="This `ScrollView` layout or its `LinearLayout` parent is unnecessary"
+ errorLine1=" &lt;ScrollView"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="55"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="UselessParent"
+ message="This `ScrollView` layout or its `LinearLayout` parent is unnecessary"
+ errorLine1=" &lt;ScrollView"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="193"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="UselessParent"
+ message="This `ScrollView` layout or its `LinearLayout` parent is unnecessary"
+ errorLine1=" &lt;ScrollView"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="305"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="UselessParent"
+ message="This `ScrollView` layout or its `LinearLayout` parent is unnecessary"
+ errorLine1=" &lt;ScrollView"
+ errorLine2=" ~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="373"
+ column="26"/>
+ </issue>
+
+ <issue
+ id="TooDeepLayout"
+ message="`toolbar_bottom.xml` has more than 10 levels, bad for performance"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="70"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="IconLocation"
+ message="Found bitmap drawable `res/drawable/calc.png` in densityless folder">
+ <location
+ file="res/drawable/calc.png"/>
+ </issue>
+
+ <issue
+ id="IconLocation"
+ message="Found bitmap drawable `res/drawable/draw.png` in densityless folder">
+ <location
+ file="res/drawable/draw.png"/>
+ </issue>
+
+ <issue
+ id="IconLocation"
+ message="Found bitmap drawable `res/drawable/dummy_page.png` in densityless folder">
+ <location
+ file="res/drawable/dummy_page.png"/>
+ </issue>
+
+ <issue
+ id="IconLocation"
+ message="Found bitmap drawable `res/drawable/impress.png` in densityless folder">
+ <location
+ file="res/drawable/impress.png"/>
+ </issue>
+
+ <issue
+ id="IconLocation"
+ message="Found bitmap drawable `res/drawable/writer.png` in densityless folder">
+ <location
+ file="res/drawable/writer.png"/>
+ </issue>
+
+ <issue
+ id="IconDensities"
+ message="Missing the following drawables in `drawable-hdpi`: background.png, decrementindent.png, handle_image_end.png, handle_image_middle.png, handle_image_start.png... (22 more)">
+ <location
+ file="res/drawable-hdpi"/>
+ </issue>
+
+ <issue
+ id="IconDensities"
+ message="Missing the following drawables in `drawable-mdpi`: decrementindent.png, handle_alias_end.xml, handle_alias_middle.xml, handle_alias_start.xml, handle_image_end.png... (33 more)">
+ <location
+ file="res/drawable-mdpi"/>
+ </issue>
+
+ <issue
+ id="IconDensities"
+ message="Missing the following drawables in `drawable-xhdpi`: background.png, decrementindent.png, handle_alias_end.xml, handle_alias_middle.xml, handle_alias_start.xml... (32 more)">
+ <location
+ file="res/drawable-xhdpi"/>
+ </issue>
+
+ <issue
+ id="IconMissingDensityFolder"
+ message="Missing density variation folders in `res`: drawable-xxhdpi">
+ <location
+ file="res"/>
+ </issue>
+
+ <issue
+ id="AlwaysShowAction"
+ message="Prefer &quot;`ifRoom`&quot; instead of &quot;`always`&quot;"
+ errorLine1=" app:showAsAction=&quot;always&quot;/>"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/menu/main.xml"
+ line="14"
+ column="15"/>
+ <location
+ file="res/menu/main.xml"
+ line="20"
+ column="15"/>
+ <location
+ file="res/menu/main.xml"
+ line="26"
+ column="15"/>
+ <location
+ file="res/menu/main.xml"
+ line="32"
+ column="13"/>
+ <location
+ file="res/menu/main.xml"
+ line="112"
+ column="13"/>
+ <location
+ file="res/menu/main.xml"
+ line="118"
+ column="13"/>
+ <location
+ file="res/menu/main.xml"
+ line="124"
+ column="13"/>
+ <location
+ file="res/menu/main.xml"
+ line="130"
+ column="13"/>
+ <location
+ file="res/menu/main.xml"
+ line="140"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/calc_header_popup.xml"
+ line="73"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/password_dialog.xml"
+ line="6"
+ column="6"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="454"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="493"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="533"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="543"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="Autofill"
+ message="Missing `autofillHints` attribute"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="553"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="ReportShortcutUsage"
+ message="Calling this method indicates use of dynamic shortcuts, but there are no calls to methods that track shortcut usage, such as `pushDynamicShortcut` or `reportShortcutUsed`. Calling these methods is recommended, as they track shortcut usage and allow launchers to adjust which shortcuts appear based on activation history. Please see https://developer.android.com/develop/ui/views/launch/shortcuts/managing-shortcuts#track-usage"
+ errorLine1=" shortcutManager.setDynamicShortcuts(shortcuts);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/ui/LibreOfficeUIActivity.java"
+ line="430"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="`onTouch` should call `View#performClick` when a click is detected"
+ errorLine1=" public boolean onTouch(View v, MotionEvent event) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/overlay/CalcHeadersView.java"
+ line="69"
+ column="32"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="Custom view `LayerView` overrides `onTouchEvent` but not `performClick`"
+ errorLine1=" public boolean onTouchEvent(MotionEvent event) {"
+ errorLine2=" ~~~~~~~~~~~~">
+ <location
+ file="src/java/org/mozilla/gecko/gfx/LayerView.java"
+ line="115"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="`OnSlideSwipeListener#onTouch` should call `View#performClick` when a click is detected"
+ errorLine1=" public boolean onTouch(View v, MotionEvent me) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="src/java/org/mozilla/gecko/OnSlideSwipeListener.java"
+ line="89"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="Custom view ``WebView`` has `setOnTouchListener` called on it but does not override `performClick`"
+ errorLine1=" mWebView.setOnTouchListener(new View.OnTouchListener() {"
+ errorLine2=" ^">
+ <location
+ file="src/java/org/libreoffice/PresentationActivity.java"
+ line="40"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="`onTouch` should call `View#performClick` when a click is detected"
+ errorLine1=" public boolean onTouch(View v, MotionEvent event) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/PresentationActivity.java"
+ line="42"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="ClickableViewAccessibility"
+ message="`onTouch` should call `View#performClick` when a click is detected"
+ errorLine1=" public boolean onTouch(View v, MotionEvent event) {"
+ errorLine2=" ~~~~~~~">
+ <location
+ file="src/java/org/libreoffice/PresentationActivity.java"
+ line="77"
+ column="28"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;com.google.android.material.floatingactionbutton.FloatingActionButton"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="137"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;com.google.android.material.floatingactionbutton.FloatingActionButton"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="169"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;com.google.android.material.floatingactionbutton.FloatingActionButton"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="201"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;com.google.android.material.floatingactionbutton.FloatingActionButton"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="233"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/colorbox.xml"
+ line="6"
+ column="6"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageView"
+ errorLine2=" ~~~~~~~~~">
+ <location
+ file="res/layout/document_part_list_layout.xml"
+ line="10"
+ column="6"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="16"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="25"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="70"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="80"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="90"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="100"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="110"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="140"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="150"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="160"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="170"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="207"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="217"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="227"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="237"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="253"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="263"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="273"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="283"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="315"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="325"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="335"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="345"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="355"
+ column="34"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="398"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="427"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="503"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="511"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="519"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="563"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="ContentDescription"
+ message="Missing `contentDescription` attribute on image"
+ errorLine1=" &lt;ImageButton"
+ errorLine2=" ~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="30"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="111"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="143"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="175"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="207"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_document_browser.xml"
+ line="239"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/colorbox.xml"
+ line="11"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="30"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="64"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="95"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="KeyboardInaccessibleWidget"
+ message="&apos;clickable&apos; attribute found, please also add &apos;focusable&apos;"
+ errorLine1=" android:clickable=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="126"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="LabelFor"
+ message="Missing accessibility label: provide either a view with an `android:labelFor` that references this view or provide an `android:hint`"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/activity_main.xml"
+ line="42"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="LabelFor"
+ message="Missing accessibility label: provide either a view with an `android:labelFor` that references this view or provide an `android:hint`"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/activity_main.xml"
+ line="52"
+ column="18"/>
+ </issue>
+
+ <issue
+ id="LabelFor"
+ message="Missing accessibility label: provide either a view with an `android:labelFor` that references this view or provide an `android:hint`"
+ errorLine1=" &lt;EditText"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="454"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;Rows:&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;Rows:&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="16"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;+&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;+&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="32"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;3&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;3&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="45"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;-&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;-&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="60"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;Columns:&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;Columns:&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="77"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;-&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;-&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="90"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;3&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;3&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="108"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="HardcodedText"
+ message="Hardcoded string &quot;+&quot;, should use `@string` resource"
+ errorLine1=" android:text=&quot;+&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="122"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RelativeOverlap"
+ message="`@id/slide_show_nav_back` can overlap `@id/slide_show_nav_prev` if @string/slideshow_action_back grows due to localized text expansion"
+ errorLine1=" &lt;Button"
+ errorLine2=" ~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="34"
+ column="10"/>
+ </issue>
+
+ <issue
+ id="RelativeOverlap"
+ message="`TextView-1` can overlap `@id/font_color_picker_button` if @string/font_color grows due to localized text expansion"
+ errorLine1=" &lt;TextView"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="386"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="RelativeOverlap"
+ message="`TextView-1` can overlap `@id/font_back_color_picker_button` if @string/highlight_color grows due to localized text expansion"
+ errorLine1=" &lt;TextView"
+ errorLine2=" ~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="415"
+ column="38"/>
+ </issue>
+
+ <issue
+ id="RelativeOverlap"
+ message="`@id/button_auto_color` can overlap `@id/button_go_back_color_picker` if @string/automatic grows due to localized text expansion"
+ errorLine1=" &lt;Button"
+ errorLine2=" ~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="38"
+ column="14"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_toRightOf`; already defining `layout_toEndOf` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_toRightOf=&quot;@+id/calc_header_top_left&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_main.xml"
+ line="78"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_toRightOf`; already defining `layout_toEndOf` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_toRightOf=&quot;@+id/calc_header_row&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/activity_main.xml"
+ line="94"
+ column="21"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_marginRight`; already defining `layout_marginEnd` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_marginRight=&quot;@dimen/file_icon_margin_end&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/item_recent_files.xml"
+ line="26"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_marginLeft`; already defining `layout_marginStart` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_marginLeft=&quot;8dp&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="14"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_marginRight`; already defining `layout_marginEnd` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_marginRight=&quot;8dp&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="27"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_marginLeft`; already defining `layout_marginStart` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_marginLeft=&quot;8dp&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="75"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_marginRight`; already defining `layout_marginEnd` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_marginRight=&quot;8dp&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/number_picker.xml"
+ line="120"
+ column="9"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_alignParentRight`; already defining `layout_alignParentEnd` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_alignParentRight=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="21"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_alignParentRight`; already defining `layout_alignParentEnd` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_alignParentRight=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="31"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Redundant attribute `layout_alignParentLeft`; already defining `layout_alignParentStart` with `targetSdkVersion` 34"
+ errorLine1=" android:layout_alignParentLeft=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/presentation_mode.xml"
+ line="38"
+ column="13"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Consider replacing `android:layout_alignParentLeft` with `android:layout_alignParentStart=&quot;true&quot;` to better support right-to-left layouts"
+ errorLine1=" android:layout_alignParentLeft=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="395"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Consider replacing `android:layout_alignParentRight` with `android:layout_alignParentEnd=&quot;true&quot;` to better support right-to-left layouts"
+ errorLine1=" android:layout_alignParentRight=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="405"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Consider replacing `android:layout_alignParentLeft` with `android:layout_alignParentStart=&quot;true&quot;` to better support right-to-left layouts"
+ errorLine1=" android:layout_alignParentLeft=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="424"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Consider replacing `android:layout_alignParentRight` with `android:layout_alignParentEnd=&quot;true&quot;` to better support right-to-left layouts"
+ errorLine1=" android:layout_alignParentRight=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_bottom.xml"
+ line="434"
+ column="41"/>
+ </issue>
+
+ <issue
+ id="RtlHardcoded"
+ message="Consider replacing `android:layout_alignParentRight` with `android:layout_alignParentEnd=&quot;true&quot;` to better support right-to-left layouts"
+ errorLine1=" android:layout_alignParentRight=&quot;true&quot;"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="res/layout/toolbar_color_picker.xml"
+ line="40"
+ column="17"/>
+ </issue>
+
+ <issue
+ id="RtlEnabled"
+ message="The project references RTL attributes, but does not explicitly enable or disable RTL support with `android:supportsRtl` in the manifest">
+ <location
+ file="AndroidManifest.xml"/>
+ </issue>
+
+</issues>
diff --git a/android/source/lint.xml b/android/source/lint.xml
new file mode 100644
index 000000000000..bfcae7ec03cf
--- /dev/null
+++ b/android/source/lint.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+ <!-- Disable check for extra resources in translations, Weblate takes care of
+ removing these. -->
+ <issue id="UnusedResources">
+ <ignore path="res/values-*/strings.xml" />
+ </issue>
+</lint>
+
diff --git a/android/source/res/drawable-hdpi/action_search.png b/android/source/res/drawable-hdpi/action_search.png
deleted file mode 100644
index e6b70451863a..000000000000
--- a/android/source/res/drawable-hdpi/action_search.png
+++ /dev/null
Binary files differ
diff --git a/android/source/res/drawable-hdpi/action_search_light.png b/android/source/res/drawable-hdpi/action_search_light.png
deleted file mode 100644
index f12e005ebe83..000000000000
--- a/android/source/res/drawable-hdpi/action_search_light.png
+++ /dev/null
Binary files differ
diff --git a/android/source/res/drawable-hdpi/ic_folder_48dp.xml b/android/source/res/drawable-hdpi/ic_folder_48dp.xml
new file mode 100644
index 000000000000..7eec9b367f00
--- /dev/null
+++ b/android/source/res/drawable-hdpi/ic_folder_48dp.xml
@@ -0,0 +1,5 @@
+<vector android:autoMirrored="true" android:height="48dp"
+ android:viewportHeight="24.0" android:viewportWidth="24.0"
+ android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@color/toolbar_foreground" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
+</vector>
diff --git a/android/source/res/drawable-hdpi/ic_keyboard.xml b/android/source/res/drawable-hdpi/ic_keyboard.xml
index 00902169d505..2aea0f7597a7 100644
--- a/android/source/res/drawable-hdpi/ic_keyboard.xml
+++ b/android/source/res/drawable-hdpi/ic_keyboard.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_keyboard_black_24dp"
- android:tint="@color/toolbar_foreground"/> \ No newline at end of file
+ android:src="@drawable/ic_keyboard_black__24dp"
+ android:tint="@color/toolbar_foreground"/>
diff --git a/android/source/res/drawable-hdpi/lo_icon.png b/android/source/res/drawable-hdpi/lo_icon.png
deleted file mode 100644
index d03373b9c2ee..000000000000
--- a/android/source/res/drawable-hdpi/lo_icon.png
+++ /dev/null
Binary files differ
diff --git a/android/source/res/drawable-mdpi/lo_icon.png b/android/source/res/drawable-mdpi/lo_icon.png
deleted file mode 100644
index 48e90bd1fdc5..000000000000
--- a/android/source/res/drawable-mdpi/lo_icon.png
+++ /dev/null
Binary files differ
diff --git a/android/source/res/drawable-xxxhdpi/decrementindent.png b/android/source/res/drawable-xxxhdpi/decrementindent.png
new file mode 100644
index 000000000000..0995c751d68c
--- /dev/null
+++ b/android/source/res/drawable-xxxhdpi/decrementindent.png
Binary files differ
diff --git a/android/source/res/drawable-xxxhdpi/ic_keyboard_black_24dp.png b/android/source/res/drawable-xxxhdpi/ic_keyboard_black__24dp.png
index ba4d5be6d74d..ba4d5be6d74d 100644
--- a/android/source/res/drawable-xxxhdpi/ic_keyboard_black_24dp.png
+++ b/android/source/res/drawable-xxxhdpi/ic_keyboard_black__24dp.png
Binary files differ
diff --git a/android/source/res/drawable-xxxhdpi/incrementindent.png b/android/source/res/drawable-xxxhdpi/incrementindent.png
new file mode 100644
index 000000000000..619c76bd6b55
--- /dev/null
+++ b/android/source/res/drawable-xxxhdpi/incrementindent.png
Binary files differ
diff --git a/android/source/res/drawable/calc.png b/android/source/res/drawable/calc.png
index 0c0d31444d11..240da6c8966d 100644
--- a/android/source/res/drawable/calc.png
+++ b/android/source/res/drawable/calc.png
Binary files differ
diff --git a/android/source/res/drawable/draw.png b/android/source/res/drawable/draw.png
index b3ee11426a04..8b8436789cc2 100644
--- a/android/source/res/drawable/draw.png
+++ b/android/source/res/drawable/draw.png
Binary files differ
diff --git a/android/source/res/drawable/ic_add_black_24dp.xml b/android/source/res/drawable/ic_add_24dp.xml
index 0258249cc482..7f7afe05c114 100644
--- a/android/source/res/drawable/ic_add_black_24dp.xml
+++ b/android/source/res/drawable/ic_add_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>
diff --git a/android/source/res/drawable/ic_arrow_back_black_24dp.xml b/android/source/res/drawable/ic_arrow_back_24dp.xml
index beafea3959eb..deb00257fb1d 100644
--- a/android/source/res/drawable/ic_arrow_back_black_24dp.xml
+++ b/android/source/res/drawable/ic_arrow_back_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
</vector>
diff --git a/android/source/res/drawable/ic_auto_color.xml b/android/source/res/drawable/ic_auto_color.xml
new file mode 100644
index 000000000000..3c68b556ee70
--- /dev/null
+++ b/android/source/res/drawable/ic_auto_color.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18,14c0,-4 -6,-10.8 -6,-10.8s-1.33,1.51 -2.73,3.52l8.59,8.59c0.09,-0.42 0.14,-0.86 0.14,-1.31zM17.12,17.12L12.5,12.5 5.27,5.27 4,6.55l3.32,3.32C6.55,11.32 6,12.79 6,14c0,3.31 2.69,6 6,6 1.52,0 2.9,-0.57 3.96,-1.5l2.63,2.63 1.27,-1.27 -2.74,-2.74z"/>
+</vector>
diff --git a/android/source/res/drawable/ic_cloud_black_24dp.xml b/android/source/res/drawable/ic_cloud_black_24dp.xml
deleted file mode 100644
index e0940ca0e7b0..000000000000
--- a/android/source/res/drawable/ic_cloud_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96z"/>
-</vector>
diff --git a/android/source/res/drawable/ic_content_copy_black_24dp.xml b/android/source/res/drawable/ic_content_copy_24dp.xml
index 8a894a3bcd73..26f2aefd40a2 100644
--- a/android/source/res/drawable/ic_content_copy_black_24dp.xml
+++ b/android/source/res/drawable/ic_content_copy_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>
diff --git a/android/source/res/drawable/ic_content_cut_black_24dp.xml b/android/source/res/drawable/ic_content_cut_24dp.xml
index 1c0f96a37b42..6a6ba24f2b7f 100644
--- a/android/source/res/drawable/ic_content_cut_black_24dp.xml
+++ b/android/source/res/drawable/ic_content_cut_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M9.64,7.64c0.23,-0.5 0.36,-1.05 0.36,-1.64 0,-2.21 -1.79,-4 -4,-4S2,3.79 2,6s1.79,4 4,4c0.59,0 1.14,-0.13 1.64,-0.36L10,12l-2.36,2.36C7.14,14.13 6.59,14 6,14c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4c0,-0.59 -0.13,-1.14 -0.36,-1.64L12,14l7,7h3v-1L9.64,7.64zM6,8c-1.1,0 -2,-0.89 -2,-2s0.9,-2 2,-2 2,0.89 2,2 -0.9,2 -2,2zM6,20c-1.1,0 -2,-0.89 -2,-2s0.9,-2 2,-2 2,0.89 2,2 -0.9,2 -2,2zM12,12.5c-0.28,0 -0.5,-0.22 -0.5,-0.5s0.22,-0.5 0.5,-0.5 0.5,0.22 0.5,0.5 -0.22,0.5 -0.5,0.5zM19,3l-6,6 2,2 7,-7L22,3z"/>
</vector>
diff --git a/android/source/res/drawable/ic_content_paste_black_24dp.xml b/android/source/res/drawable/ic_content_paste_24dp.xml
index a902d9a856a0..e01601364307 100644
--- a/android/source/res/drawable/ic_content_paste_black_24dp.xml
+++ b/android/source/res/drawable/ic_content_paste_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M19,2h-4.18C14.4,0.84 13.3,0 12,0c-1.3,0 -2.4,0.84 -2.82,2L5,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,4c0,-1.1 -0.9,-2 -2,-2zM12,2c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM19,20L5,20L5,4h2v3h10L17,4h2v16z"/>
</vector>
diff --git a/android/source/res/drawable/ic_decrementindent.xml b/android/source/res/drawable/ic_decrementindent.xml
new file mode 100644
index 000000000000..85235d32fd06
--- /dev/null
+++ b/android/source/res/drawable/ic_decrementindent.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/decrementindent"
+ android:tint="@color/toolbar_foreground"/>
diff --git a/android/source/res/drawable/ic_filter_list_black_24dp.xml b/android/source/res/drawable/ic_filter_list_24dp.xml
index b99b672f4e62..87414cbed6b4 100644
--- a/android/source/res/drawable/ic_filter_list_black_24dp.xml
+++ b/android/source/res/drawable/ic_filter_list_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z"/>
</vector>
diff --git a/android/source/res/drawable/ic_folder_black_24dp.xml b/android/source/res/drawable/ic_folder_24dp.xml
index 1a9a16fb1704..0435c89afc5d 100644
--- a/android/source/res/drawable/ic_folder_black_24dp.xml
+++ b/android/source/res/drawable/ic_folder_24dp.xml
@@ -1,5 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="#FF000000" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
+ <path android:fillColor="@color/toolbar_foreground" android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
</vector>
diff --git a/android/source/res/drawable/ic_format_clear_black_24dp.xml b/android/source/res/drawable/ic_format_clear_24dp.xml
index 4c903c7163e0..eeb661b8c09a 100644
--- a/android/source/res/drawable/ic_format_clear_black_24dp.xml
+++ b/android/source/res/drawable/ic_format_clear_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M3.27,5L2,6.27l6.97,6.97L6.5,19h3l1.57,-3.66L16.73,21 18,19.73 3.55,5.27 3.27,5zM6,5v0.18L8.82,8h2.4l-0.72,1.68 2.1,2.1L14.21,8H20V5H6z"/>
</vector>
diff --git a/android/source/res/drawable/ic_grid_off_black_24dp.xml b/android/source/res/drawable/ic_grid_off_24dp.xml
index 7cf3c950cc4b..6d5df305e48a 100644
--- a/android/source/res/drawable/ic_grid_off_black_24dp.xml
+++ b/android/source/res/drawable/ic_grid_off_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M8,4v1.45l2,2L10,4h4v4h-3.45l2,2L14,10v1.45l2,2L16,10h4v4h-3.45l2,2L20,16v1.45l2,2L22,4c0,-1.1 -0.9,-2 -2,-2L4.55,2l2,2L8,4zM16,4h4v4h-4L16,4zM1.27,1.27L0,2.55l2,2L2,20c0,1.1 0.9,2 2,2h15.46l2,2 1.27,-1.27L1.27,1.27zM10,12.55L11.45,14L10,14v-1.45zM4,6.55L5.45,8L4,8L4,6.55zM8,20L4,20v-4h4v4zM8,14L4,14v-4h3.45l0.55,0.55L8,14zM14,20h-4v-4h3.45l0.55,0.54L14,20zM16,20v-1.46L17.46,20L16,20z"/>
</vector>
diff --git a/android/source/res/drawable/ic_grid_on_black_24dp.xml b/android/source/res/drawable/ic_grid_on_24dp.xml
index b2ff9e5be07b..3aec5d2840d6 100644
--- a/android/source/res/drawable/ic_grid_on_black_24dp.xml
+++ b/android/source/res/drawable/ic_grid_on_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M20,2L4,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM8,20L4,20v-4h4v4zM8,14L4,14v-4h4v4zM8,8L4,8L4,4h4v4zM14,20h-4v-4h4v4zM14,14h-4v-4h4v4zM14,8h-4L10,4h4v4zM20,20h-4v-4h4v4zM20,14h-4v-4h4v4zM20,8h-4L16,4h4v4z"/>
</vector>
diff --git a/android/source/res/drawable/ic_incrementindent.xml b/android/source/res/drawable/ic_incrementindent.xml
new file mode 100644
index 000000000000..3bee99911ec1
--- /dev/null
+++ b/android/source/res/drawable/ic_incrementindent.xml
@@ -0,0 +1,3 @@
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/incrementindent"
+ android:tint="@color/toolbar_foreground"/>
diff --git a/android/source/res/drawable/ic_insert_drive_file_black_24dp.xml b/android/source/res/drawable/ic_insert_drive_file_black_24dp.xml
deleted file mode 100644
index aaeb289d7060..000000000000
--- a/android/source/res/drawable/ic_insert_drive_file_black_24dp.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:width="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0" >
- <path android:fillColor="#FF000000" android:pathData="M6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6L6,2zM13,9L13,3.5L18.5,9L13,9z"/>
-</vector>
diff --git a/android/source/res/drawable/ic_keyboard_backspace_black_24dp.xml b/android/source/res/drawable/ic_keyboard_backspace_black_24dp.xml
deleted file mode 100644
index 827cde0056cd..000000000000
--- a/android/source/res/drawable/ic_keyboard_backspace_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M21,11H6.83l3.58,-3.59L9,6l-6,6 6,6 1.41,-1.41L6.83,13H21z"/>
-</vector>
diff --git a/android/source/res/drawable/ic_line.xml b/android/source/res/drawable/ic_line.xml
index 639ba2dbf690..ae33c2929c94 100644
--- a/android/source/res/drawable/ic_line.xml
+++ b/android/source/res/drawable/ic_line.xml
@@ -7,6 +7,6 @@
android:pathData="M4,11h16v2h-16z"
android:fillAlpha="1"
android:strokeColor="#00000000"
- android:fillColor="#4d4d4d"
+ android:fillColor="@color/toolbar_foreground"
android:strokeWidth="2"/>
</vector>
diff --git a/android/source/res/drawable/ic_menu_back.png b/android/source/res/drawable/ic_menu_back.png
deleted file mode 100644
index d3191caffd13..000000000000
--- a/android/source/res/drawable/ic_menu_back.png
+++ /dev/null
Binary files differ
diff --git a/android/source/res/drawable/ic_rect.xml b/android/source/res/drawable/ic_rect.xml
index 241759ff00c3..ac6db359f56e 100644
--- a/android/source/res/drawable/ic_rect.xml
+++ b/android/source/res/drawable/ic_rect.xml
@@ -7,7 +7,7 @@
android:pathData="M4,6h16v12h-16z"
android:fillAlpha="0.99"
android:strokeColor="#00000000"
- android:fillColor="#4d4d4d"
+ android:fillColor="@color/toolbar_foreground"
android:strokeWidth="4"
android:strokeAlpha="0.99"/>
</vector>
diff --git a/android/source/res/drawable/ic_sd_card_black_24dp.xml b/android/source/res/drawable/ic_sd_card_black_24dp.xml
deleted file mode 100644
index f9ad72d482db..000000000000
--- a/android/source/res/drawable/ic_sd_card_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM12,8h-2L10,4h2v4zM15,8h-2L13,4h2v4zM18,8h-2L16,4h2v4z"/>
-</vector>
diff --git a/android/source/res/drawable/ic_settings_black_24dp.xml b/android/source/res/drawable/ic_settings_24dp.xml
index ace746c40eed..990ea6fb9c33 100644
--- a/android/source/res/drawable/ic_settings_black_24dp.xml
+++ b/android/source/res/drawable/ic_settings_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@color/toolbar_foreground"
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
</vector>
diff --git a/android/source/res/drawable/ic_sort_black_24dp.xml b/android/source/res/drawable/ic_sort_24dp.xml
index d582deea67ec..7f5f2d4e8702 100644
--- a/android/source/res/drawable/ic_sort_black_24dp.xml
+++ b/android/source/res/drawable/ic_sort_24dp.xml
@@ -9,5 +9,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="#FF000000" android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
+ <path android:fillColor="@color/toolbar_foreground" android:pathData="M3,18h6v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h12v-2L3,11v2z"/>
</vector>
diff --git a/android/source/res/drawable/ic_storage_black_24dp.xml b/android/source/res/drawable/ic_storage_black_24dp.xml
deleted file mode 100644
index 53c595cd7d1c..000000000000
--- a/android/source/res/drawable/ic_storage_black_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M2,20h20v-4L2,16v4zM4,17h2v2L4,19v-2zM2,4v4h20L22,4L2,4zM6,7L4,7L4,5h2v2zM2,14h20v-4L2,10v4zM4,11h2v2L4,13v-2z"/>
-</vector>
diff --git a/android/source/res/drawable/ic_usb_black_24dp.xml b/android/source/res/drawable/ic_usb_black_24dp.xml
deleted file mode 100644
index d9b39bac1a86..000000000000
--- a/android/source/res/drawable/ic_usb_black_24dp.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:width="24dp"
- android:viewportHeight="24.0"
- android:viewportWidth="24.0" >
- <path android:fillColor="#FF000000" android:pathData="M15,7v4h1v2h-3V5h2l-3,-4 -3,4h2v8H8v-2.07c0.7,-0.37 1.2,-1.08 1.2,-1.93 0,-1.21 -0.99,-2.2 -2.2,-2.2 -1.21,0 -2.2,0.99 -2.2,2.2 0,0.85 0.5,1.56 1.2,1.93V13c0,1.11 0.89,2 2,2h3v3.05c-0.71,0.37 -1.2,1.1 -1.2,1.95 0,1.22 0.99,2.2 2.2,2.2 1.21,0 2.2,-0.98 2.2,-2.2 0,-0.85 -0.49,-1.58 -1.2,-1.95V15h3c1.11,0 2,-0.89 2,-2v-2h1V7h-4z"/>
-</vector>
diff --git a/android/source/res/drawable/impress.png b/android/source/res/drawable/impress.png
index 5909f05bf089..2de82d6bd42b 100644
--- a/android/source/res/drawable/impress.png
+++ b/android/source/res/drawable/impress.png
Binary files differ
diff --git a/android/source/res/drawable/label_background.xml b/android/source/res/drawable/label_background.xml
index 1e097857537a..2727c7d9ab0b 100644
--- a/android/source/res/drawable/label_background.xml
+++ b/android/source/res/drawable/label_background.xml
@@ -2,8 +2,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
- <solid android:color="@color/background_normal" />
+ <solid android:color="@color/background_floating" />
<corners android:radius="5dp" />
</shape>
</item>
-</selector> \ No newline at end of file
+</selector>
diff --git a/android/source/res/drawable/writer.png b/android/source/res/drawable/writer.png
index 8a4e21e47174..6cc9e8483033 100644
--- a/android/source/res/drawable/writer.png
+++ b/android/source/res/drawable/writer.png
Binary files differ
diff --git a/android/source/res/layout/about.xml b/android/source/res/layout/about.xml
index 8968c00d2695..f37482b82a0c 100644
--- a/android/source/res/layout/about.xml
+++ b/android/source/res/layout/about.xml
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -14,8 +15,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
- android:text="@string/app_version"
- android:textSize="18sp"/>
+ android:textSize="18sp"
+ tools:text="Version: x.x.x.x\nBuild ID: 000000000000" />
<TextView
android:id="@+id/about_description"
@@ -39,7 +40,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
- android:text="@string/app_vendor"
- android:textSize="18sp"/>
+ android:textSize="18sp"
+ tools:text="@string/app_vendor" />
</LinearLayout>
</ScrollView>
diff --git a/android/source/res/layout/activity_directory_browser.xml b/android/source/res/layout/activity_directory_browser.xml
deleted file mode 100644
index b03c6bbb1224..000000000000
--- a/android/source/res/layout/activity_directory_browser.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/fragment_container"
- android:layout_width="match_parent" android:layout_height="match_parent">
-
-</FrameLayout> \ No newline at end of file
diff --git a/android/source/res/layout/activity_document_browser.xml b/android/source/res/layout/activity_document_browser.xml
index 8e17a3e1624f..72b6e42b29b2 100644
--- a/android/source/res/layout/activity_document_browser.xml
+++ b/android/source/res/layout/activity_document_browser.xml
@@ -6,7 +6,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -14,12 +14,11 @@
android:orientation="vertical">
<!-- The toolbar -->
- <android.support.v7.widget.Toolbar
+ <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="3dp"
- android:background="@color/toolbar_background"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:theme="@style/LibreOfficeTheme.Toolbar"
app:popupTheme="@style/LibreOfficeTheme"
@@ -30,10 +29,10 @@
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
- </android.support.v7.widget.Toolbar>
+ </com.google.android.material.appbar.MaterialToolbar>
- <android.support.v4.widget.DrawerLayout
+ <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="0dp"
android:layout_height="0dp"
@@ -47,7 +46,7 @@
app:layout_constraintLeft_toLeftOf="parent">
<!-- The content -->
- <android.support.v4.widget.NestedScrollView
+ <androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -59,78 +58,62 @@
android:showDividers="middle">
<TextView
+ android:id="@+id/header_browser"
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:id="@+id/header_recents"
- android:text="@string/title_recents"
+ android:layout_height="wrap_content"
android:gravity="center_vertical"
- android:textSize="14sp"
android:padding="16dp"
+ android:text="@string/title_browser"
+ android:textSize="14sp"
android:textStyle="bold" />
- <!--Recent files-->
- <android.support.v7.widget.RecyclerView
- android:id="@+id/list_recent"
+ <Button
+ android:id="@+id/open_file_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp" />
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+ android:text="@string/select_file_to_open"
+ android:textSize="14dp"
+ app:drawableLeftCompat="@drawable/ic_folder_48dp" />
<TextView
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:id="@+id/header_browser"
- android:text="@string/title_browser"
+ android:layout_height="wrap_content"
+ android:id="@+id/header_recents"
+ android:text="@string/title_recents"
android:gravity="center_vertical"
android:textSize="14sp"
android:padding="16dp"
android:textStyle="bold" />
- <TextView
+ <!--Recent files-->
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/list_recent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textSize="14sp"
- android:padding="7dp"
- android:id="@+id/text_directory_path"
- android:background="@color/background_normal"
- />
-
-
- <!--Document browser-->
- <android.support.v7.widget.RecyclerView
- android:id="@+id/file_recycler_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/background_normal"
- android:orientation="vertical" />
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp" />
</LinearLayout>
- </android.support.v4.widget.NestedScrollView>
+ </androidx.core.widget.NestedScrollView>
<!-- The navigation drawer -->
- <android.support.design.widget.NavigationView
- android:id="@+id/navigation_drawer"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="@color/background_normal"
- app:menu="@menu/navigation_menu"
- android:theme="@style/LibreOfficeTheme.NavigationView" />
- </android.support.v4.widget.DrawerLayout>
+ </androidx.drawerlayout.widget.DrawerLayout>
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/editFAB"
+ android:contentDescription="@string/create_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
- android:visibility="invisible"
- app:backgroundTint="@color/background_normal"
+ app:backgroundTint="@color/background_floating"
app:fabSize="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
- app:srcCompat="@drawable/ic_add_black_24dp"
+ app:srcCompat="@drawable/ic_add_24dp"
app:useCompatPadding="true" />
<LinearLayout
@@ -151,14 +134,14 @@
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:text="@string/new_textdocument" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/newWriterFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/new_doc_fab_tweak_bottom"
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:clickable="true"
- app:backgroundTint="@color/background_normal"
+ app:backgroundTint="@color/background_floating"
app:fabSize="mini"
app:srcCompat="@drawable/writer"
app:useCompatPadding="true" />
@@ -183,14 +166,14 @@
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:text="@string/new_presentation" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/newImpressFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/new_doc_fab_tweak_bottom"
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:clickable="true"
- app:backgroundTint="@color/background_normal"
+ app:backgroundTint="@color/background_floating"
app:fabSize="mini"
app:srcCompat="@drawable/impress"
app:useCompatPadding="true" />
@@ -215,14 +198,14 @@
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:text="@string/new_spreadsheet" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/newCalcFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/new_doc_fab_tweak_bottom"
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:clickable="true"
- app:backgroundTint="@color/background_normal"
+ app:backgroundTint="@color/background_floating"
app:fabSize="mini"
app:srcCompat="@drawable/calc"
app:useCompatPadding="true" />
@@ -247,18 +230,18 @@
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:text="@string/new_drawing" />
- <android.support.design.widget.FloatingActionButton
+ <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/newDrawFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/new_doc_fab_tweak_bottom"
android:layout_marginTop="@dimen/new_doc_fab_tweak_top"
android:clickable="true"
- app:backgroundTint="@color/background_normal"
+ app:backgroundTint="@color/background_floating"
app:fabSize="mini"
app:srcCompat="@drawable/draw"
app:useCompatPadding="true" />
</LinearLayout>
-</android.support.constraint.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/android/source/res/layout/activity_main.xml b/android/source/res/layout/activity_main.xml
index c2528023d0f8..e503cb90f0eb 100644
--- a/android/source/res/layout/activity_main.xml
+++ b/android/source/res/layout/activity_main.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout"
+<androidx.drawerlayout.widget.DrawerLayout android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -8,7 +8,7 @@
android:background="#fff"
tools:context=".LibreOfficeMainActivity">
- <android.support.design.widget.CoordinatorLayout
+ <androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -18,44 +18,46 @@
android:layout_height="match_parent"
android:orientation="vertical">
- <android.support.design.widget.AppBarLayout
+ <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
- <android.support.v7.widget.Toolbar
+ <com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="3dp"
- android:background="@color/toolbar_background"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:theme="@style/LibreOfficeTheme.Toolbar"
app:popupTheme="@style/LibreOfficeTheme" />
- </android.support.design.widget.AppBarLayout>
+ </com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:background="@color/background_floating">
<EditText
android:id="@+id/calc_address"
android:layout_width="@dimen/calc_address_bar_width"
- android:layout_height="@dimen/calc_toolbar_height"
+ android:layout_height="wrap_content"
android:layout_weight="0"
android:inputType="textNoSuggestions"
android:imeOptions="actionDone|actionGo"
- android:visibility="gone"/>
+ android:visibility="gone"
+ android:importantForAutofill="no" />
<EditText
android:id="@+id/calc_formula"
android:layout_width="0dp"
- android:layout_height="@dimen/calc_toolbar_height"
+ android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="text"
android:imeOptions="actionDone|actionGo"
- android:visibility="gone"/>
+ android:visibility="gone"
+ android:importantForAutofill="no" />
</LinearLayout>
@@ -133,7 +135,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
- </android.support.design.widget.CoordinatorLayout>
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
<ListView
android:id="@+id/left_drawer"
@@ -143,4 +145,4 @@
android:background="#9FFF"
android:choiceMode="singleChoice"/>
-</android.support.v4.widget.DrawerLayout>
+</androidx.drawerlayout.widget.DrawerLayout>
diff --git a/android/source/res/layout/file_explorer_grid_item.xml b/android/source/res/layout/file_explorer_grid_item.xml
deleted file mode 100644
index e64fdc23a6a7..000000000000
--- a/android/source/res/layout/file_explorer_grid_item.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- This file is part of the LibreOffice project.
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
- android:orientation="vertical" >
-
- <ImageView
- android:id="@+id/file_item_icon"
- tools:src="@drawable/ic_folder_black_24dp"
- tools:tint="@color/text_color_secondary"
- android:layout_width="100dp"
- android:layout_height="100dp"
- android:scaleType="fitStart"
- android:layout_gravity="center"
- android:contentDescription="@string/file_icon_desc" >
- </ImageView>
-
- <TextView
- android:id="@+id/file_item_name"
- tools:text="file or dirname"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="10dp"
- android:paddingRight="10dp"
- android:paddingTop="10dp"
- android:layout_gravity="center"
- android:textSize="15sp"
- android:textStyle="bold"
- android:textColor="@android:color/secondary_text_light"
- android:maxLines="2">
- </TextView>
-
-</LinearLayout>
diff --git a/android/source/res/layout/file_grid.xml b/android/source/res/layout/file_grid.xml
deleted file mode 100644
index 1885bd34ed6a..000000000000
--- a/android/source/res/layout/file_grid.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- This file is part of the LibreOffice project.
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <GridView
- android:id="@+id/file_explorer_grid_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:columnWidth="120dp"
- android:numColumns="auto_fit"
- android:verticalSpacing="10dp"
- android:horizontalSpacing="10dp"
- android:stretchMode="columnWidth"
- android:gravity="center">
- </GridView>
-
-</LinearLayout>
diff --git a/android/source/res/layout/file_list.xml b/android/source/res/layout/file_list.xml
deleted file mode 100644
index 48dfb1e31267..000000000000
--- a/android/source/res/layout/file_list.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- This file is part of the LibreOffice project.
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
- <ListView
- android:id="@+id/file_explorer_list_view"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- </ListView>
-
-</LinearLayout>
diff --git a/android/source/res/layout/file_list_item.xml b/android/source/res/layout/file_list_item.xml
deleted file mode 100644
index 518885d4b296..000000000000
--- a/android/source/res/layout/file_list_item.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- This file is part of the LibreOffice project.
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
- -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="48dp"
- android:orientation="horizontal"
- android:layout_marginStart="@dimen/list_item_margin"
- android:layout_marginLeft="@dimen/list_item_margin"
- android:layout_marginEnd="@dimen/list_item_margin"
- android:layout_marginRight="@dimen/list_item_margin">
- <ImageView
- android:id="@+id/file_item_icon"
- tools:src="@drawable/ic_folder_black_24dp"
- tools:tint="@color/text_color_secondary"
- android:layout_height="match_parent"
- android:layout_width="@dimen/file_icon_width"
- android:layout_marginEnd="@dimen/file_icon_margin_end"
- android:layout_marginRight="@dimen/file_icon_margin_end"
- android:layout_gravity="center"
- android:contentDescription="@string/file_icon_desc" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="48dp"
- android:orientation="horizontal">
- <TextView
- android:id="@+id/file_item_name"
- tools:text="file or dirname"
- style="@style/ListItemText"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="2"
- android:ellipsize="end"
- android:maxLines="1"/>
- <TextView
- android:id="@+id/file_item_size"
- tools:text="filesize"
- style="@style/ListItemText"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="1" />
- <TextView
- android:id="@+id/file_item_date"
- tools:text="date/time"
- style="@style/ListItemText"
- android:layout_height="match_parent"
- android:layout_width="0dp"
- android:layout_weight="2"
- android:ellipsize="end"
- android:gravity="end"
- android:maxLines="1"/>
- </LinearLayout>
-</LinearLayout>
diff --git a/android/source/res/layout/fragment_directory_browser.xml b/android/source/res/layout/fragment_directory_browser.xml
deleted file mode 100644
index 37a61fa3518c..000000000000
--- a/android/source/res/layout/fragment_directory_browser.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#FFFFFF">
-
- <LinearLayout
- android:id="@+id/browser_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <ImageView
- android:id="@+id/up_image"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:src="@drawable/ic_menu_back"
- android:scaleType="fitCenter"
- android:adjustViewBounds="true"
- android:contentDescription="@string/up_description"/>
-
- <EditText
- android:id="@+id/directory_header"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:maxLines="1"
- android:scrollHorizontally="true"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:inputType="text"/>
-
- <Button
- android:id="@+id/directory_search_button"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="@string/search_label"/>
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/browser_footer"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_alignParentBottom="true">
-
- <Button
- android:id="@+id/cancel_button"
- android:layout_height="wrap_content"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:text="@string/cancel_label"/>
-
- <Button
- android:id="@+id/confirm_button"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:text="@string/confirm_label"/>
- </LinearLayout>
-
- <ListView
- android:id="@+id/directory_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/browser_header"
- android:layout_above="@id/browser_footer">
- </ListView>
-
-
-</RelativeLayout> \ No newline at end of file
diff --git a/android/source/res/layout/item_recent_files.xml b/android/source/res/layout/item_recent_files.xml
index b374ba56f04f..f13839b44b73 100644
--- a/android/source/res/layout/item_recent_files.xml
+++ b/android/source/res/layout/item_recent_files.xml
@@ -11,7 +11,6 @@
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
- android:background="?android:attr/selectableItemBackground"
android:layout_marginStart="@dimen/list_item_margin"
android:layout_marginLeft="@dimen/list_item_margin"
android:layout_marginEnd="@dimen/list_item_margin"
diff --git a/android/source/res/layout/number_picker.xml b/android/source/res/layout/number_picker.xml
index 51463926c70f..32eea0e80a84 100644
--- a/android/source/res/layout/number_picker.xml
+++ b/android/source/res/layout/number_picker.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -127,4 +127,4 @@
android:background="@drawable/image_button_background"
app:layout_constraintEnd_toEndOf="@+id/numberpickerLayout"
app:layout_constraintTop_toBottomOf="@+id/number_picker_rows_positive" />
-</android.support.constraint.ConstraintLayout> \ No newline at end of file
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/android/source/res/layout/toolbar_bottom.xml b/android/source/res/layout/toolbar_bottom.xml
index f4b3f3c5f8cc..172b215f5a1c 100644
--- a/android/source/res/layout/toolbar_bottom.xml
+++ b/android/source/res/layout/toolbar_bottom.xml
@@ -7,13 +7,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:background="@color/toolbar_background"
+ android:background="?attr/colorPrimary"
android:elevation="3dp"
android:orientation="vertical"
app:popupTheme="@style/LibreOfficeTheme.Toolbar"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:showIn="@layout/activity_main"
- app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
+ app:layout_behavior="@string/bottom_sheet_behavior"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp">
@@ -115,7 +115,7 @@
android:background="@drawable/image_button_background"
android:paddingBottom="12dp"
android:paddingTop="12dp"
- app:srcCompat="@drawable/ic_format_clear_black_24dp" />
+ app:srcCompat="@drawable/ic_format_clear_24dp" />
</LinearLayout>
@@ -269,6 +269,27 @@
android:paddingBottom="12dp"
android:paddingTop="12dp"
android:src="@drawable/ic_format_bullets" />
+
+ <ImageButton
+ android:id="@+id/button_increaseIndent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.25"
+ android:background="@drawable/image_button_background"
+ android:paddingBottom="12dp"
+ android:paddingTop="12dp"
+ android:src="@drawable/ic_incrementindent" />
+
+ <ImageButton
+ android:id="@+id/button_decreaseIndent"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.25"
+ android:background="@drawable/image_button_background"
+ android:paddingBottom="12dp"
+ android:paddingTop="12dp"
+ android:src="@drawable/ic_decrementindent" />
+
</LinearLayout>
</LinearLayout>
@@ -319,7 +340,7 @@
android:background="@drawable/image_button_background"
android:paddingBottom="12dp"
android:paddingTop="12dp"
- app:srcCompat="@drawable/ic_folder_black_24dp" />
+ app:srcCompat="@drawable/ic_folder_24dp" />
<ImageButton
android:id="@+id/button_insert_table"
@@ -329,7 +350,7 @@
android:background="@drawable/image_button_background"
android:paddingBottom="12dp"
android:paddingTop="12dp"
- app:srcCompat="@drawable/ic_grid_on_black_24dp" />
+ app:srcCompat="@drawable/ic_grid_on_24dp" />
<ImageButton
android:id="@+id/button_delete_table"
@@ -339,7 +360,7 @@
android:background="@drawable/image_button_background"
android:paddingBottom="12dp"
android:paddingTop="12dp"
- app:srcCompat="@drawable/ic_grid_off_black_24dp" />
+ app:srcCompat="@drawable/ic_grid_off_24dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
@@ -370,7 +391,7 @@
android:paddingTop="12dp"
android:textSize="14sp"
android:gravity="center_vertical"
- android:textColor="@color/fontBlack"
+ android:textColor="?android:attr/textColorPrimary"
android:layout_alignParentLeft="true"
/>
@@ -399,7 +420,7 @@
android:paddingTop="12dp"
android:textSize="14sp"
android:gravity="center_vertical"
- android:textColor="@color/fontBlack"
+ android:textColor="?android:attr/textColorPrimary"
android:layout_alignParentLeft="true"
/>
@@ -445,7 +466,8 @@
android:layout_weight="0.6"
android:background="@drawable/image_button_background"
android:padding="10dp"
- android:src="@drawable/ic_search_direction_down" />
+ android:src="@drawable/ic_search_direction_down"
+ android:contentDescription="@string/search_find_next" />
<ImageButton
android:id="@+id/button_search_up"
@@ -454,7 +476,8 @@
android:layout_weight="0.6"
android:background="@drawable/image_button_background"
android:padding="10dp"
- android:src="@drawable/ic_search_direction_up" />
+ android:src="@drawable/ic_search_direction_up"
+ android:contentDescription="@string/search_find_previous" />
</LinearLayout>
<LinearLayout
@@ -491,7 +514,7 @@
android:layout_height="wrap_content"
android:background="@drawable/image_button_background"
android:padding="10dp"
- app:srcCompat="@drawable/ic_filter_list_black_24dp" />
+ app:srcCompat="@drawable/ic_filter_list_24dp" />
<ImageButton
android:id="@+id/button_send_UNO_commands_clear"
@@ -543,7 +566,7 @@
android:layout_height="wrap_content"
android:background="@drawable/image_button_background"
android:padding="10dp"
- app:srcCompat="@drawable/ic_add_black_24dp" />
+ app:srcCompat="@drawable/ic_add_24dp" />
</LinearLayout>
diff --git a/android/source/res/layout/toolbar_color_picker.xml b/android/source/res/layout/toolbar_color_picker.xml
index 9393259123be..0969d0e52e3d 100644
--- a/android/source/res/layout/toolbar_color_picker.xml
+++ b/android/source/res/layout/toolbar_color_picker.xml
@@ -6,13 +6,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:background="@color/toolbar_background"
+ android:background="?attr/colorPrimary"
android:elevation="3dp"
android:orientation="vertical"
app:popupTheme="@style/LibreOfficeTheme.Toolbar"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:showIn="@layout/activity_main"
- app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
+ app:layout_behavior="@string/bottom_sheet_behavior"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp">
@@ -21,23 +21,41 @@
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="vertical">
- <ImageButton
- android:id="@+id/button_go_back_color_picker"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:srcCompat="@drawable/ic_arrow_back_black_24dp"
- android:background="@drawable/image_button_background"
- android:layout_marginBottom="10dp"/>
- <android.support.v7.widget.RecyclerView
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal">
+
+ <ImageButton
+ android:id="@+id/button_go_back_color_picker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:background="@drawable/image_button_background"
+ app:srcCompat="@drawable/ic_arrow_back_24dp" />
+
+ <Button
+ android:id="@+id/button_auto_color"
+ android:layout_alignParentRight="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:background="@drawable/image_button_background"
+ android:text="@string/automatic"
+ app:drawableLeftCompat="@drawable/ic_auto_color" />
+
+ </RelativeLayout>
+
+ <androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fontColorView"
>
- </android.support.v7.widget.RecyclerView>
+ </androidx.recyclerview.widget.RecyclerView>
- <android.support.v7.widget.RecyclerView
+ <androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fontColorViewSub"
@@ -45,11 +63,11 @@
android:layout_below="@id/fontColorView"
android:layout_alignParentBottom="true">
- </android.support.v7.widget.RecyclerView>
+ </androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/android/source/res/menu/context_menu.xml b/android/source/res/menu/context_menu.xml
deleted file mode 100644
index 43824875d867..000000000000
--- a/android/source/res/menu/context_menu.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:id="@+id/context_menu_open"
- android:title="@string/open"/>
- <item android:id="@+id/context_menu_share"
- android:title="@string/share"/>
-</menu>
diff --git a/android/source/res/menu/main.xml b/android/source/res/menu/main.xml
index 2c97b3201b9e..cbca33aa4a81 100644
--- a/android/source/res/menu/main.xml
+++ b/android/source/res/menu/main.xml
@@ -31,10 +31,25 @@
android:orderInCategory="100"
app:showAsAction="always"/>
+ <item android:id="@+id/action_UNO_commands"
+ android:title="@string/action_UNO_commands"
+ android:orderInCategory="100" />
+
+ </group>
+
+ <group android:id="@+id/group_misc_actions"
+ tools:visible="true"
+ android:visible="false">
<item android:id="@+id/action_save"
android:title="@string/action_save"
- android:orderInCategory="100" />
+ android:orderInCategory="100"
+ android:visible="true" />
+
+ <item android:id="@+id/action_save_as"
+ android:title="@string/action_save_as"
+ android:orderInCategory="100"
+ android:visible="true" />
<item android:id="@+id/action_exportToPDF"
android:title="@string/action_exportToPDF"
@@ -47,9 +62,6 @@
android:orderInCategory="100"
android:visible="true" />
- <item android:id="@+id/action_UNO_commands"
- android:title="@string/action_UNO_commands"
- android:orderInCategory="100" />
</group>
<group android:id="@+id/group_spreadsheet_options"
@@ -98,25 +110,25 @@
<item android:id="@+id/action_back"
android:title="@string/action_back"
app:showAsAction="always"
- android:icon="@drawable/ic_arrow_back_black_24dp"
+ android:icon="@drawable/ic_arrow_back_24dp"
android:orderInCategory="1"/>
<item android:id="@+id/action_copy"
android:title="@string/action_copy"
app:showAsAction="always"
- android:icon="@drawable/ic_content_copy_black_24dp"
+ android:icon="@drawable/ic_content_copy_24dp"
android:orderInCategory="2"/>
<item android:id="@+id/action_cut"
android:title="@string/action_cut"
app:showAsAction="always"
- android:icon="@drawable/ic_content_cut_black_24dp"
+ android:icon="@drawable/ic_content_cut_24dp"
android:orderInCategory="3"/>
<item android:id="@+id/action_paste"
android:title="@string/action_paste"
app:showAsAction="always"
- android:icon="@drawable/ic_content_paste_black_24dp"
+ android:icon="@drawable/ic_content_paste_24dp"
android:orderInCategory="4"/>
</group>
diff --git a/android/source/res/menu/navigation_menu.xml b/android/source/res/menu/navigation_menu.xml
deleted file mode 100644
index db680a9a1b8c..000000000000
--- a/android/source/res/menu/navigation_menu.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <group
- android:checkableBehavior="single"
- android:id="@+id/group_providers">
-
- <item android:id="@+id/menu_provider_documents"
- android:title="@string/local_documents"
- android:icon="@drawable/ic_folder_black_24dp" />
-
- <item android:id="@+id/menu_provider_filesystem"
- android:title="@string/local_file_system"
- android:icon="@drawable/ic_storage_black_24dp"/>
-
- <item android:id="@+id/menu_provider_extsd"
- android:title="@string/external_sd_file_system"
- android:icon="@drawable/ic_sd_card_black_24dp"/>
-
- <item android:id="@+id/menu_provider_otg"
- android:title="@string/otg_file_system"
- android:icon="@drawable/ic_usb_black_24dp"/>
-
- <item android:id="@+id/menu_provider_owncloud"
- android:title="@string/owncloud"
- android:icon="@drawable/ic_cloud_black_24dp"/>
-
-
- </group>
-
- <group android:orderInCategory="100">
- <item android:id="@+id/menu_storage_preferences"
- android:title="@string/storage_provider_settings"
- android:icon="@drawable/ic_settings_black_24dp"/>
- </group>
-</menu>
diff --git a/android/source/res/menu/view_menu.xml b/android/source/res/menu/view_menu.xml
index 67f059647989..a40bdf5802c9 100644
--- a/android/source/res/menu/view_menu.xml
+++ b/android/source/res/menu/view_menu.xml
@@ -2,60 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
- <item
- android:id="@+id/menu_filter"
- android:title="@string/filter"
- android:icon="@drawable/ic_filter_list_black_24dp"
- app:showAsAction="ifRoom">
- <menu>
- <group
- android:checkableBehavior="single">
- <item
- android:id="@+id/menu_filter_everything"
- android:title="@string/filter_everything" />
- <item
- android:id="@+id/menu_filter_documents"
- android:title="@string/filter_documents" />
- <item
- android:id="@+id/menu_filter_spreadsheets"
- android:title="@string/filter_spreadsheets" />
- <item
- android:id="@+id/menu_filter_presentations"
- android:title="@string/filter_presentations" />
- <item
- android:id="@+id/menu_filter_drawings"
- android:title="@string/filter_drawings" />
- </group>
- </menu>
- </item>
-
- <item
- android:id="@+id/menu_sort"
- android:title="@string/sort"
- android:icon="@drawable/ic_sort_black_24dp"
- app:showAsAction="ifRoom">
- <menu>
- <group android:checkableBehavior="single">
- <item android:id="@+id/menu_sort_size_asc"
- android:title="@string/sort_smallest" />
-
- <item android:id="@+id/menu_sort_size_desc"
- android:title="@string/sort_largest" />
-
- <item android:id="@+id/menu_sort_az"
- android:title="@string/sort_az"/>
-
- <item android:id="@+id/menu_sort_za"
- android:title="@string/sort_za"/>
-
- <item android:id="@+id/menu_sort_modified_newest"
- android:title="@string/sort_newest"/>
-
- <item android:id="@+id/menu_sort_modified_oldest"
- android:title="@string/sort_oldest"/>
- </group>
- </menu>
- </item>
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"/>
diff --git a/android/source/res/mipmap-hdpi/ic_launcher.png b/android/source/res/mipmap-hdpi/ic_launcher.png
index f8b74553e385..0765a1e0108e 100644
--- a/android/source/res/mipmap-hdpi/ic_launcher.png
+++ b/android/source/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/android/source/res/mipmap-mdpi/ic_launcher.png b/android/source/res/mipmap-mdpi/ic_launcher.png
index fa68d30f003a..dcc03ff1fb2c 100644
--- a/android/source/res/mipmap-mdpi/ic_launcher.png
+++ b/android/source/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/android/source/res/mipmap-xhdpi/ic_launcher.png b/android/source/res/mipmap-xhdpi/ic_launcher.png
index 12069c7e8ac5..d8fb1d912633 100644
--- a/android/source/res/mipmap-xhdpi/ic_launcher.png
+++ b/android/source/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/android/source/res/mipmap-xxhdpi/ic_launcher.png b/android/source/res/mipmap-xxhdpi/ic_launcher.png
index a00a40dbe1de..7b9a8029aa40 100644
--- a/android/source/res/mipmap-xxhdpi/ic_launcher.png
+++ b/android/source/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/source/res/mipmap-xxxhdpi/ic_launcher.png b/android/source/res/mipmap-xxxhdpi/ic_launcher.png
index ef7067cbd2a3..86d268ede8ef 100644
--- a/android/source/res/mipmap-xxxhdpi/ic_launcher.png
+++ b/android/source/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/source/res/values-ab/strings.xml b/android/source/res/values-ab/strings.xml
new file mode 100644
index 000000000000..a6b3daec9354
--- /dev/null
+++ b/android/source/res/values-ab/strings.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources></resources> \ No newline at end of file
diff --git a/android/source/res/values-ast/strings.xml b/android/source/res/values-ast/strings.xml
new file mode 100644
index 000000000000..27e9d06bd131
--- /dev/null
+++ b/android/source/res/values-ast/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="about_license">Amosar la llicencia</string>
+ <string name="new_textdocument">Documentu de testu nuevu</string>
+ <string name="new_drawing">Dibuxu nuevu</string>
+ <string name="default_document_name">ensin títulu</string>
+ <string name="select_file_to_open">Esbilla\'l ficheru que quies abrir</string>
+ <string name="title_recents">Ficheros recién</string>
+ <string name="title_browser">Tolos ficheros</string>
+ <string name="action_settings">Axustes</string>
+ <string name="action_keyboard">Amosar el tecláu</string>
+ <string name="action_redo">Refacer</string>
+ <string name="no_save_document">NON</string>
+ <string name="calc_delete">Desaniciar</string>
+ <string name="calc_hide">Anubrir</string>
+ <string name="calc_show">Amosar</string>
+ <string name="sheet">Fueya</string>
+ <string name="readonly_file">Esti ficheru ye namái de llectura.</string>
+ <string name="new_presentation">Presentación nueva</string>
+ <string name="new_spreadsheet">Fueya de cálculu nueva</string>
+ <string name="action_about">Tocante a</string>
+ <string name="action_save">Guardar</string>
+ <string name="action_search">Guetar</string>
+ <string name="action_undo">Desfacer</string>
+ <string name="page">Páxina</string>
+ <string name="app_name_settings">Configuración del visor del LibreOffice</string>
+ <string name="app_version">Versión: %1$s&lt;br&gt;Identificador de la construción: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">El Visor del LibreOffice ye un visor de documentos basáu nel LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Esta versión fornióla $VENDOR.</string>
+ <string name="app_name">Visor del LibreOffice</string>
+ <string name="pref_category_general">Xenerales</string>
+ <string name="pref_experimental_editing">Mou esperimental</string>
+ <string name="pref_developer_mode">Mou de desendolcu</string>
+ <string name="action_save_as">Guardar como…</string>
+ <string name="message_saving">Guardando’l documentu…</string>
+ <string name="message_saving_failed">Nun se pudo guardar el documentu.</string>
+ <string name="save_alert_dialog_title">¿Quies guardar el documentu enantes de zarralu\?</string>
+ <string name="save_document">GUARDAR</string>
+ <string name="action_cancel">Encaboxar</string>
+ <string name="about_notice">Amosar l\'avisu</string>
+ <string name="about_privacy_policy">Política de privacidá</string>
+ <string name="create_file">Crear un ficheru nuevu</string>
+ <string name="search_find_next">Atopar siguiente</string>
+ <string name="search_find_previous">Atopar anterior</string>
+ <string name="file_icon_desc">iconu de ficheru</string>
+ <string name="pref_experimental_editing_summary">Activa\'l mou d\'edición esperimental. Úsalu baxo la to responsabilidá.</string>
+ <string name="pref_developer_mode_summary">Activar mou de desendolcu, nel que se puen unviar ordes d\'UNO dientro de l\'app. Úsalu baxo la to responsabilidá.</string>
+ <string name="action_parts">Partes</string>
+ <string name="action_fromat">Activar el formatu</string>
+ <string name="action_UNO_commands">Unviar orde UNO</string>
+ <string name="message_saved">Guardar completu</string>
+ <string name="password">Contraseña</string>
+ <string name="action_presentation">Presentación de diapositives</string>
+ <string name="action_add_slide">Ametar diapositiva</string>
+ <string name="slideshow_action_back">Atrás</string>
+ <string name="calc_insert_before">Inxertar</string>
+ <string name="calc_optimal_length">Llargor óptimu</string>
+ <string name="calc_adjust_length">Axustar el llargor</string>
+ <string name="calc_adjust_width">Axustar l\'anchor</string>
+ <string name="calc_optimal_height">Altor óptimu</string>
+ <string name="calc_optimal_width">Anchor óptimu</string>
+ <string name="calc_optimal_length_confirm">Val</string>
+ <string name="calc_optimal_length_default_text">Pon el llargor extra en centésimes de milímetru</string>
+ <string name="action_add_worksheet">Amestar fueya de cálculu</string>
+ <string name="action_pwd_dialog_OK">Val</string>
+ <string name="action_pwd_dialog_cancel">Encaboxar</string>
+ <string name="action_pwd_dialog_title">Pon la contraseña</string>
+ <string name="take_photo">Facer foto</string>
+ <string name="calc_adjust_height">Axustar l\'altor</string>
+ <string name="calc_alert_double_click_optimal_length">Conseyu: Tocar dos vegaes na testera define l\'anchor/altor óptimu.</string>
+ <string name="select_photo_title">Esbillar una imaxe</string>
+ <string name="no_camera_found">Nun s\'atopó denguna cámara</string>
+ <string name="compress_photo_smallest_size">Tamañu menor</string>
+ <string name="compress_photo_medium_size">Tamañu mediu</string>
+ <string name="compress_photo_max_quality">Calidá máxima</string>
+ <string name="compress_photo_no_compress">Nun comprimir</string>
+ <string name="compress_photo_title">¿Quies comprimir la foto\?</string>
+ <string name="action_copy">Copia</string>
+ <string name="action_paste">Apegar</string>
+ <string name="action_cut">Cortar</string>
+ <string name="action_back">Atrás</string>
+ <string name="action_text_copied">Copióse\'l testu al cartafueyu</string>
+ <string name="insert_table">Inxertar tabla</string>
+ <string name="select_insert_options">Escoyer opciones d\'inxerimientu:</string>
+ <string name="select_delete_options">Escoyer opciones de desaniciu:</string>
+ <string name="action_rename_worksheet">Renomar la fueya de cálculu</string>
+ <string name="action_delete_worksheet">Desaniciar fueya</string>
+ <string name="action_delete_slide">Desaniciar diapositiva</string>
+ <string name="name_already_used">El nome que punxisti yá se ta usando.</string>
+ <string name="part_name_changed">El nome de la parte camudó.</string>
+ <string name="part_deleted">Desanicióse una parte</string>
+ <string name="UNO_commands_string_hint">Orde de UNO</string>
+ <string name="UNO_commands_string_type_hint">Triba</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor cimeru</string>
+ <string name="action_exportToPDF">Esportar a PDF</string>
+ <string name="action_print">Imprentar</string>
+ <string name="tabhost_character">Carácter</string>
+ <string name="tabhost_paragraph">Párrafu</string>
+ <string name="tabhost_insert">Inxertar</string>
+ <string name="tabhost_style">Estilu</string>
+ <string name="alert_ok">Val</string>
+ <string name="alert_cancel">Encaboxar</string>
+ <string name="current_uno_command">Orde d\'UNO actual</string>
+ <string name="display_language">Llingua p\'amosar</string>
+ <string name="select_photo">Esbilla una foto</string>
+ <string name="pdf_export_finished">Acabó la esportación a PDF</string>
+ <string name="unable_to_export_pdf">Nun se pudo esportar a PDF</string>
+ <string name="unable_to_save">Nun se pudo guardar el ficheru</string>
+ <string name="error">Fallu</string>
+ <string name="enter_part_name">Pon un nome pa la parte</string>
+ <string name="bmp_null">El BMP nun val.</string>
+ <string name="slide">Diapositiva</string>
+ <string name="part">Parte</string>
+ <string name="highlight_color">Color de resalte</string>
+ <string name="font_color">Color de la lletra</string>
+ <string name="action_rename_slide">Cambiar el nome de la diapositiva</string>
+ <string name="automatic">Automaticu</string>
+ <string name="display_language_summary">Afitar la llingua predeterminada de la interfaz</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-ca/strings.xml b/android/source/res/values-ca/strings.xml
new file mode 100644
index 000000000000..531bae150b78
--- /dev/null
+++ b/android/source/res/values-ca/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Visualitzador del LibreOffice</string>
+ <string name="app_credits">https://ca.libreoffice.org</string>
+ <string name="action_keyboard">Mostra el teclat</string>
+ <string name="action_save">Desa</string>
+ <string name="action_pwd_dialog_title">Introduïu la contrasenya</string>
+ <string name="take_photo">Fes una foto</string>
+ <string name="action_copy">Copia</string>
+ <string name="action_paste">Enganxa</string>
+ <string name="action_cut">Retalla</string>
+ <string name="action_back">Enrere</string>
+ <string name="tabhost_insert">Insereix</string>
+ <string name="tabhost_style">Estil</string>
+ <string name="page">Pàgina</string>
+ <string name="sheet">Full</string>
+ <string name="slide">Diapositiva</string>
+ <string name="part">Part</string>
+ <string name="automatic">Automàtic</string>
+ <string name="font_color">Color de la lletra</string>
+ <string name="app_name_settings">Paràmetres del visualitzador del LibreOffice</string>
+ <string name="app_description">Aquesta aplicació és un visualitzador de documents basat en el LibreOffice.</string>
+ <string name="readonly_file">Aquest fitxer és només de lectura.</string>
+ <string name="about_license">Mostra la llicència</string>
+ <string name="new_textdocument">Document de text nou</string>
+ <string name="new_presentation">Presentació nova</string>
+ <string name="new_spreadsheet">Full de càlcul nou</string>
+ <string name="new_drawing">Dibuix nou</string>
+ <string name="default_document_name">sense títol</string>
+ <string name="title_recents">Fitxers recents</string>
+ <string name="title_browser">Tots els fitxers</string>
+ <string name="pref_experimental_editing">Mode experimental</string>
+ <string name="pref_developer_mode">Mode de desenvolupament</string>
+ <string name="action_about">Quant a</string>
+ <string name="action_parts">Parts</string>
+ <string name="action_settings">Paràmetres</string>
+ <string name="action_save_as">Anomena i desa…</string>
+ <string name="action_search">Cerca</string>
+ <string name="password">Contrasenya</string>
+ <string name="action_undo">Desfés</string>
+ <string name="action_redo">Refés</string>
+ <string name="save_alert_dialog_title">Voleu desar el document abans de tancar-lo\?</string>
+ <string name="save_document">DESA</string>
+ <string name="no_save_document">NO</string>
+ <string name="action_presentation">Presentació de diapositives</string>
+ <string name="action_add_slide">Afegeix una diapositiva</string>
+ <string name="slideshow_action_back">Enrere</string>
+ <string name="calc_insert_before">Insereix</string>
+ <string name="calc_delete">Suprimeix</string>
+ <string name="calc_hide">Amaga</string>
+ <string name="calc_show">Mostra</string>
+ <string name="insert_table">Insereix una taula</string>
+ <string name="action_delete_slide">Suprimeix la diapositiva</string>
+ <string name="UNO_commands_string_type_hint">Tipus</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="action_exportToPDF">Exporta com a PDF</string>
+ <string name="action_print">Imprimeix</string>
+ <string name="tabhost_character">Caràcter</string>
+ <string name="tabhost_paragraph">Paràgraf</string>
+ <string name="about_privacy_policy">Política de privadesa</string>
+ <string name="create_file">Crea un fitxer nou</string>
+ <string name="action_cancel">Cancel·la</string>
+ <string name="action_pwd_dialog_cancel">Cancel·la</string>
+ <string name="compress_photo_smallest_size">Mida més petita</string>
+ <string name="select_photo">Tria una foto</string>
+ <string name="select_photo_title">Trieu una imatge</string>
+ <string name="alert_cancel">Cancel·la</string>
+ <string name="enter_part_name">Introduïu un nom per a la part</string>
+ <string name="bmp_null">El BMP no és vàlid.</string>
+ <string name="action_delete_worksheet">Suprimeix el full</string>
+ <string name="highlight_color">Color de realçament</string>
+ <string name="app_version">Versió: %1$s&lt;br&gt;ID de compilació: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_notice">Mostra l\'avís</string>
+ <string name="app_vendor">$VENDOR us proporciona aquesta versió.</string>
+ <string name="select_file_to_open">Trieu el fitxer que voleu obrir</string>
+ <string name="search_find_next">Troba la següent</string>
+ <string name="search_find_previous">Troba l\'anterior</string>
+ <string name="file_icon_desc">icona de fitxer</string>
+ <string name="pref_category_general">General</string>
+ <string name="pref_experimental_editing_summary">Activa el mode d\'edició experimental. Useu-ho sota la vostra responsabilitat.</string>
+ <string name="pref_developer_mode_summary">Activa el mode de desenvolupament per a posar enviar ordres UNO amb l\'aplicació. Useu-ho sota la vostra responsabilitat.</string>
+ <string name="action_fromat">Activa el format</string>
+ <string name="action_UNO_commands">Envia una ordre UNO</string>
+ <string name="message_saving">S\'està desant el document…</string>
+ <string name="message_saving_failed">No s\'ha pogut desar el document.</string>
+ <string name="calc_optimal_length">Longitud òptima</string>
+ <string name="calc_adjust_length">Ajusta la longitud</string>
+ <string name="calc_adjust_height">Ajusta l\'alçada</string>
+ <string name="message_saved">S\'ha desat</string>
+ <string name="calc_adjust_width">Ajusta l\'amplada</string>
+ <string name="calc_optimal_height">Alçada òptima</string>
+ <string name="calc_optimal_width">Amplada òptima</string>
+ <string name="calc_optimal_length_confirm">D\'acord</string>
+ <string name="action_pwd_dialog_OK">D\'acord</string>
+ <string name="calc_optimal_length_default_text">Introduïu la longitud addicional en centèsimes de mil·límetre.</string>
+ <string name="action_add_worksheet">Afegeix un full de càlcul</string>
+ <string name="no_camera_found">No s\'ha trobat cap càmera</string>
+ <string name="compress_photo_medium_size">Mida mitjana</string>
+ <string name="compress_photo_max_quality">Màxima qualitat</string>
+ <string name="compress_photo_no_compress">Sense compressió</string>
+ <string name="compress_photo_title">Voleu comprimir la foto\?</string>
+ <string name="select_insert_options">Trieu les opcions d\'inserció:</string>
+ <string name="select_delete_options">Trieu les opcions de supressió:</string>
+ <string name="action_rename_worksheet">Canvia el nom del full de càcul</string>
+ <string name="name_already_used">El nom facilitat ja és en ús.</string>
+ <string name="UNO_commands_string_hint">Ordre UNO</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor superior</string>
+ <string name="action_text_copied">S\'ha copiat text al porta-retalls</string>
+ <string name="part_name_changed">S\'ha canviat el nom de la part.</string>
+ <string name="part_deleted">S\'ha suprimit la part.</string>
+ <string name="alert_ok">D\'acord</string>
+ <string name="display_language">Llengua de la interfície</string>
+ <string name="display_language_summary">Estableix la llengua predeterminada de la interfície</string>
+ <string name="pdf_export_finished">L\'exportació a PDF ha finalitzat</string>
+ <string name="unable_to_export_pdf">No s\'ha pogut exportar a pdf</string>
+ <string name="current_uno_command">Ordre UNO actual</string>
+ <string name="error">Error</string>
+ <string name="action_rename_slide">Canvia el nom de la diapositiva</string>
+ <string name="unable_to_save">No s\'ha pogut desar el fitxer</string>
+ <string name="calc_alert_double_click_optimal_length">Suggeriment: toqueu dues vegades una capçalera per a establir l\'amplada/alçada òptima.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-cs/strings.xml b/android/source/res/values-cs/strings.xml
new file mode 100644
index 000000000000..ee3bf0bc0b66
--- /dev/null
+++ b/android/source/res/values-cs/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="app_name_settings">Nastavení LibreOffice Viewer</string>
+ <string name="app_description">LibreOffice Viewer je prohlížeč dokumentů založený na LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Toto vydání bylo dodáno společností $VENDOR.</string>
+ <string name="app_version">Verze: %1$s&lt;br&gt;ID sestavení: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_license">Zobrazit licenci</string>
+ <string name="readonly_file">Tento soubor je pouze pro čtení.</string>
+ <string name="about_notice">Zobrazit upozornění</string>
+ <string name="about_privacy_policy">Zásady ochrany osobních údajů</string>
+ <string name="create_file">Vytvořit nový soubor</string>
+ <string name="new_textdocument">Nový textový dokument</string>
+ <string name="new_presentation">Nová prezentace</string>
+ <string name="new_drawing">Nová kresba</string>
+ <string name="default_document_name">bez názvu</string>
+ <string name="new_spreadsheet">Nový sešit</string>
+ <string name="pref_developer_mode_summary">Povolí vývojářský režim, ve kterém lze v aplikaci posílat příkazy UNO. Použití na vlastní nebezpečí.</string>
+ <string name="calc_show">Zobrazit</string>
+ <string name="pref_developer_mode">Vývojářský režim</string>
+ <string name="calc_hide">Skrýt</string>
+ <string name="action_UNO_commands">Poslat příkaz UNO</string>
+ <string name="action_about">O aplikaci</string>
+ <string name="action_fromat">Povolit formát</string>
+ <string name="password">Heslo</string>
+ <string name="select_insert_options">Vyberte možnosti vložení:</string>
+ <string name="slideshow_action_back">Zpět</string>
+ <string name="save_document">ULOŽIT</string>
+ <string name="calc_adjust_length">Upravit délku</string>
+ <string name="select_file_to_open">Vyberte soubor k otevření</string>
+ <string name="save_alert_dialog_title">Uložit dokument před zavřením?</string>
+ <string name="message_saving_failed">Ukládání dokumentu selhalo.</string>
+ <string name="calc_optimal_length">Optimální délka</string>
+ <string name="action_redo">Znovu</string>
+ <string name="title_recents">Poslední soubory</string>
+ <string name="calc_insert_before">Vložit</string>
+ <string name="message_saving">Ukládání dokumentu…</string>
+ <string name="no_save_document">NE</string>
+ <string name="calc_adjust_width">Upravit šířku</string>
+ <string name="action_back">Zpět</string>
+ <string name="pref_experimental_editing">Experimentální režim</string>
+ <string name="calc_delete">Smazat</string>
+ <string name="action_undo">Zpět</string>
+ <string name="action_parts">Části</string>
+ <string name="select_delete_options">Vyberte možnosti smazání:</string>
+ <string name="pref_category_general">Obecné</string>
+ <string name="action_text_copied">Text zkopírován do schránky</string>
+ <string name="action_keyboard">Zobrazit klávesnici</string>
+ <string name="action_presentation">Prezentace</string>
+ <string name="action_search">Hledat</string>
+ <string name="message_saved">Ukládání dokončeno</string>
+ <string name="action_save">Uložit</string>
+ <string name="action_settings">Nastavení</string>
+ <string name="title_browser">Všechny soubory</string>
+ <string name="insert_table">Vložit tabulku</string>
+ <string name="action_add_slide">Přidat snímek</string>
+ <string name="action_cancel">Zrušit</string>
+ <string name="calc_adjust_height">Upravit výšku</string>
+ <string name="pref_experimental_editing_summary">Povolí experimentální režim úprav. Použití na vlastní nebezpečí.</string>
+ <string name="calc_optimal_height">Optimální výška</string>
+ <string name="search_find_next">Najít další</string>
+ <string name="search_find_previous">Najít předchozí</string>
+ <string name="action_save_as">Uložit jako…</string>
+ <string name="file_icon_desc">Ikona souboru</string>
+ <string name="calc_optimal_width">Optimální šířka</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="calc_optimal_length_default_text">Zadejte dodatečnou délku v setinách mm</string>
+ <string name="calc_alert_double_click_optimal_length">Tip: Optimální šířku/výšku nastavíte poklepáním na záhlaví.</string>
+ <string name="action_add_worksheet">Přidat list</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="action_pwd_dialog_cancel">Zrušit</string>
+ <string name="action_pwd_dialog_title">Zadejte heslo</string>
+ <string name="take_photo">Vyfotit</string>
+ <string name="select_photo">Vyberte fotku</string>
+ <string name="select_photo_title">Vyberte obrázek</string>
+ <string name="no_camera_found">Nenalezen fotoaparát</string>
+ <string name="compress_photo_smallest_size">Nejmenší velikost</string>
+ <string name="compress_photo_medium_size">Střední velikost</string>
+ <string name="compress_photo_max_quality">Maximální kvalita</string>
+ <string name="compress_photo_no_compress">Nekomprimovat</string>
+ <string name="compress_photo_title">Přejete si fotku zkomprimovat?</string>
+ <string name="action_paste">Vložit</string>
+ <string name="action_cut">Vyjmout</string>
+ <string name="action_rename_worksheet">Přejmenovat list</string>
+ <string name="action_delete_worksheet">Smazat list</string>
+ <string name="action_delete_slide">Smazat snímek</string>
+ <string name="name_already_used">Zadaný název se již používá.</string>
+ <string name="part_deleted">Část byla smazána.</string>
+ <string name="UNO_commands_string_hint">Příkaz UNO</string>
+ <string name="UNO_commands_string_type_hint">Typ</string>
+ <string name="UNO_commands_string_value_hint">Hodnota</string>
+ <string name="UNO_commands_string_parent_value_hint">Hodnota rodičovského</string>
+ <string name="action_exportToPDF">Exportovat do PDF</string>
+ <string name="action_print">Tisk</string>
+ <string name="tabhost_character">Znak</string>
+ <string name="tabhost_paragraph">Odstavec</string>
+ <string name="tabhost_insert">Vložit</string>
+ <string name="tabhost_style">Styl</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Zrušit</string>
+ <string name="display_language">Jazyk zobrazení</string>
+ <string name="display_language_summary">Nastaví výchozí jazyk zobrazení</string>
+ <string name="pdf_export_finished">Export do PDF dokončen</string>
+ <string name="unable_to_export_pdf">Export do PDF se nepodařil</string>
+ <string name="unable_to_save">Soubor se uložit nepodařilo</string>
+ <string name="error">Chyba</string>
+ <string name="enter_part_name">Zadejte název části</string>
+ <string name="bmp_null">Bmp je prázdný!</string>
+ <string name="page">Stránka</string>
+ <string name="sheet">List</string>
+ <string name="slide">Snímek</string>
+ <string name="part">Část</string>
+ <string name="highlight_color">Barva zvýraznění</string>
+ <string name="font_color">Barva písma</string>
+ <string name="automatic">Automatická</string>
+ <string name="part_name_changed">Název části byl změněn.</string>
+ <string name="current_uno_command">Aktuální příkaz UNO</string>
+ <string name="action_rename_slide">Přejmenovat snímek</string>
+ <string name="action_copy">Kopírovat</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-cy/strings.xml b/android/source/res/values-cy/strings.xml
new file mode 100644
index 000000000000..284265619e18
--- /dev/null
+++ b/android/source/res/values-cy/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="calc_optimal_length">Hyd Gorau</string>
+ <string name="pref_experimental_editing_summary">Galluogi’r modd golygu arbrofol. Gall fod peryglon.</string>
+ <string name="app_name_settings">Gosodiadau LibreOffice Viewer</string>
+ <string name="app_description">Mae LibreOffice Viewer yn ddarllenydd dogfennau yn seiliedig ar LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Darparwyd y fersiwn yma gan $VENDOR.</string>
+ <string name="readonly_file">Darllen yn unig yw\'r ffeil.</string>
+ <string name="about_license">Dangos y Drwydded</string>
+ <string name="about_notice">Dangos yr Hysbysiad</string>
+ <string name="about_privacy_policy">Polisi Preifatrwydd</string>
+ <string name="create_file">Creu Ffeil Newydd</string>
+ <string name="new_textdocument">Dogfen Testun Newydd</string>
+ <string name="new_spreadsheet">Taenlen Newydd</string>
+ <string name="new_drawing">Lluniad Newydd</string>
+ <string name="default_document_name">dideitl</string>
+ <string name="select_file_to_open">Dewis ffeil i\'w hagor</string>
+ <string name="search_find_next">Canfod Nesaf</string>
+ <string name="search_find_previous">Canfod Blaenorol</string>
+ <string name="title_recents">Ffeiliau diweddar</string>
+ <string name="title_browser">Pob ffeil</string>
+ <string name="pref_category_general">Cyffredinol</string>
+ <string name="pref_experimental_editing">Y Modd Arbrofol</string>
+ <string name="pref_developer_mode">Y Modd Datblygwr</string>
+ <string name="action_about">Ynghylch</string>
+ <string name="action_parts">Rhannau</string>
+ <string name="action_settings">Gosodiadau</string>
+ <string name="action_keyboard">Dangos bysellfwrdd</string>
+ <string name="action_save">Cadw</string>
+ <string name="action_save_as">Cadw Fel…</string>
+ <string name="action_fromat">Galluogi Fformat</string>
+ <string name="message_saved">Cwblhawyd y cadw</string>
+ <string name="message_saving">Yn cadw\'r ddogfen…</string>
+ <string name="password">Cyfrinair</string>
+ <string name="action_undo">Dadwneud</string>
+ <string name="action_redo">Ail-wneud</string>
+ <string name="save_document">CADW</string>
+ <string name="action_cancel">Diddymu</string>
+ <string name="no_save_document">NA</string>
+ <string name="action_presentation">Sioe sleidiau</string>
+ <string name="action_add_slide">Ychwanegu Sleid</string>
+ <string name="slideshow_action_back">Nôl</string>
+ <string name="calc_insert_before">Mewnosod</string>
+ <string name="calc_delete">Dileu</string>
+ <string name="calc_hide">Cuddio</string>
+ <string name="calc_show">Dangos</string>
+ <string name="calc_adjust_length">Addasu\'r Hyd</string>
+ <string name="calc_adjust_height">Addasu\'r Uchder</string>
+ <string name="calc_adjust_width">Addasu\'r Lled</string>
+ <string name="calc_optimal_height">Uchder Gorau</string>
+ <string name="calc_optimal_length_confirm">Iawn</string>
+ <string name="calc_alert_double_click_optimal_length">Awgrym: Mae rhoi tap dwbl i bennyn yn gosod y lled/hyd gorau.</string>
+ <string name="action_add_worksheet">Ychwanegu Dalen Waith</string>
+ <string name="action_pwd_dialog_OK">Iawn</string>
+ <string name="action_pwd_dialog_cancel">Diddymu</string>
+ <string name="action_pwd_dialog_title">Rhowch gyfrinair</string>
+ <string name="take_photo">Cymryd Ffoto</string>
+ <string name="select_photo_title">Dewis Llun</string>
+ <string name="no_camera_found">Heb Ganfod Camera</string>
+ <string name="compress_photo_smallest_size">Maint Lleiaf</string>
+ <string name="compress_photo_medium_size">Maint Canolig</string>
+ <string name="compress_photo_max_quality">Ansawdd Gorau</string>
+ <string name="compress_photo_title">Hoffech chi gywasgu\'r ffoto\?</string>
+ <string name="action_cut">Torri</string>
+ <string name="action_back">Nôl</string>
+ <string name="insert_table">Mewnosod tabl</string>
+ <string name="select_insert_options">Dewis dewisiadau mewnosod:</string>
+ <string name="select_delete_options">Dewis dewisiadau dileu:</string>
+ <string name="action_rename_worksheet">Ailenwi dalen waith</string>
+ <string name="action_delete_worksheet">Dileu dalen waith</string>
+ <string name="action_delete_slide">Dileu sleid</string>
+ <string name="action_paste">Gludo</string>
+ <string name="part_deleted">Rhan wedi\'i ddileu.</string>
+ <string name="part_name_changed">Enw rhan wedi newid</string>
+ <string name="UNO_commands_string_parent_value_hint">Gwerth Rhiant</string>
+ <string name="action_exportToPDF">Allforio i PDF</string>
+ <string name="action_print">Argraffu</string>
+ <string name="tabhost_character">Nod</string>
+ <string name="tabhost_paragraph">Paragraff</string>
+ <string name="tabhost_insert">Mewnosod</string>
+ <string name="tabhost_style">Arddull</string>
+ <string name="alert_ok">Iawn</string>
+ <string name="current_uno_command">Y gorchymyn UNO cyfredol</string>
+ <string name="display_language">Iaith Dangos</string>
+ <string name="display_language_summary">Gosod yr iaith dangos ragosodedig</string>
+ <string name="pdf_export_finished">Allforio PDF wedi gorffen</string>
+ <string name="unable_to_export_pdf">Methu allforio i PDF</string>
+ <string name="error">Gwall</string>
+ <string name="enter_part_name">Rho enw rhan</string>
+ <string name="bmp_null">Mae bmp yn nwll!</string>
+ <string name="page">Tudalen</string>
+ <string name="sheet">Dalen</string>
+ <string name="slide">Sleid</string>
+ <string name="part">Rhan</string>
+ <string name="highlight_color">Lliw Amlygu</string>
+ <string name="font_color">Lliw Ffont</string>
+ <string name="action_rename_slide">Ailenwi Sleid</string>
+ <string name="automatic">Awtomatig</string>
+ <string name="new_presentation">Cyflwyniadau Newydd</string>
+ <string name="app_version">Fersiwn: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="pref_developer_mode_summary">Galluogi\'r modd datblygwr lle mae modd i chi anfon gorchmynion UNO o fewn yr ap. Gall fod peryglon.</string>
+ <string name="file_icon_desc">eiconffeil</string>
+ <string name="calc_optimal_length_default_text">Rhoi Hyd Ychwanegol mewn 100fed/mm</string>
+ <string name="select_photo">Dewis Ffoto</string>
+ <string name="name_already_used">Mae\'r enw eisoes yn cael ei ddefnyddio.</string>
+ <string name="action_search">Chwilio</string>
+ <string name="save_alert_dialog_title">Cadw\'r ddogfen cyn cau\?</string>
+ <string name="calc_optimal_width">Lled Gorau</string>
+ <string name="action_UNO_commands">Anfon Cmd UNO</string>
+ <string name="message_saving_failed">Methodd cadw dogfen</string>
+ <string name="compress_photo_no_compress">Peidio Cywasgu</string>
+ <string name="UNO_commands_string_hint">Gorchymyn UNO</string>
+ <string name="UNO_commands_string_value_hint">Gwerth</string>
+ <string name="action_copy">Copïo</string>
+ <string name="action_text_copied">Testun wedi\'i gopïo i\'r clipfwrdd</string>
+ <string name="UNO_commands_string_type_hint">Math</string>
+ <string name="alert_cancel">Diddymu</string>
+ <string name="unable_to_save">Methu cadw i ffeil</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-de/strings.xml b/android/source/res/values-de/strings.xml
index a4f88b2742c4..61f03c9bd63c 100644
--- a/android/source/res/values-de/strings.xml
+++ b/android/source/res/values-de/strings.xml
@@ -1,149 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
-
<string name="app_name">LibreOffice Viewer</string>
<string name="app_name_settings">LibreOffice-Viewer-Einstellungen</string>
-
- <string name="app_about_name"><b>LibreOffice Viewer \'Beta\'</b></string>
- <string name="app_version">Version: %1$s\nBuild ID: %2$s</string>
+ <string name="app_version">Version: %1$s&lt;br&gt;Build ID: &lt;a href="https://hub.libreoffice.org/git-core/%2$s"&gt;%2$s&lt;/a&gt;</string>
<string name="app_description">LibreOffice Viewer ist ein Dokumentenbetrachter, der auf LibreOffice basiert.</string>
<string name="app_credits">https://www.libreoffice.org</string>
<string name="app_vendor">Dieses Release wurde bereitgestellt durch $VENDOR.</string>
- <string name="temp_file_saving_disabled">Diese Datei ist schreibgeschützt, Speichern ist deaktiviert.</string>
-
+ <string name="readonly_file">Diese Datei ist schreibgeschützt.</string>
<string name="about_license">Lizenz anzeigen</string>
<string name="about_notice">Hinweise anzeigen</string>
- <string name="about_moreinfo">Weitere Informationen</string>
- <string name="back_again_to_quit">Zum Beenden noch einmal \'zurück\' drücken</string>
-
+ <string name="about_privacy_policy">Datenschutzerklärung</string>
<string name="new_textdocument">Neues Textdokument</string>
<string name="new_presentation">Neue Präsentation</string>
<string name="new_spreadsheet">Neues Tabellendokument</string>
<string name="new_drawing">Neue Zeichnung</string>
<string name="default_document_name">unbenannt</string>
-
- <string name="browser_app_name">LibreOffice Browser</string>
- <string name="menu_search">Suchen</string>
- <string name="list_view">Liste</string>
- <string name="grid_view">Gitter</string>
- <string name="filter">Filtern nach</string>
- <string name="search_not_found">Suchbegriff nicht gefunden</string>
- <string name="sort">Sortieren nach</string>
- <string name="sort_smallest">Kleinste zuerst</string>
- <string name="sort_largest">Größte zuerst</string>
- <string name="sort_az">A-Z</string>
- <string name="sort_za">Z-A</string>
- <string name="sort_oldest">Älteste zuerst</string>
- <string name="sort_newest">Neueste zuerst</string>
- <string name="menu_sort_size">Nach Größe sortieren</string>
- <string name="menu_sort_az">Von A bis Z sortieren</string>
- <string name="menu_sort_modified">Nach Datum sortieren</string>
- <string name="menu_preferences">Einstellungen</string>
+ <string name="select_file_to_open">Datei zum Öffnen auswählen</string>
<string name="file_icon_desc">Datei-Icon</string>
<string name="title_recents">Zuletzt verwendete Dateien</string>
<string name="title_browser">Alle Dateien</string>
- <!-- Pref keys as resources ; Not currently used -->
- <string name="EXPLORER_VIEW_TYPE_KEY">EXPLORER_VIEW_TYPE</string>
- <string name="CURRENT_DIRECTORY_KEY">CURRENT_DIRECTORY</string>
- <string name="pref_category_explorer">Dateimanager-Einstellungen</string>
<string name="pref_category_general">Allgemein</string>
<string name="pref_experimental_editing">Experimenteller Modus</string>
<string name="pref_experimental_editing_summary">Den experimentellen Editier-Modus aktivieren. Verwendung auf eigene Gefahr.</string>
- <string name="pref_show_hidden_files">Versteckte Dateien/Ordner</string>
- <string name="pref_show_hidden_files_summary">Anzeige versteckter Dateien/Ordner aktivieren</string>
<string name="pref_developer_mode">Entwickler-Modus</string>
<string name="pref_developer_mode_summary">Entwickler-Modus, in dem in der App UNO-Kommandos gesendet werden können. Verwendung auf eigene Gefahr.</string>
-
<string name="action_about">Info</string>
<string name="action_parts">Abschnitte</string>
<string name="action_settings">Einstellungen</string>
- <string name="open">Öffnen</string>
- <string name="share">Teilen</string>
- <string name="share_via">Teilen via</string>
-
- <!-- Document browser filters -->
- <string name="filter_everything">Alles</string>
- <string name="filter_documents">Dokumente</string>
- <string name="filter_spreadsheets">Tabellendokumente</string>
- <string name="filter_presentations">Präsentationen</string>
- <string name="filter_drawings">Zeichnungen</string>
-
- <!-- Document provider names -->
- <string name="document_locations">Dokumentenorte</string>
- <string name="close_document_locations">Dokumentenorte schließen</string>
- <string name="local_documents">Dokumentenverzeichnis</string>
- <string name="local_file_system">Lokales Dateisystem</string>
- <string name="external_sd_file_system">Externe SD</string>
- <string name="otg_file_system">OTG-Gerät (experimentell)</string>
- <string name="owncloud">Entfernter Server</string>
- <string name="usb_connected_configure">USB verbunden, richten Sie Ihr Gerät ein.</string>
-
- <string name="owncloud_wrong_connection">Verbindung mit dem ownCloud-Server nicht möglich. Prüfen Sie die Einstellungen.</string>
- <string name="owncloud_unauthorized">Anmeldung am ownCloud-Server nicht möglich. Prüfen Sie die Einstellungen.</string>
- <string name="owncloud_unspecified_error">Nicht näher spezifizierter Fehler beim Verbindungsaufbau zum ownCloud-Server. Prüfen Sie die Einstellungen und/oder versuchen Sie es später.</string>
-
- <string name="ext_document_provider_error">Ungültige Wurzel-Datei. Prüfen Sie die SD-Karten-Einstellungen.</string>
- <string name="legacy_extsd_missing_error">Ungültige Wurzel-Datei. Prüfen Sie die externe SD-Karte und/oder die Einstellungen</string>
- <string name="otg_missing_error">Ungültige Wurzel-Datei. Prüfen Sie Ihr OTG-Gerät und/oder die Einstellungen.</string>
-
<!-- Edit action names -->
- <string name="action_bold">Fett</string>
- <string name="action_underline">Unterstrichen</string>
- <string name="action_italic">Kursiv</string>
- <string name="action_strikeout">Durchgestrichen</string>
<string name="action_keyboard">Tastatur anzeigen</string>
<string name="action_save">Speichern</string>
+ <string name="action_save_as">Speichern unter…</string>
<string name="action_fromat">Format anwenden</string>
<string name="action_search">Suchen</string>
<string name="action_UNO_commands">UNO-Kommando senden</string>
-
<!-- Feedback messages -->
<string name="message_saved">Speichern beendet</string>
<string name="message_saving">Dokument wird gespeichert…</string>
- <string name="message_save_incomplete">Speichern unvollständig. Gab es Änderungen?</string>
- <string name="create_new_file_success">"Neue Datei angelegt - "</string>
- <string name="create_new_file_error">Neue Datei konnte nicht angelegt weden, bitte Prüfen Sie den eingegeben Dateinamen.</string>
-
- <!-- Document provider settings -->
- <string name="storage_provider_settings">Speicheranbieter-Einstellungen</string>
- <string name="owncloud_settings">ownCloud-Einstellungen</string>
- <string name="physical_storage_settings">Einstellungen für physikalischen Speicher</string>
- <string name="external_sd_path">Pfad zur externen SD-Karte</string>
- <string name="otg_device_path">Pfad zum OTG-Gerät</string>
- <string name="otg_warning">Experimentelles Feature: Nur verwenden, wenn OTG-Gerät beschreibbar ist.</string>
- <string name="server_url">Server-URL</string>
- <string name="server_url_and_port">URL und Port des ownCloud-Servers.</string>
- <string name="user_name">Benutzername</string>
+ <string name="message_saving_failed">Speichern des Dokuments ist fehlgeschlagen.</string>
<string name="password">Passwort</string>
<string name="action_undo">Rückgängig</string>
<string name="action_redo">Wiederherstellen</string>
-
- <!-- Directory browser strings -->
- <string name="up_description">Nach oben</string>
- <string name="confirm_label">Bestätigen</string>
- <string name="cancel_label">Abbrechen</string>
- <string name="search_label">Los</string>
- <string name="directory_browser_label">Verzeichnis auswählen</string>
- <string name="bad_directory">Ungültiger Verzeichnispfad</string>
- <string name="current_dir">Aktuelles Verzeichnis: %1$s</string>
-
<!-- Save Alert dialog strings -->
<string name="save_alert_dialog_title">Dokument vor dem Schließen speichern?</string>
<string name="save_document">SPEICHERN</string>
<string name="action_cancel">Abbrechen</string>
<string name="no_save_document">NEIN</string>
-
- <!-- Create New Document Dialog Strings -->
- <string name="create_new_document_title">Dateiname eingeben</string>
- <string name="action_create">ANLEGEN</string>
-
<!-- Presentation Mode Strings -->
<string name="action_presentation">Präsentation</string>
<string name="action_add_slide">Folie hinzufügen</string>
- <string name="alert_copy_svg_slide_show_to_clipboard">Ihr Android-Gerät unterstützt keine In-App-SVG-Präsentation. Wir haben den Link zur Präsentation in die Zwischenablage kopiert. Drücken Sie den Home-Button, öffnen Sie einen modernen Web-Browser, fügen Sie in die Adressleiste ein und los.</string>
- <string name="alert_copy_svg_slide_show_to_clipboard_dismiss">OK</string>
<string name="slideshow_action_back">Zurück</string>
-
<!-- Calc Header Menu Strings -->
<string name="calc_insert_before">Einfügen</string>
<string name="calc_delete">Löschen</string>
@@ -159,12 +65,10 @@
<string name="calc_optimal_length_default_text">Geben Sie die zusätzliche Höhe in 100tel/mm ein</string>
<string name="calc_alert_double_click_optimal_length">Hinweis: Doppeltes Antippen auf eine Überschrift setzt die optimale Breite/Höhe.</string>
<string name="action_add_worksheet">Arbeitsblatt hinzufügen</string>
-
<!-- Password dialog strings -->
<string name="action_pwd_dialog_OK">OK</string>
<string name="action_pwd_dialog_cancel">Abbrechen</string>
<string name="action_pwd_dialog_title">Bitte Passwort eingeben</string>
-
<!-- Insert Image Strings -->
<string name="take_photo">Foto Machen</string>
<string name="select_photo">Foto Auswählen</string>
@@ -175,7 +79,6 @@
<string name="compress_photo_max_quality">Maximale Qualität</string>
<string name="compress_photo_no_compress">Nicht komprimieren</string>
<string name="compress_photo_title">Wollen Sie das Foto komprimieren?</string>
-
<!-- Clipboard Actions -->
<string name="action_copy">Kopieren</string>
<string name="action_paste">Einfügen</string>
@@ -203,7 +106,6 @@
<item>Spalten Löschen</item>
<item>Tabelle Löschen</item>
</string-array>
-
<!-- UNO cmd controller Strings -->
<string name="UNO_commands_string_hint">UNO-Kommando</string>
<string name="UNO_commands_string_type_hint">Typ</string>
@@ -217,23 +119,15 @@
<string name="tabhost_style">Format</string>
<string name="alert_ok">OK</string>
<string name="alert_cancel">Abbrechen</string>
- <string name="unable_to_go_further">Kann nicht weiter gehen.</string>
<string name="current_uno_command">Aktuelles UNO-Kommando</string>
- <string name="pref_sort_summary">Sortiermodus für Dateien auswählen: A-Z, nach Größe oder nach Datum.</string>
- <string name="pref_viewmode_summary">Dateien als Gitter oder als Liste anzeigen.</string>
- <string name="pref_file_explorer_title">Dateimanager-Layout</string>
- <string name="pref_sort_title">Datei-Reihenfolge</string>
- <string name="pref_filter_title">Standard-Dateifilter</string>
- <string name="pref_filter_summary">Wählen Sie, welcher Dateifilter standardmäßig verwendet werden soll.</string>
<string name="display_language">Anzeigesprache</string>
<string name="display_language_summary">Wählen Sie die Standard-Anzeigesprache</string>
+ <string name="pdf_export_finished">PDF-Export abgeschlossen</string>
<string name="unable_to_export_pdf">PDF-Export nicht möglich</string>
- <string name="pdf_exported_at">PDF exportiert nach</string>
- <string name="printing_not_supported">Ihr Gerät unterstützt Drucken nicht</string>
+ <string name="unable_to_save">Speichern nicht möglich</string>
<string name="error">Fehler</string>
<string name="enter_part_name">Name für Abschnitt eingeben</string>
<string name="bmp_null">Bmp ist null!</string>
- <string name="directory_not_saved">Verzeichnis nicht gespeichert.</string>
<string name="page">Seite</string>
<string name="sheet">Arbeitsblatt</string>
<string name="slide">Folie</string>
@@ -241,4 +135,8 @@
<string name="highlight_color">Hervorhebungs-Farbe</string>
<string name="font_color">Schriftfarbe</string>
<string name="action_rename_slide">Folie umbenennen</string>
-</resources>
+ <string name="automatic">Automatisch</string>
+ <string name="create_file">Neue Datei erstellen</string>
+ <string name="search_find_next">Nächste suchen</string>
+ <string name="search_find_previous">Vorherige suchen</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-dsb/strings.xml b/android/source/res/values-dsb/strings.xml
new file mode 100644
index 000000000000..b1885d60a18e
--- /dev/null
+++ b/android/source/res/values-dsb/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="calc_hide">Schowaś</string>
+ <string name="compress_photo_title">Cośo foto kompriměrowaś\?</string>
+ <string name="app_name_settings">Nastajenja LibreOffice Viewer</string>
+ <string name="app_description">LibreOffice Viewer jo dokumentowy wobglědowak, kótaryž na LibreOffice bazěrujo.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Toś to wózjawjenje jo se stajiło wót $VENDOR k dispoziciji.</string>
+ <string name="readonly_file">Toś ta dataja jo pśeśiwo pisanjeju šćitana.</string>
+ <string name="about_notice">Powěźeńku pokazaś</string>
+ <string name="create_file">Nowu dataju napóraś</string>
+ <string name="new_textdocument">Nowy tekstowy dokument</string>
+ <string name="new_presentation">Nowa prezentacija</string>
+ <string name="new_spreadsheet">Nowy tabelowy dokument</string>
+ <string name="new_drawing">Nowa kreslanka</string>
+ <string name="default_document_name">bźez titela</string>
+ <string name="select_file_to_open">Wubjeŕśo dataju, kótaraž se ma wócyniś</string>
+ <string name="about_license">Licencu pokazaś</string>
+ <string name="about_privacy_policy">Pšawidła priwatnosći</string>
+ <string name="calc_adjust_length">Dłujkosć pśiměriś</string>
+ <string name="search_find_previous">Pjerwjejšny pytaś</string>
+ <string name="file_icon_desc">datajowy symbol</string>
+ <string name="title_recents">Nejnowše dataje</string>
+ <string name="pref_category_general">Powšykne</string>
+ <string name="pref_experimental_editing">Eksperimentelny modus</string>
+ <string name="pref_experimental_editing_summary">Eksperimentelny wobźěłański modus zmóžniś. Wužywanje na swójske riziko.</string>
+ <string name="pref_developer_mode">Wuwijaŕski modus</string>
+ <string name="action_about">Wó</string>
+ <string name="action_parts">Źěle</string>
+ <string name="action_settings">Nastajenja</string>
+ <string name="action_keyboard">Tastaturu pokazaś</string>
+ <string name="action_save">Składowaś</string>
+ <string name="action_save_as">Składowaś ako…</string>
+ <string name="action_fromat">Format zmóžniś</string>
+ <string name="action_search">Pytaś</string>
+ <string name="action_UNO_commands">Pśikaz UNO pósłaś</string>
+ <string name="message_saved">Składowanje dokóńcone</string>
+ <string name="message_saving">Dokument se składujo…</string>
+ <string name="message_saving_failed">Składowanje dokumenta njejo se raźiło.</string>
+ <string name="password">Gronidło</string>
+ <string name="action_undo">Anulěrowaś</string>
+ <string name="action_redo">Wóspjetowaś</string>
+ <string name="save_document">SKŁADOWAŚ</string>
+ <string name="action_cancel">Pśetergnuś</string>
+ <string name="no_save_document">NĚ</string>
+ <string name="action_presentation">Prezentacija</string>
+ <string name="action_add_slide">Foliju pśidaś</string>
+ <string name="slideshow_action_back">Slědk</string>
+ <string name="calc_insert_before">Zasajźiś</string>
+ <string name="calc_delete">Wulašowaś</string>
+ <string name="calc_show">Pokazaś</string>
+ <string name="calc_optimal_length">Optimalna dłujkosć</string>
+ <string name="calc_adjust_height">Wusokosć pśiměriś</string>
+ <string name="calc_adjust_width">Šyrokosć pśiměriś</string>
+ <string name="calc_optimal_height">Optimalna wusokosć</string>
+ <string name="calc_optimal_width">Optimalna šyrokosć</string>
+ <string name="calc_optimal_length_confirm">W pórěźe</string>
+ <string name="calc_optimal_length_default_text">Zapódajśo pśidatnu dłujkosć w 100tych mm</string>
+ <string name="action_add_worksheet">Źěłowe łopjeno pśidaś</string>
+ <string name="action_pwd_dialog_OK">W pórěźe</string>
+ <string name="action_pwd_dialog_cancel">Pśetergnuś</string>
+ <string name="action_pwd_dialog_title">Zapódajśo pšosym gronidło</string>
+ <string name="take_photo">Foto gótowaś</string>
+ <string name="select_photo">Foto wubraś</string>
+ <string name="select_photo_title">Wobraz wubraś</string>
+ <string name="no_camera_found">Žedna kamera namakana</string>
+ <string name="compress_photo_smallest_size">Nejmjeńša wjelikosć</string>
+ <string name="compress_photo_medium_size">Srjejźna wjelikosć</string>
+ <string name="compress_photo_max_quality">Maksimalna kwalita</string>
+ <string name="compress_photo_no_compress">Njekompriměrowaś</string>
+ <string name="action_copy">Kopěrowaś</string>
+ <string name="action_paste">Zasajźiś</string>
+ <string name="action_cut">Wurězaś</string>
+ <string name="action_back">Slědk</string>
+ <string name="action_text_copied">Tekst jo se kopěrował do mjazywótkłada</string>
+ <string name="insert_table">Tabelu zasajźiś</string>
+ <string name="select_insert_options">Zasajźeńske nastajenja wubraś:</string>
+ <string name="select_delete_options">Lašowańske nastajenja wubraś:</string>
+ <string name="action_rename_worksheet">Źěłowe łopjeno pśemjeniś</string>
+ <string name="action_delete_worksheet">Źěłowe łopjeno wulašowaś</string>
+ <string name="action_delete_slide">Foliju wulašowaś</string>
+ <string name="name_already_used">Pódane mě se južo wužywa.</string>
+ <string name="part_name_changed">Mě źěla jo se změniło.</string>
+ <string name="part_deleted">Źěl jo se wulašował.</string>
+ <string name="UNO_commands_string_hint">Pśikaz UNO</string>
+ <string name="UNO_commands_string_type_hint">Typ</string>
+ <string name="UNO_commands_string_value_hint">Gódnota</string>
+ <string name="UNO_commands_string_parent_value_hint">Nadrědowana gódnota</string>
+ <string name="action_exportToPDF">Ako PDF eksportěrowaś</string>
+ <string name="action_print">Śišćaś</string>
+ <string name="tabhost_character">Znamuško</string>
+ <string name="tabhost_paragraph">Wótstawk</string>
+ <string name="tabhost_insert">Zasajźiś</string>
+ <string name="tabhost_style">Pśedłoga</string>
+ <string name="alert_ok">W pórěźe</string>
+ <string name="alert_cancel">Pśetergnuś</string>
+ <string name="current_uno_command">Aktualny pśikaz UNO</string>
+ <string name="display_language">Pokazowańska rěc</string>
+ <string name="display_language_summary">Nastajśo standardnu pokazowańsku rěc</string>
+ <string name="pdf_export_finished">Eksport ako PDF dokóńcony</string>
+ <string name="unable_to_export_pdf">Eksport ako PDF njejo móžny</string>
+ <string name="unable_to_save">Dataja njedajo se składowaś</string>
+ <string name="error">Zmólka</string>
+ <string name="enter_part_name">Mě źěla zapódaś</string>
+ <string name="bmp_null">Bmp jo nul!</string>
+ <string name="page">Bok</string>
+ <string name="sheet">Tabela</string>
+ <string name="slide">Folija</string>
+ <string name="part">Źěl</string>
+ <string name="highlight_color">Barwa za wuzwignjenja</string>
+ <string name="font_color">Pismowa barwa</string>
+ <string name="action_rename_slide">Foliju pśemjeniś</string>
+ <string name="automatic">Awtomatiski</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="app_version">Wersija: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="search_find_next">Dalej pytaś</string>
+ <string name="title_browser">Wšykne dataje</string>
+ <string name="pref_developer_mode_summary">Wuwijaŕski modus zmóžniś, źož móžośo pśikaze UNO w nałoženju pósłaś. Wužywanje na swójske riziko.</string>
+ <string name="save_alert_dialog_title">Dokument do zacynjanja składowaś\?</string>
+ <string name="calc_alert_double_click_optimal_length">Pokaz: Pótusniśo dwójcy nadpismo, aby optimalnu šyrokosć/wusokosć nastajił.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-el/strings.xml b/android/source/res/values-el/strings.xml
new file mode 100644
index 000000000000..4de4e2c60047
--- /dev/null
+++ b/android/source/res/values-el/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="create_file">Δημιουργία νέου αρχείου</string>
+ <string name="message_saving_failed">Αποτυχία αποθήκευσης του εγγράφου.</string>
+ <string name="action_presentation">Προβολή παρουσίασης</string>
+ <string name="app_name">Προβολή LibreOffice</string>
+ <string name="app_name_settings">Ρυθμίσεις της προβολής του LibreOffice</string>
+ <string name="app_description">Η προβολή του LibreOffice είναι ένα πρόγραμμα προβολής εγγράφων που βασίζεται στο LibreOffice.</string>
+ <string name="select_file_to_open">Επιλέξτε αρχείο για άνοιγμα</string>
+ <string name="pref_experimental_editing">Πειραματική λειτουργία</string>
+ <string name="action_keyboard">Εμφάνιση πληκτρολογίου</string>
+ <string name="app_version">Έκδοση: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Αυτή η έκδοση παρέχεται από την $VENDOR.</string>
+ <string name="readonly_file">Αυτό το αρχείο είναι μόνο για ανάγνωση.</string>
+ <string name="about_license">Εμφάνιση άδειας</string>
+ <string name="about_notice">Εμφάνιση σημείωσης</string>
+ <string name="about_privacy_policy">Πολιτική απορρήτου</string>
+ <string name="new_textdocument">Νέο έγγραφο κειμένου</string>
+ <string name="new_presentation">Νέα παρουσίαση</string>
+ <string name="new_spreadsheet">Νέο υπολογιστικό φύλλο</string>
+ <string name="new_drawing">Νέο σχέδιο</string>
+ <string name="default_document_name">χωρίς τίτλο</string>
+ <string name="search_find_next">Εύρεση επόμενου</string>
+ <string name="search_find_previous">Εύρεση προηγούμενου</string>
+ <string name="file_icon_desc">Εικονίδιο αρχείου</string>
+ <string name="title_recents">Πρόσφατα αρχεία</string>
+ <string name="title_browser">Όλα τα αρχεία</string>
+ <string name="pref_category_general">Γενικά</string>
+ <string name="pref_developer_mode">Λειτουργία ανάπτυξης</string>
+ <string name="pref_developer_mode_summary">Ενεργοποίηση της λειτουργίας προγραμματιστή όπου μπορείτε να στείλετε εντολές UNO εντός της εφαρμογής. Χρησιμοποιήστε το με δική σας ευθύνη.</string>
+ <string name="action_about">Περί</string>
+ <string name="action_parts">Τμήματα</string>
+ <string name="action_settings">Ρυθμίσεις</string>
+ <string name="action_save">Αποθήκευση</string>
+ <string name="action_save_as">Αποθήκευση ως…</string>
+ <string name="action_fromat">Ενεργοποίηση μορφής</string>
+ <string name="message_saved">Ολοκλήρωση αποθήκευσης</string>
+ <string name="message_saving">Αποθήκευση του εγγράφου…</string>
+ <string name="password">Κωδικός πρόσβασης</string>
+ <string name="action_undo">Αναίρεση</string>
+ <string name="action_redo">Ακύρωση αναίρεσης</string>
+ <string name="save_alert_dialog_title">Να αποθηκευτεί το έγγραφο πριν το κλείσιμο;</string>
+ <string name="save_document">ΑΠΟΘΗΚΕΥΣΗ</string>
+ <string name="action_cancel">Ακύρωση</string>
+ <string name="no_save_document">ΟΧΙ</string>
+ <string name="action_add_slide">Προσθήκη διαφάνειας</string>
+ <string name="slideshow_action_back">Πίσω</string>
+ <string name="calc_insert_before">Εισαγωγή</string>
+ <string name="calc_delete">Διαγραφή</string>
+ <string name="calc_hide">Απόκρυψη</string>
+ <string name="calc_show">Εμφάνιση</string>
+ <string name="calc_optimal_length">Βέλτιστο μήκος</string>
+ <string name="calc_adjust_length">Προσαρμογή μήκους</string>
+ <string name="calc_adjust_height">Προσαρμογή ύψους</string>
+ <string name="calc_optimal_height">Βέλτιστο ύψος</string>
+ <string name="calc_optimal_width">Βέλτιστο πλάτος</string>
+ <string name="calc_optimal_length_confirm">Εντάξει</string>
+ <string name="calc_alert_double_click_optimal_length">Συμβουλή: Το διπλό πάτημα σε μια κεφαλίδα ορίζει το βέλτιστο πλάτος/ύψος.</string>
+ <string name="action_add_worksheet">Προσθήκη φύλλου εργασίας</string>
+ <string name="action_pwd_dialog_OK">Εντάξει</string>
+ <string name="action_pwd_dialog_cancel">Ακύρωση</string>
+ <string name="action_pwd_dialog_title">Παρακαλούμε εισάγετε τον κωδικό πρόσβασης</string>
+ <string name="take_photo">Λήψη φωτογραφίας</string>
+ <string name="pref_experimental_editing_summary">Ενεργοποίηση της πειραματικής λειτουργίας επεξεργασίας. Χρησιμοποιήστε την με δική σας ευθύνη.</string>
+ <string name="action_search">Αναζήτηση</string>
+ <string name="action_UNO_commands">Αποστολή εντολής UNO</string>
+ <string name="calc_adjust_width">Προσαρμογή πλάτους</string>
+ <string name="calc_optimal_length_default_text">Εισαγάγετε επιπλέον μήκος σε 100στά/mm</string>
+ <string name="select_photo">Επιλογή φωτογραφίας</string>
+ <string name="select_photo_title">Επιλογή εικόνας</string>
+ <string name="no_camera_found">Δεν βρέθηκε κάμερα</string>
+ <string name="compress_photo_smallest_size">Ελάχιστο μέγεθος</string>
+ <string name="compress_photo_medium_size">Μεσαίο μέγεθος</string>
+ <string name="compress_photo_max_quality">Μέγιστη ποιότητα</string>
+ <string name="compress_photo_no_compress">Να μην συμπιεστεί</string>
+ <string name="compress_photo_title">Θέλετε να συμπιέσετε τη φωτογραφία;</string>
+ <string name="action_copy">Αντιγραφή</string>
+ <string name="action_paste">Επικόλληση</string>
+ <string name="action_cut">Αποκοπή</string>
+ <string name="action_back">Πίσω</string>
+ <string name="action_text_copied">Το κείμενο αντιγράφηκε στο πρόχειρο</string>
+ <string name="insert_table">Εισαγωγή πίνακα</string>
+ <string name="select_delete_options">Διαλέξτε επιλογές διαγραφής:</string>
+ <string name="action_rename_worksheet">Μετονομασία φύλλου εργασίας</string>
+ <string name="action_delete_worksheet">Διαγραφή φύλλου εργασίας</string>
+ <string name="action_delete_slide">Διαγραφή διαφάνειας</string>
+ <string name="part_deleted">Το τμήμα έχει διαγραφεί.</string>
+ <string name="UNO_commands_string_hint">Εντολή UNO</string>
+ <string name="UNO_commands_string_type_hint">Τύπος</string>
+ <string name="UNO_commands_string_value_hint">Τιμή</string>
+ <string name="UNO_commands_string_parent_value_hint">Γονική τιμή</string>
+ <string name="action_exportToPDF">Εξαγωγή σε PDF</string>
+ <string name="action_print">Εκτύπωση</string>
+ <string name="tabhost_character">Χαρακτήρας</string>
+ <string name="tabhost_insert">Εισαγωγή</string>
+ <string name="part_name_changed">Το όνομα του τμήματος άλλαξε.</string>
+ <string name="tabhost_style">Τεχνοτροπία</string>
+ <string name="alert_ok">Εντάξει</string>
+ <string name="alert_cancel">Ακύρωση</string>
+ <string name="current_uno_command">Τρέχουσα εντολή UNO</string>
+ <string name="display_language">Εμφάνιση γλώσσας</string>
+ <string name="display_language_summary">Ορίστε την προεπιλεγμένη γλώσσα εμφάνισης</string>
+ <string name="pdf_export_finished">Η εξαγωγή PDF ολοκληρώθηκε</string>
+ <string name="unable_to_export_pdf">Αδυναμία εξαγωγής σε pdf</string>
+ <string name="unable_to_save">Αδυναμία αποθήκευσης του αρχείου</string>
+ <string name="error">Σφάλμα</string>
+ <string name="bmp_null">Το Bmp είναι null!</string>
+ <string name="page">Σελίδα</string>
+ <string name="sheet">Φύλλο</string>
+ <string name="slide">Διαφάνεια</string>
+ <string name="part">Τμήμα</string>
+ <string name="highlight_color">Χρώμα επισήμανσης</string>
+ <string name="font_color">Χρώμα γραμματοσειράς</string>
+ <string name="action_rename_slide">Μετονομασία διαφάνειας</string>
+ <string name="automatic">Αυτόματα</string>
+ <string name="enter_part_name">Εισαγάγετε ένα όνομα του τμήματος</string>
+ <string name="select_insert_options">Διαλέξτε επιλογές εισαγωγής:</string>
+ <string name="name_already_used">Το συγκεκριμένο όνομα χρησιμοποιείται ήδη.</string>
+ <string name="tabhost_paragraph">Παράγραφος</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-es/strings.xml b/android/source/res/values-es/strings.xml
new file mode 100644
index 000000000000..0dbbf6fbf522
--- /dev/null
+++ b/android/source/res/values-es/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="no_camera_found">No se encontró ninguna cámara</string>
+ <string name="app_name">Visor de LibreOffice</string>
+ <string name="action_presentation">Pase de diapositivas</string>
+ <string name="calc_delete">Eliminar</string>
+ <string name="app_vendor">$VENDOR le proporciona esta versión.</string>
+ <string name="pref_experimental_editing">Modo experimental</string>
+ <string name="app_name_settings">Configuración del visor de LibreOffice</string>
+ <string name="app_version">Versión: %1$s&lt;br&gt;Id. de montaje: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">Esta aplicación es un visor de documentos basado en LibreOffice.</string>
+ <string name="app_credits">https://es.libreoffice.org</string>
+ <string name="readonly_file">Este archivo es de solo lectura.</string>
+ <string name="about_license">Mostrar licencia</string>
+ <string name="about_notice">Mostrar aviso</string>
+ <string name="about_privacy_policy">Normativa de privacidad</string>
+ <string name="create_file">Crear un archivo</string>
+ <string name="new_textdocument">Documento de texto nuevo</string>
+ <string name="new_presentation">Presentación nueva</string>
+ <string name="new_spreadsheet">Libro nuevo</string>
+ <string name="new_drawing">Dibujo nuevo</string>
+ <string name="default_document_name">sin título</string>
+ <string name="select_file_to_open">Seleccione un archivo para abrirlo</string>
+ <string name="search_find_next">Buscar siguiente</string>
+ <string name="search_find_previous">Buscar anterior</string>
+ <string name="file_icon_desc">icono de archivo</string>
+ <string name="title_recents">Archivos recientes</string>
+ <string name="title_browser">Todos los archivos</string>
+ <string name="pref_category_general">Generales</string>
+ <string name="pref_experimental_editing_summary">Activar el modo de edición experimental. Úselo bajo su responsabilidad.</string>
+ <string name="pref_developer_mode">Modo de desarrollo</string>
+ <string name="action_about">Acerca de</string>
+ <string name="action_parts">Partes</string>
+ <string name="action_settings">Configuración</string>
+ <string name="action_keyboard">Mostrar teclado</string>
+ <string name="action_save">Guardar</string>
+ <string name="action_save_as">Guardar como…</string>
+ <string name="action_fromat">Activar formato</string>
+ <string name="action_search">Buscar</string>
+ <string name="message_saved">Se completó el guardado</string>
+ <string name="message_saving">Guardando el documento…</string>
+ <string name="message_saving_failed">No se pudo guardar el documento.</string>
+ <string name="password">Contraseña</string>
+ <string name="action_undo">Deshacer</string>
+ <string name="action_redo">Rehacer</string>
+ <string name="save_alert_dialog_title">¿Quiere guardar el documento antes de cerrarlo\?</string>
+ <string name="save_document">GUARDAR</string>
+ <string name="action_cancel">Cancelar</string>
+ <string name="no_save_document">NO</string>
+ <string name="action_add_slide">Añadir diapositiva</string>
+ <string name="slideshow_action_back">Atrás</string>
+ <string name="calc_insert_before">Insertar</string>
+ <string name="calc_hide">Ocultar</string>
+ <string name="calc_show">Mostrar</string>
+ <string name="calc_optimal_length">Longitud óptima</string>
+ <string name="calc_adjust_length">Ajustar longitud</string>
+ <string name="calc_adjust_height">Ajustar altura</string>
+ <string name="calc_adjust_width">Ajustar anchura</string>
+ <string name="calc_optimal_width">Anchura óptima</string>
+ <string name="calc_optimal_length_confirm">Aceptar</string>
+ <string name="action_add_worksheet">Añadir hoja de cálculo</string>
+ <string name="action_pwd_dialog_OK">Aceptar</string>
+ <string name="action_pwd_dialog_cancel">Cancelar</string>
+ <string name="action_pwd_dialog_title">Introduzca la contraseña</string>
+ <string name="take_photo">Hacer foto</string>
+ <string name="select_photo">Seleccionar foto</string>
+ <string name="select_photo_title">Seleccionar imagen</string>
+ <string name="compress_photo_smallest_size">Tamaño menor</string>
+ <string name="compress_photo_medium_size">Tamaño medio</string>
+ <string name="compress_photo_max_quality">Calidad máxima</string>
+ <string name="compress_photo_no_compress">No comprimir</string>
+ <string name="compress_photo_title">¿Quiere comprimir la foto\?</string>
+ <string name="action_copy">Copiar</string>
+ <string name="action_paste">Pegar</string>
+ <string name="action_cut">Cortar</string>
+ <string name="action_back">Atrás</string>
+ <string name="action_text_copied">Se copió el texto en el portapapeles</string>
+ <string name="insert_table">Insertar tabla</string>
+ <string name="select_insert_options">Seleccionar opciones de inserción:</string>
+ <string name="select_delete_options">Seleccionar opciones de eliminación:</string>
+ <string name="action_rename_worksheet">Cambiar nombre de hoja</string>
+ <string name="action_delete_worksheet">Eliminar hoja</string>
+ <string name="action_delete_slide">Eliminar diapositiva</string>
+ <string name="name_already_used">El nombre proporcionado ya se utiliza.</string>
+ <string name="part_name_changed">Se cambió el nombre de la parte.</string>
+ <string name="part_deleted">Se eliminó la parte.</string>
+ <string name="UNO_commands_string_hint">Orden UNO</string>
+ <string name="UNO_commands_string_type_hint">Tipo</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="action_exportToPDF">Exportar a PDF</string>
+ <string name="action_print">Imprimir</string>
+ <string name="tabhost_character">Carácter</string>
+ <string name="tabhost_paragraph">Párrafo</string>
+ <string name="tabhost_insert">Insertar</string>
+ <string name="tabhost_style">Estilo</string>
+ <string name="alert_ok">Aceptar</string>
+ <string name="alert_cancel">Cancelar</string>
+ <string name="current_uno_command">Orden UNO actual</string>
+ <string name="display_language">Mostrar en idioma</string>
+ <string name="display_language_summary">Establecer el idioma en pantalla predeterminado</string>
+ <string name="pdf_export_finished">Terminó la exportación a PDF</string>
+ <string name="unable_to_export_pdf">No se pudo exportar a PDF</string>
+ <string name="unable_to_save">No se pudo guardar el archivo</string>
+ <string name="error">Error</string>
+ <string name="bmp_null">El BMP está vacío.</string>
+ <string name="page">Página</string>
+ <string name="sheet">Hoja</string>
+ <string name="slide">Diapositiva</string>
+ <string name="part">Parte</string>
+ <string name="highlight_color">Color de resalte</string>
+ <string name="font_color">Color de letra</string>
+ <string name="automatic">Automático</string>
+ <string name="pref_developer_mode_summary">Activar el modo de desarrollo para enviar órdenes UNO mediante la aplicación. Úselo bajo su responsabilidad.</string>
+ <string name="calc_optimal_height">Altura óptima</string>
+ <string name="enter_part_name">Introduzca un nombre para la parte</string>
+ <string name="action_UNO_commands">Enviar orden UNO</string>
+ <string name="action_rename_slide">Cambiar nombre de diapositiva</string>
+ <string name="calc_alert_double_click_optimal_length">Consejo: tocar dos veces una cabecera define la anchura/altura óptima.</string>
+ <string name="calc_optimal_length_default_text">Introduzca la longitud adicional en centésimas de milímetro</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor superior</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-eu/strings.xml b/android/source/res/values-eu/strings.xml
new file mode 100644
index 000000000000..660fce1fb581
--- /dev/null
+++ b/android/source/res/values-eu/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="action_settings">Ezarpenak</string>
+ <string name="action_search">Bilatu</string>
+ <string name="action_undo">Desegin</string>
+ <string name="action_UNO_commands">Bidali UNO komandoa</string>
+ <string name="app_description">LibreOffice ikustailea LibreOffice-n oinarritutako dokumentu-ikustailea da.</string>
+ <string name="app_name">LibreOffice ikustailea</string>
+ <string name="app_version">Bertsioa: %1$s&lt;br&gt;Konpilazioaren IDa: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Kaleratze hau $VENDOR hornitzaileak ekarri du.</string>
+ <string name="about_license">Erakutsi lizentzia</string>
+ <string name="about_notice">Erakutsi oharra</string>
+ <string name="new_textdocument">Testu-dokumentu berria</string>
+ <string name="new_presentation">Aurkezpen berria</string>
+ <string name="new_spreadsheet">Kalkulu-orri berria</string>
+ <string name="new_drawing">Marrazki berria</string>
+ <string name="default_document_name">izengabea</string>
+ <string name="select_file_to_open">Hautatu fitxategia irekitzeko</string>
+ <string name="file_icon_desc">fitxategiaren ikonoa</string>
+ <string name="title_browser">Fitxategi guztiak</string>
+ <string name="pref_category_general">Orokorra</string>
+ <string name="pref_experimental_editing">Modu esperimentala</string>
+ <string name="pref_developer_mode">Garapen modua</string>
+ <string name="pref_developer_mode_summary">Gaitu garapen modua UNO komandoak aplikazioan bidaltzeko. Erabili zure arriskupean.</string>
+ <string name="title_recents">Azken fitxategiak</string>
+ <string name="about_privacy_policy">Pribatutasun-politika</string>
+ <string name="create_file">Sortu fitxategi berria</string>
+ <string name="search_find_next">Aurkitu hurrengoa</string>
+ <string name="search_find_previous">Aurkitu aurrekoa</string>
+ <string name="action_parts">Zatiak</string>
+ <string name="action_keyboard">Erakutsi teklatua</string>
+ <string name="action_save">Gorde</string>
+ <string name="action_save_as">Gorde honela…</string>
+ <string name="action_fromat">Gaitu formatua</string>
+ <string name="message_saved">Gorde da</string>
+ <string name="message_saving">Dokumentua gordetzen…</string>
+ <string name="message_saving_failed">Ezin izan da gorde dokumentua.</string>
+ <string name="password">Pasahitza</string>
+ <string name="action_redo">Berregin</string>
+ <string name="save_document">GORDE</string>
+ <string name="action_cancel">Utzi</string>
+ <string name="no_save_document">EZ</string>
+ <string name="action_add_slide">Gehitu diapositiba</string>
+ <string name="action_presentation">Diapositiba-saioa</string>
+ <string name="slideshow_action_back">Itzuli</string>
+ <string name="calc_insert_before">Txertatu</string>
+ <string name="calc_delete">Ezabatu</string>
+ <string name="calc_hide">Ezkutatu</string>
+ <string name="calc_show">Erakutsi</string>
+ <string name="calc_adjust_length">Doitu luzera</string>
+ <string name="calc_adjust_height">Doitu altuera</string>
+ <string name="calc_adjust_width">Doitu zabalera</string>
+ <string name="calc_optimal_height">Altuera egokia</string>
+ <string name="calc_optimal_width">Zabalera egokia</string>
+ <string name="calc_optimal_length_confirm">Ados</string>
+ <string name="calc_alert_double_click_optimal_length">Aholkua: Goiburuan birritan sakatzean zabalera/altuera egokia ezartzen du.</string>
+ <string name="action_add_worksheet">Gehitu laneko orria</string>
+ <string name="action_pwd_dialog_OK">Ados</string>
+ <string name="action_pwd_dialog_cancel">Utzi</string>
+ <string name="action_pwd_dialog_title">Sartu pasahitza</string>
+ <string name="take_photo">Atera argazkia</string>
+ <string name="select_photo">Hautatu argazkia</string>
+ <string name="select_photo_title">Hautatu irudia</string>
+ <string name="no_camera_found">Ez da aurkitu kamerarik</string>
+ <string name="compress_photo_smallest_size">Tamaina txikiena</string>
+ <string name="compress_photo_medium_size">Tamaina ertaina</string>
+ <string name="compress_photo_max_quality">Gehieneko kalitatea</string>
+ <string name="compress_photo_no_compress">Ez konprimatu</string>
+ <string name="compress_photo_title">Argazkia konprimatu nahi duzu\?</string>
+ <string name="action_copy">Kopiatu</string>
+ <string name="action_paste">Itsatsi</string>
+ <string name="action_cut">Moztu</string>
+ <string name="action_back">Itzuli</string>
+ <string name="action_text_copied">Testua arbelera kopiatu da</string>
+ <string name="insert_table">Txertatu taula</string>
+ <string name="select_insert_options">Hautatu txertatzeko aukerak:</string>
+ <string name="select_delete_options">Hautatu ezabatzeko aukerak:</string>
+ <string name="action_rename_worksheet">Aldatu laneko orriaren izena</string>
+ <string name="action_delete_worksheet">Ezabatu laneko orria</string>
+ <string name="action_delete_slide">Ezabatu diapositiba</string>
+ <string name="name_already_used">Emandako izena erabilia dago jada.</string>
+ <string name="part_name_changed">Zatiaren izena aldatu da.</string>
+ <string name="part_deleted">Zatia ezabatu da.</string>
+ <string name="UNO_commands_string_value_hint">Balioa</string>
+ <string name="UNO_commands_string_parent_value_hint">Balio nagusia</string>
+ <string name="tabhost_style">Estiloa</string>
+ <string name="alert_ok">Ados</string>
+ <string name="alert_cancel">Utzi</string>
+ <string name="current_uno_command">Uneko UNO komandoa</string>
+ <string name="display_language">Bistaratzeko hizkuntza</string>
+ <string name="display_language_summary">Ezarri bistaratzeko hizkuntza lehenetsia</string>
+ <string name="pdf_export_finished">PDF-a esportatu da</string>
+ <string name="unable_to_export_pdf">Ezin izan da esportatu PDF-ra</string>
+ <string name="unable_to_save">Ezin izan da gorde fitxategia</string>
+ <string name="error">Errorea</string>
+ <string name="enter_part_name">Sartu zatiaren izena</string>
+ <string name="bmp_null">Bmp nulua da.</string>
+ <string name="page">Orria</string>
+ <string name="sheet">Orria</string>
+ <string name="slide">Diapositiba</string>
+ <string name="part">Zatia</string>
+ <string name="highlight_color">Nabarmendutako kolorea</string>
+ <string name="font_color">Letra-tipoaren kolorea</string>
+ <string name="action_rename_slide">Aldatu diapositibaren izena</string>
+ <string name="automatic">Automatikoa</string>
+ <string name="app_name_settings">LibreOffice ikustailearen ezarpenak</string>
+ <string name="readonly_file">Fitxategi hau irakurtzeko soilik da.</string>
+ <string name="pref_experimental_editing_summary">Gaitu edizio modu esperimentala. Erabili zure arriskupean.</string>
+ <string name="action_about">Honi buruz</string>
+ <string name="save_alert_dialog_title">Dokumentua gorde nahi duzu itxi aurretik\?</string>
+ <string name="calc_optimal_length">Luzera egokia</string>
+ <string name="calc_optimal_length_default_text">Sartu luzera gehigarria 100th/mm neurrian</string>
+ <string name="UNO_commands_string_type_hint">Mota</string>
+ <string name="tabhost_paragraph">Paragrafoa</string>
+ <string name="UNO_commands_string_hint">UNO komandoa</string>
+ <string name="action_exportToPDF">Esportatu PDF-ra</string>
+ <string name="action_print">Inprimatu</string>
+ <string name="tabhost_character">Karakterea</string>
+ <string name="tabhost_insert">Txertatu</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-fa/strings.xml b/android/source/res/values-fa/strings.xml
new file mode 100644
index 000000000000..b307d00eeed2
--- /dev/null
+++ b/android/source/res/values-fa/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">تنظیمات نمایشگر لیبره آفیس</string>
+ <string name="app_name">نمایشگر لیبره آفیس</string>
+ <string name="app_version">نسخه: %1$s&lt;br&gt;شناسه ساخت: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">نمایشگر لیبره آفیس یک نمایشگر سند مبتنی بر لیبره آفیس است.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">این نسخه توسط $VENDOR ارائه شده است.</string>
+ <string name="readonly_file">این پرونده فقط خواندنی است.</string>
+ <string name="select_file_to_open">پرونده را برای باز کردن انتخاب کنید</string>
+ <string name="search_find_next">یافتن بعدی</string>
+ <string name="action_about">درباره</string>
+ <string name="action_parts">اجزاء</string>
+ <string name="action_settings">تنظیمات</string>
+ <string name="pref_developer_mode">حالت برنامه‌نویس</string>
+ <string name="pref_developer_mode_summary">حالت برنامه‌نویس را فعال کنید تا بتوانید دستورات UNO را در برنامه ارسال کنید. با مسئولیت خودتان استفاده کنید.</string>
+ <string name="action_UNO_commands">ارسال دستور UNO</string>
+ <string name="message_saved">ذخیره کردن کامل شد</string>
+ <string name="message_saving">ذخیره کردن سند…</string>
+ <string name="slideshow_action_back">بازگشت</string>
+ <string name="action_delete_slide">حذف اسلاید</string>
+ <string name="error">خطا</string>
+ <string name="action_save_as">ذخیره به عنوان…</string>
+ <string name="new_textdocument">سند متنی جدید</string>
+ <string name="new_presentation">ارائه جدید</string>
+ <string name="new_spreadsheet">صفحه گسترده جدید</string>
+ <string name="new_drawing">طراحی جدید</string>
+ <string name="default_document_name">بدون عنوان</string>
+ <string name="file_icon_desc">شمایل پرونده</string>
+ <string name="title_browser">همه پرونده‌ها</string>
+ <string name="pref_category_general">عمومی</string>
+ <string name="pref_experimental_editing">حالت آزمایشی</string>
+ <string name="action_keyboard">نمایش صفحه کلید</string>
+ <string name="action_save">ذخیره</string>
+ <string name="about_privacy_policy">سیاست حریم خصوصی</string>
+ <string name="create_file">ایجاد پرونده جدید</string>
+ <string name="search_find_previous">یافتن قبلی</string>
+ <string name="action_search">جستجو</string>
+ <string name="message_saving_failed">ذخیره کردن سند ناموفق بود.</string>
+ <string name="password">رمز عبور</string>
+ <string name="action_undo">واگردان</string>
+ <string name="save_alert_dialog_title">آیا سند قبل از بستن ذخیره شود؟</string>
+ <string name="save_document">ذخیره</string>
+ <string name="action_cancel">لغو</string>
+ <string name="no_save_document">خیر</string>
+ <string name="action_add_slide">افزودن اسلاید</string>
+ <string name="calc_insert_before">درج</string>
+ <string name="calc_delete">حذف</string>
+ <string name="calc_hide">پنهان کردن</string>
+ <string name="calc_show">نمایش</string>
+ <string name="calc_optimal_length">طول بهینه</string>
+ <string name="calc_adjust_length">تنظیم طول</string>
+ <string name="calc_adjust_height">تنظیم ارتفاع</string>
+ <string name="calc_adjust_width">تنظیم عرض</string>
+ <string name="calc_optimal_width">عرض بهینه</string>
+ <string name="calc_optimal_length_confirm">باشد</string>
+ <string name="calc_optimal_length_default_text">طول اضافی را در واحد 100 تا در میلی‌متر وارد کنید</string>
+ <string name="action_add_worksheet">افزودن کاربرگ</string>
+ <string name="action_pwd_dialog_OK">باشد</string>
+ <string name="action_pwd_dialog_cancel">لغو</string>
+ <string name="action_pwd_dialog_title">لطفاً رمز عبور را وارد کنید</string>
+ <string name="take_photo">عکس گرفتن</string>
+ <string name="select_photo">انتخاب عکس</string>
+ <string name="select_photo_title">انتخاب تصویر</string>
+ <string name="no_camera_found">هیچ دوربینی یافت نشد</string>
+ <string name="compress_photo_smallest_size">کوچک‌ترین اندازه</string>
+ <string name="compress_photo_medium_size">اندازه متوسط</string>
+ <string name="compress_photo_no_compress">فشرده نکن</string>
+ <string name="action_paste">چسباندن</string>
+ <string name="action_cut">برش</string>
+ <string name="action_back">بازگشت</string>
+ <string name="insert_table">درج جدول</string>
+ <string name="select_delete_options">گزینه‌های حذف را انتخاب کنید:</string>
+ <string name="action_rename_worksheet">تغییر نام کاربرگ</string>
+ <string name="action_delete_worksheet">حذف کاربرگ</string>
+ <string name="name_already_used">نام داده شده پیش از این در حال استفاده است.</string>
+ <string name="part_name_changed">نام جزء تغییر کرده است.</string>
+ <string name="part_deleted">جزء حذف شده است.</string>
+ <string name="UNO_commands_string_hint">دستور UNO</string>
+ <string name="UNO_commands_string_type_hint">نوع</string>
+ <string name="UNO_commands_string_value_hint">مقدار</string>
+ <string name="UNO_commands_string_parent_value_hint">مقدار والد</string>
+ <string name="action_print">چاپ</string>
+ <string name="tabhost_character">نویسه</string>
+ <string name="tabhost_paragraph">بند</string>
+ <string name="tabhost_insert">درج</string>
+ <string name="tabhost_style">سبک</string>
+ <string name="alert_ok">باشد</string>
+ <string name="alert_cancel">لغو</string>
+ <string name="current_uno_command">دستورات UNO فعلی</string>
+ <string name="display_language">زبان نمایش</string>
+ <string name="pdf_export_finished">صدور به PDF پایان یافت</string>
+ <string name="unable_to_export_pdf">صدور به PDF ممکن نبود</string>
+ <string name="unable_to_save">ذخیره پرونده ممکن نبود</string>
+ <string name="enter_part_name">نام یک جزء را وارد کنید</string>
+ <string name="bmp_null">Bmp تهی است!</string>
+ <string name="page">صفحه</string>
+ <string name="sheet">برگه</string>
+ <string name="part">جزء</string>
+ <string name="highlight_color">رنگ برجسته کردن</string>
+ <string name="action_rename_slide">تغییر نام اسلاید</string>
+ <string name="automatic">خودکار</string>
+ <string name="action_fromat">فعال کردن قالب</string>
+ <string name="about_license">نمایش اجازه‌نامه‌ها</string>
+ <string name="about_notice">نمایش اطلاعیه</string>
+ <string name="title_recents">پرونده‌های اخیر</string>
+ <string name="pref_experimental_editing_summary">حالت آزمایشی ویرایش را فعال کنید. با مسئولیت خودتان استفاده کنید.</string>
+ <string name="action_redo">انجام دوباره</string>
+ <string name="action_presentation">نمایش اسلاید</string>
+ <string name="calc_optimal_height">ارتفاع بهینه</string>
+ <string name="compress_photo_max_quality">کیفیت بیشینه</string>
+ <string name="calc_alert_double_click_optimal_length">نکته: دوبار ضربه زدن روی سرایند عرض/ارتفاع بهینه را تنظیم می‌کند.</string>
+ <string name="compress_photo_title">آیا می‌خواهید عکس را فشرده کنید؟</string>
+ <string name="action_copy">کپی</string>
+ <string name="slide">اسلاید</string>
+ <string name="action_text_copied">متن در تخته کپی شد</string>
+ <string name="select_insert_options">گزینه‌های درج را انتخاب کنید:</string>
+ <string name="action_exportToPDF">صدور به PDF</string>
+ <string name="display_language_summary">زبان نمایش پیش‌فرض را تنظیم کنید</string>
+ <string name="font_color">رنگ قلم</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-fi/strings.xml b/android/source/res/values-fi/strings.xml
new file mode 100644
index 000000000000..a6b3daec9354
--- /dev/null
+++ b/android/source/res/values-fi/strings.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources></resources> \ No newline at end of file
diff --git a/android/source/res/values-fr/strings.xml b/android/source/res/values-fr/strings.xml
new file mode 100644
index 000000000000..48f8f56ec0c5
--- /dev/null
+++ b/android/source/res/values-fr/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">Paramètre de l\'afficheur LibreOffice</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Cette version est fournie par $VENDOR.</string>
+ <string name="readonly_file">Ce fichier est en lecture seule.</string>
+ <string name="about_license">Afficher la licence</string>
+ <string name="about_notice">Afficher la notice</string>
+ <string name="app_version">Version : %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">LibreOffice Viewer est une visionneuse de document basée sur LibreOffice.</string>
+ <string name="search_find_next">Rechercher le suivant</string>
+ <string name="search_find_previous">Rechercher le précédent</string>
+ <string name="file_icon_desc">fileicon</string>
+ <string name="title_recents">Fichiers récents</string>
+ <string name="title_browser">Tous les fichiers</string>
+ <string name="pref_category_general">Général</string>
+ <string name="create_file">Créer un nouveau fichier</string>
+ <string name="new_textdocument">Nouveau document texte</string>
+ <string name="new_presentation">Nouvelle présentation</string>
+ <string name="new_spreadsheet">Nouveau classeur</string>
+ <string name="new_drawing">Nouveau dessin</string>
+ <string name="default_document_name">sans titre</string>
+ <string name="select_file_to_open">Sélectionner un fichier à ouvrir</string>
+ <string name="pref_experimental_editing">Mode expérimental</string>
+ <string name="action_add_slide">Ajouter une diapo</string>
+ <string name="slideshow_action_back">Précédent</string>
+ <string name="calc_insert_before">Insérer</string>
+ <string name="calc_delete">Supprimer</string>
+ <string name="calc_hide">Masquer</string>
+ <string name="calc_show">Afficher</string>
+ <string name="calc_optimal_length">Longueur optimale</string>
+ <string name="calc_adjust_height">Adapter la hauteur</string>
+ <string name="calc_adjust_width">Adapter la largeur</string>
+ <string name="calc_optimal_height">Hauteur optimale</string>
+ <string name="calc_optimal_width">Largeur optimale</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="about_privacy_policy">Politique de confidentialité</string>
+ <string name="action_presentation">Diaporama</string>
+ <string name="calc_adjust_length">Adapter la longueur</string>
+ <string name="action_UNO_commands">Envoyer Cmd UNO</string>
+ <string name="message_saved">Enregistrement terminé</string>
+ <string name="message_saving">Enregistrement du document…</string>
+ <string name="action_keyboard">Afficher le clavier</string>
+ <string name="action_save">Enregistrer</string>
+ <string name="action_fromat">Activer le formatage</string>
+ <string name="action_search">Rechercher</string>
+ <string name="action_add_worksheet">Ajouter une feuille de calcul</string>
+ <string name="action_exportToPDF">Exporter au format PDF</string>
+ <string name="action_print">Imprimer</string>
+ <string name="page">Page</string>
+ <string name="action_save_as">Enregistrer sous…</string>
+ <string name="pref_experimental_editing_summary">Activez le mode d\'édition expérimental. À utiliser à vos risques et périls.</string>
+ <string name="pref_developer_mode">Mode développeur</string>
+ <string name="action_settings">Paramètres</string>
+ <string name="message_saving_failed">L\'enregistrement du document a échoué</string>
+ <string name="pref_developer_mode_summary">Activez le mode développeur où vous pouvez envoyer des commandes UNO dans l\'application. À utiliser à vos risques et périls.</string>
+ <string name="action_about">À propos</string>
+ <string name="action_parts">Parties</string>
+ <string name="password">Mot de passe</string>
+ <string name="action_undo">Annuler</string>
+ <string name="action_redo">Rétablir</string>
+ <string name="save_alert_dialog_title">Enregistrer le document avant de le fermer \?</string>
+ <string name="save_document">ENREGISTRER</string>
+ <string name="action_cancel">Annuler</string>
+ <string name="no_save_document">NON</string>
+ <string name="calc_optimal_length_default_text">Saisissez la longueur supplémentaire en 100ème/mm</string>
+ <string name="calc_alert_double_click_optimal_length">Astuce : appuyez deux fois sur un en-tête pour définir la largeur/hauteur optimale.</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="action_pwd_dialog_cancel">Annuler</string>
+ <string name="action_pwd_dialog_title">Veuillez saisir le mot de passe</string>
+ <string name="take_photo">Prendre une photo</string>
+ <string name="select_photo">Sélectionner une photo</string>
+ <string name="select_photo_title">Sélectionner une image</string>
+ <string name="no_camera_found">Aucune caméra trouvée</string>
+ <string name="compress_photo_smallest_size">Plus petite taille</string>
+ <string name="compress_photo_medium_size">Taille moyenne</string>
+ <string name="compress_photo_max_quality">Qualité maximale</string>
+ <string name="compress_photo_no_compress">Ne pas compresser</string>
+ <string name="compress_photo_title">Voulez-vous compresser la photo \?</string>
+ <string name="action_copy">Copier</string>
+ <string name="action_paste">Coller</string>
+ <string name="action_cut">Couper</string>
+ <string name="action_back">Précédent</string>
+ <string name="action_text_copied">Texte copié dans le presse-papiers</string>
+ <string name="insert_table">Insérer un tableau</string>
+ <string name="select_insert_options">Sélectionnez les options d\'insertion :</string>
+ <string name="select_delete_options">Sélectionnez les options de suppression :</string>
+ <string name="action_rename_worksheet">Renommer la feuille de calcul</string>
+ <string name="action_delete_worksheet">Supprimer la feuille de calcul</string>
+ <string name="action_delete_slide">Supprimer la diapo</string>
+ <string name="name_already_used">Le nom donné est déjà utilisé.</string>
+ <string name="part_name_changed">Le nom de la partie a été modifié.</string>
+ <string name="part_deleted">La partie a été supprimée.</string>
+ <string name="UNO_commands_string_hint">Commande UNO</string>
+ <string name="UNO_commands_string_type_hint">Type</string>
+ <string name="UNO_commands_string_value_hint">Valeur</string>
+ <string name="UNO_commands_string_parent_value_hint">Valeur parent</string>
+ <string name="tabhost_character">Caractère</string>
+ <string name="tabhost_paragraph">Paragraphe</string>
+ <string name="tabhost_insert">Insérer</string>
+ <string name="tabhost_style">Style</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Annuler</string>
+ <string name="current_uno_command">Commande UNO actuelle</string>
+ <string name="display_language">Afficher la langue</string>
+ <string name="display_language_summary">Définir la langue d\'affichage par défaut</string>
+ <string name="pdf_export_finished">Export au format PDF terminé</string>
+ <string name="unable_to_export_pdf">Impossible d\'exporter au format PDF</string>
+ <string name="unable_to_save">Impossible d\'enregistrer le fichier</string>
+ <string name="error">Erreur</string>
+ <string name="enter_part_name">Saisissez le nom d\'une partie</string>
+ <string name="bmp_null">Bmp est invalide !</string>
+ <string name="sheet">Feuille</string>
+ <string name="slide">Diapo</string>
+ <string name="part">Partie</string>
+ <string name="highlight_color">Couleur de surlignage</string>
+ <string name="font_color">Couleur de police</string>
+ <string name="action_rename_slide">Renommer la diapo</string>
+ <string name="automatic">Automatique</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-gl/strings.xml b/android/source/res/values-gl/strings.xml
new file mode 100644
index 000000000000..3ad68bd82357
--- /dev/null
+++ b/android/source/res/values-gl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="calc_optimal_length_default_text">Introduza lonxitude extra en centésimas de milímetro</string>
+ <string name="compress_photo_no_compress">Non comprimir</string>
+ <string name="new_presentation">Nova presentación</string>
+ <string name="app_name">Visor do LibreOffice</string>
+ <string name="calc_adjust_width">Axustar largura</string>
+ <string name="app_name_settings">Configuración do visor do LibreOffice</string>
+ <string name="app_description">O Visor do LibreOffice é un visor de documentos baseado no LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Esta versión foi fornecida por $VENDOR.</string>
+ <string name="readonly_file">Este ficheiro só permite lectura.</string>
+ <string name="about_license">Mostrar licenza</string>
+ <string name="about_notice">Mostrar aviso</string>
+ <string name="about_privacy_policy">Política de privacidade</string>
+ <string name="create_file">Crear novo ficheiro</string>
+ <string name="new_textdocument">Novo documento de texto</string>
+ <string name="new_spreadsheet">Nova folla de cálculo</string>
+ <string name="new_drawing">Novo debuxo</string>
+ <string name="default_document_name">sen título</string>
+ <string name="select_file_to_open">Seleccionar ficheiro para abrir</string>
+ <string name="search_find_previous">Atopar anterior</string>
+ <string name="file_icon_desc">iconadeficheiro</string>
+ <string name="title_recents">Ficheiros recentes</string>
+ <string name="title_browser">Todos os ficheiros</string>
+ <string name="pref_category_general">Xeral</string>
+ <string name="pref_experimental_editing_summary">Activar o modo de edición experimental. Úseo baixo a súa responsabilidade.</string>
+ <string name="pref_developer_mode">Modo de desenvolvemento</string>
+ <string name="action_about">Sobre</string>
+ <string name="action_parts">Partes</string>
+ <string name="action_settings">Configuración</string>
+ <string name="action_save">Gardar</string>
+ <string name="action_save_as">Gardar como…</string>
+ <string name="action_search">Buscar</string>
+ <string name="action_UNO_commands">Enviar orde de UNO</string>
+ <string name="message_saving">Gardar o documento…</string>
+ <string name="message_saving_failed">Fallou o gardado do documento.</string>
+ <string name="action_undo">Desfacer</string>
+ <string name="action_redo">Refacer</string>
+ <string name="save_document">GARDAR</string>
+ <string name="no_save_document">NON</string>
+ <string name="action_presentation">Presentación de diapositivas</string>
+ <string name="action_add_slide">Engadir diapositiva</string>
+ <string name="slideshow_action_back">Atrás</string>
+ <string name="calc_insert_before">Inserir</string>
+ <string name="calc_delete">Eliminar</string>
+ <string name="calc_hide">Agochar</string>
+ <string name="calc_show">Mostrar</string>
+ <string name="calc_optimal_length">Lonxitude ideal</string>
+ <string name="calc_adjust_length">Axustar lonxitude</string>
+ <string name="calc_adjust_height">Axustar altura</string>
+ <string name="calc_optimal_height">Altura ideal</string>
+ <string name="calc_optimal_width">Largura ideal</string>
+ <string name="calc_optimal_length_confirm">Aceptar</string>
+ <string name="action_add_worksheet">Engadir folla de cálculo</string>
+ <string name="action_pwd_dialog_OK">Aceptar</string>
+ <string name="action_pwd_dialog_cancel">Cancelar</string>
+ <string name="take_photo">Tirar foto</string>
+ <string name="select_photo">Seleccionar foto</string>
+ <string name="no_camera_found">Non se atopou ningunha cámara</string>
+ <string name="compress_photo_smallest_size">Tamaño menor</string>
+ <string name="compress_photo_medium_size">Tamaño mediano</string>
+ <string name="compress_photo_max_quality">Calidade máxima</string>
+ <string name="compress_photo_title">Desexa comprimir a foto\?</string>
+ <string name="action_copy">Copiar</string>
+ <string name="action_paste">Pegar</string>
+ <string name="action_cut">Cortar</string>
+ <string name="insert_table">Inserir táboa</string>
+ <string name="select_insert_options">Seleccionar opcións de inserción:</string>
+ <string name="select_delete_options">Seleccionar opcións de eliminación:</string>
+ <string name="action_rename_worksheet">Renomear folla de cálculo</string>
+ <string name="action_delete_slide">Eliminar diapositiva</string>
+ <string name="name_already_used">O nome dado xa está en uso.</string>
+ <string name="part_name_changed">O nome da parte cambiou.</string>
+ <string name="part_deleted">A parte foi eliminada.</string>
+ <string name="UNO_commands_string_hint">Orde de UNO</string>
+ <string name="UNO_commands_string_type_hint">Tipo</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor superior</string>
+ <string name="action_exportToPDF">Exportar a PDF</string>
+ <string name="action_print">Imprimir</string>
+ <string name="search_find_next">Atopar seguinte</string>
+ <string name="tabhost_character">Carácter</string>
+ <string name="tabhost_paragraph">Parágrafo</string>
+ <string name="tabhost_insert">Inserir</string>
+ <string name="tabhost_style">Estilo</string>
+ <string name="alert_ok">Aceptar</string>
+ <string name="alert_cancel">Cancelar</string>
+ <string name="current_uno_command">Orde de UNO actual</string>
+ <string name="display_language">Idioma para mostrar</string>
+ <string name="display_language_summary">Configurar o idioma predeterminado</string>
+ <string name="pdf_export_finished">Rematou a exportación a PDF</string>
+ <string name="unable_to_export_pdf">Non foi posíbel exportar a pdf</string>
+ <string name="unable_to_save">Non foi posíbel gardar o ficheiro</string>
+ <string name="error">Erro</string>
+ <string name="enter_part_name">Introduza un nome da parte</string>
+ <string name="bmp_null">BMP é nulo!</string>
+ <string name="page">Páxina</string>
+ <string name="sheet">Folla</string>
+ <string name="slide">Diapositiva</string>
+ <string name="part">Parte</string>
+ <string name="highlight_color">Cor de realce</string>
+ <string name="font_color">Cor do tipo de letra</string>
+ <string name="action_rename_slide">Renomear diapositiva</string>
+ <string name="automatic">Automático</string>
+ <string name="app_version">Versión: %1$s&lt;br&gt;Identificador da construción: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="action_keyboard">Mostrar teclado</string>
+ <string name="action_fromat">Activar formato</string>
+ <string name="action_text_copied">Texto copiado ao portapapeis</string>
+ <string name="pref_experimental_editing">Modo experimental</string>
+ <string name="pref_developer_mode_summary">Activar modo de desenvolvemento, no que se poden enviar ordes de UNO dentro da app. Úseo baixo a súa responsabilidade.</string>
+ <string name="message_saved">Gardar completo</string>
+ <string name="password">Contrasinal</string>
+ <string name="save_alert_dialog_title">Gardar o documento antes de pechar\?</string>
+ <string name="action_cancel">Cancelar</string>
+ <string name="calc_alert_double_click_optimal_length">Suxestión: Tocar dúas veces nunha cabeceira estabelece a largura/altura ideais.</string>
+ <string name="action_pwd_dialog_title">Introduza contrasinal</string>
+ <string name="select_photo_title">Seleccionar imaxe</string>
+ <string name="action_back">Atrás</string>
+ <string name="action_delete_worksheet">Eliminar folla de cálculo</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-hsb/strings.xml b/android/source/res/values-hsb/strings.xml
new file mode 100644
index 000000000000..e8feed7dd991
--- /dev/null
+++ b/android/source/res/values-hsb/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_version">Wersija: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Tute wozjewjenje je so wot $VENDOR k dispoziciji stajiło.</string>
+ <string name="readonly_file">Tuta dataja je přećiwo pisanju škitana.</string>
+ <string name="about_notice">Zdźělenku pokazać</string>
+ <string name="create_file">Nowu dataju wutworić</string>
+ <string name="new_textdocument">Nowy tekstowy dokument</string>
+ <string name="new_presentation">Nowa prezentacija</string>
+ <string name="new_spreadsheet">Nowy tabelowy dokument</string>
+ <string name="new_drawing">Nowa rysowanka</string>
+ <string name="default_document_name">bjez titula</string>
+ <string name="select_file_to_open">Wubjerće dataju, kotraž so ma wočinić</string>
+ <string name="search_find_next">Dale pytać</string>
+ <string name="file_icon_desc">datajowy symbol</string>
+ <string name="title_recents">Najnowše dataje</string>
+ <string name="title_browser">Wšě dataje</string>
+ <string name="pref_category_general">Powšitkowne</string>
+ <string name="pref_experimental_editing">Eksperimentelny modus</string>
+ <string name="pref_developer_mode">Wuwiwarski modus</string>
+ <string name="pref_developer_mode_summary">Wuwiwarski modus zmóžnić, hdźež móžeće přikazy UNO w nałoženju pósłać. Wužiwanje na swójske riziko.</string>
+ <string name="action_about">Wo</string>
+ <string name="action_parts">Dźěle</string>
+ <string name="action_settings">Nastajenja</string>
+ <string name="action_keyboard">Tastaturu pokazać</string>
+ <string name="action_save">Składować</string>
+ <string name="action_save_as">Składować jako…</string>
+ <string name="action_fromat">Format zmóžnić</string>
+ <string name="action_search">Pytać</string>
+ <string name="message_saved">Składowanje dokónčene</string>
+ <string name="message_saving">Dokument so składuje…</string>
+ <string name="password">Hesło</string>
+ <string name="action_undo">Cofnyć</string>
+ <string name="action_redo">Wospjetować</string>
+ <string name="save_alert_dialog_title">Dokument do začinjenja składować\?</string>
+ <string name="save_document">SKŁADOWAĆ</string>
+ <string name="action_cancel">Přetorhnyć</string>
+ <string name="no_save_document">NĚ</string>
+ <string name="action_presentation">Prezentacija</string>
+ <string name="action_add_slide">Foliju přidać</string>
+ <string name="slideshow_action_back">Wróćo</string>
+ <string name="calc_delete">Zhašeć</string>
+ <string name="calc_show">Pokazać</string>
+ <string name="calc_optimal_length">Optimalna dołhosć</string>
+ <string name="calc_adjust_length">Dołhosć přiměrić</string>
+ <string name="calc_adjust_height">Wysokosć přiměrić</string>
+ <string name="calc_adjust_width">Šěrokosć přiměrić</string>
+ <string name="calc_optimal_height">Optimalna wysokosć</string>
+ <string name="calc_optimal_width">Optimalna šěrokosć</string>
+ <string name="calc_optimal_length_confirm">W porjadku</string>
+ <string name="calc_optimal_length_default_text">Zapodajće přidatnu dołhosć w 100tych mm</string>
+ <string name="calc_alert_double_click_optimal_length">Pokiw: Podótkńće so dwójce nadpisma, zo byšće optimalnu šěrokosć/wysokosć nastajił.</string>
+ <string name="action_add_worksheet">Dźěłowe łopjeno přidać</string>
+ <string name="action_pwd_dialog_OK">W porjadku</string>
+ <string name="action_pwd_dialog_cancel">Přetorhnyć</string>
+ <string name="action_pwd_dialog_title">Zapodajće prošu hesło</string>
+ <string name="select_photo">Foto wubrać</string>
+ <string name="select_photo_title">Wobraz wubrać</string>
+ <string name="no_camera_found">Žana kamera namakana</string>
+ <string name="compress_photo_smallest_size">Najmjeńša wulkosć</string>
+ <string name="compress_photo_max_quality">Maksimalna kwalita</string>
+ <string name="compress_photo_title">Chceće foto komprimować\?</string>
+ <string name="action_copy">Kopěrować</string>
+ <string name="action_paste">Zasadźić</string>
+ <string name="action_cut">Wutřihać</string>
+ <string name="action_back">Wróćo</string>
+ <string name="action_text_copied">Tekst je so do mjezyskłada kopěrował</string>
+ <string name="insert_table">Tabelu zasadźić</string>
+ <string name="select_insert_options">Zasadźenske nastajenja wubrać:</string>
+ <string name="action_rename_worksheet">Dźěłowe łopjeno přemjenować</string>
+ <string name="action_delete_worksheet">Dźěłowe łopjeno zhašeć</string>
+ <string name="action_delete_slide">Foliju zhašeć</string>
+ <string name="name_already_used">Podate mjeno so hižo wužiwa.</string>
+ <string name="part_name_changed">Mjeno dźěla je so změniło.</string>
+ <string name="part_deleted">Dźěl je so zhašał.</string>
+ <string name="UNO_commands_string_type_hint">Typ</string>
+ <string name="UNO_commands_string_value_hint">Hódnota</string>
+ <string name="UNO_commands_string_parent_value_hint">Nadrjadowana hódnota</string>
+ <string name="action_exportToPDF">Jako PDF eksportować</string>
+ <string name="action_print">Ćišćeć</string>
+ <string name="tabhost_character">Znamješko</string>
+ <string name="tabhost_paragraph">Wotstawk</string>
+ <string name="tabhost_insert">Zasadźić</string>
+ <string name="tabhost_style">Předłoha</string>
+ <string name="alert_ok">W porjadku</string>
+ <string name="alert_cancel">Přetorhnyć</string>
+ <string name="current_uno_command">Aktualny přikaz UNO</string>
+ <string name="display_language">Pokazowanska rěč</string>
+ <string name="display_language_summary">Nastajće standardnu pokazowansku rěč</string>
+ <string name="pdf_export_finished">Eksport jako PDF dokónčeny</string>
+ <string name="unable_to_export_pdf">Eksport jako PDF móžny njeje</string>
+ <string name="unable_to_save">Dataja njeda so składować</string>
+ <string name="error">Zmylk</string>
+ <string name="enter_part_name">Mjeno dźěla zapodać</string>
+ <string name="bmp_null">Bmp je nul!</string>
+ <string name="page">Strona</string>
+ <string name="sheet">Tabela</string>
+ <string name="slide">Folija</string>
+ <string name="part">Dźěl</string>
+ <string name="highlight_color">Wuzběhnjenska barba</string>
+ <string name="font_color">Pismowa barba</string>
+ <string name="action_rename_slide">Foliju přemjenować</string>
+ <string name="automatic">Awtomatiski</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="app_name_settings">Nastajenja LibreOffice Viewer</string>
+ <string name="app_description">LibreOffice Viewer je dokumentowy wobhladowak, kotryž na LibreOffice bazuje.</string>
+ <string name="about_license">Licencu pokazać</string>
+ <string name="about_privacy_policy">Prawidła priwatnosće</string>
+ <string name="search_find_previous">Předchadny pytać</string>
+ <string name="pref_experimental_editing_summary">Eksperimentelny wobdźěłanski modus zmóžnić. Wužiwanje na swójske riziko.</string>
+ <string name="action_UNO_commands">Přikaz UNO pósłać</string>
+ <string name="message_saving_failed">Składowanje dokumenta je so nimokuliło.</string>
+ <string name="calc_insert_before">Zasadźić</string>
+ <string name="calc_hide">Schować</string>
+ <string name="take_photo">Foto činić</string>
+ <string name="compress_photo_medium_size">Srjedźna wulkosć</string>
+ <string name="compress_photo_no_compress">Njekomprimować</string>
+ <string name="select_delete_options">Zhašenske nastajenja wubrać:</string>
+ <string name="UNO_commands_string_hint">Přikaz UNO</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-hu/strings.xml b/android/source/res/values-hu/strings.xml
new file mode 100644
index 000000000000..49ef9910e435
--- /dev/null
+++ b/android/source/res/values-hu/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="pref_developer_mode_summary">Fejlesztői mód engedélyezése, ahol UNO parancsokat küldhet az alkalmazásnak. Saját felelősségre használja.</string>
+ <string name="app_description">A LibreOffice Viewer egy LibreOffice-alapú dokumentummegjelenítő.</string>
+ <string name="calc_show">Megjelenítés</string>
+ <string name="pref_developer_mode">Fejlesztői mód</string>
+ <string name="create_file">Új fájl létrehozása</string>
+ <string name="calc_hide">Elrejtés</string>
+ <string name="action_UNO_commands">UNO parancs küldése</string>
+ <string name="default_document_name">névtelen</string>
+ <string name="action_about">Névjegy</string>
+ <string name="action_fromat">Formázás engedélyezése</string>
+ <string name="password">Jelszó</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="slideshow_action_back">Vissza</string>
+ <string name="save_document">MENTÉS</string>
+ <string name="calc_adjust_length">Hossz igazítása</string>
+ <string name="new_spreadsheet">Új táblázat</string>
+ <string name="select_file_to_open">Fájl kiválasztása</string>
+ <string name="action_save_as">Mentés másként…</string>
+ <string name="save_alert_dialog_title">Bezárás előtt menti a dokumentumot\?</string>
+ <string name="message_saving_failed">A dokumentum mentése meghiúsult.</string>
+ <string name="calc_optimal_length">Optimális hossz</string>
+ <string name="new_drawing">Új rajz</string>
+ <string name="action_redo">Újra</string>
+ <string name="file_icon_desc">fájl ikon</string>
+ <string name="title_recents">Legutóbbi fájlok</string>
+ <string name="calc_insert_before">Beszúrás</string>
+ <string name="message_saving">Dokumentum mentése…</string>
+ <string name="calc_optimal_width">Optimális szélesség</string>
+ <string name="no_save_document">NEM</string>
+ <string name="new_textdocument">Új szöveges dokumentum</string>
+ <string name="calc_adjust_width">Szélesség igazítása</string>
+ <string name="new_presentation">Új bemutató</string>
+ <string name="pref_experimental_editing">Kísérleti mód</string>
+ <string name="calc_delete">Törlés</string>
+ <string name="action_undo">Vissza</string>
+ <string name="app_vendor">A kiadást készítette: $VENDOR.</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="action_parts">Részek</string>
+ <string name="pref_category_general">Általános</string>
+ <string name="action_keyboard">Billentyűzet megjelenítése</string>
+ <string name="about_privacy_policy">Adatvédelem</string>
+ <string name="action_presentation">Diavetítés</string>
+ <string name="action_search">Keresés</string>
+ <string name="message_saved">Mentés kész</string>
+ <string name="app_name_settings">LibreOffice Viewer beállításai</string>
+ <string name="action_save">Mentés</string>
+ <string name="action_settings">Beállítások</string>
+ <string name="app_version">Verzió: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_license">Licenc megjelenítése</string>
+ <string name="title_browser">Minden fájl</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="action_add_slide">Dia hozzáadása</string>
+ <string name="action_cancel">Mégse</string>
+ <string name="calc_adjust_height">Magasság igazítása</string>
+ <string name="search_find_next">Következő találat</string>
+ <string name="search_find_previous">Előző találat</string>
+ <string name="pref_experimental_editing_summary">Kísérleti szerkesztőmód bekapcsolása. Saját felelősségre használja.</string>
+ <string name="readonly_file">A fájl csak olvasható.</string>
+ <string name="about_notice">Megjegyzés megjelenítése</string>
+ <string name="calc_optimal_height">Optimális magasság</string>
+ <string name="pdf_export_finished">PDF export kész</string>
+ <string name="action_pwd_dialog_cancel">Mégse</string>
+ <string name="slide">Dia</string>
+ <string name="part_name_changed">Rész neve módosítva.</string>
+ <string name="compress_photo_max_quality">Max minőség</string>
+ <string name="select_insert_options">Válasszon beszúrási lehetőséget:</string>
+ <string name="UNO_commands_string_type_hint">Típus</string>
+ <string name="current_uno_command">Jelenlegi UNO parancs</string>
+ <string name="bmp_null">A BMP null!</string>
+ <string name="action_paste">Beillesztés</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="part">Rész</string>
+ <string name="unable_to_export_pdf">Nem lehet exportálni PDF-be</string>
+ <string name="font_color">Betűszín</string>
+ <string name="action_rename_worksheet">Munkalap átnevezése</string>
+ <string name="enter_part_name">Írjon be egy résznevet</string>
+ <string name="automatic">Automatikus</string>
+ <string name="action_delete_slide">Dia törlése</string>
+ <string name="action_cut">Kivágás</string>
+ <string name="page">Oldal</string>
+ <string name="calc_optimal_length_default_text">Extra hossz megadása 1/100 mm-ben</string>
+ <string name="tabhost_style">Stílus</string>
+ <string name="select_photo_title">Kép kiválasztása</string>
+ <string name="action_delete_worksheet">Munkalap törlése</string>
+ <string name="highlight_color">Kiemelési szín</string>
+ <string name="action_print">Nyomtatás</string>
+ <string name="action_add_worksheet">Munkalap hozzáadása</string>
+ <string name="tabhost_paragraph">Bekezdés</string>
+ <string name="action_back">Vissza</string>
+ <string name="part_deleted">Rész törölve.</string>
+ <string name="action_pwd_dialog_title">Írja be a jelszót</string>
+ <string name="compress_photo_medium_size">Közepes méret</string>
+ <string name="display_language_summary">Alapértelmezett nyelv beállítása</string>
+ <string name="select_delete_options">Válasszon törlési lehetőségeket:</string>
+ <string name="action_text_copied">Szöveg vágólapra másolva</string>
+ <string name="action_exportToPDF">PDF-be exportálás</string>
+ <string name="action_rename_slide">Dia átnevezése</string>
+ <string name="UNO_commands_string_parent_value_hint">Szülő érték</string>
+ <string name="compress_photo_smallest_size">Legkisebb méret</string>
+ <string name="select_photo">Fénykép kiválasztása</string>
+ <string name="compress_photo_no_compress">Ne tömörítse</string>
+ <string name="action_copy">Másolás</string>
+ <string name="tabhost_insert">Beszúrás</string>
+ <string name="no_camera_found">Nem található kamera</string>
+ <string name="error">Hiba</string>
+ <string name="name_already_used">Ez a név már használatban van.</string>
+ <string name="UNO_commands_string_hint">UNO parancs</string>
+ <string name="alert_ok">OK</string>
+ <string name="UNO_commands_string_value_hint">Érték</string>
+ <string name="sheet">Munkalap</string>
+ <string name="compress_photo_title">Szeretné tömöríteni a fényképet\?</string>
+ <string name="take_photo">Fényképezés</string>
+ <string name="unable_to_save">Nem lehet menteni a fájlt</string>
+ <string name="insert_table">Táblázat beszúrása</string>
+ <string name="display_language">Megjelenítési nyelv</string>
+ <string name="alert_cancel">Mégse</string>
+ <string name="tabhost_character">Karakter</string>
+ <string name="calc_alert_double_click_optimal_length">Koppintson duplán a fejlécre optimális szélesség/magasság beállításához.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-hy/strings.xml b/android/source/res/values-hy/strings.xml
new file mode 100644
index 000000000000..6f3353e485e6
--- /dev/null
+++ b/android/source/res/values-hy/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">LibreOffice Դիտակի կարգավորումներ</string>
+ <string name="app_description">LibreOffice Viewer-ը LibreOffice-ի վրա հիմնված փաստաթղթերի դիտարկիչ է:</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Այս թողարկումը տրամադրվել է $VENDOR -ի կողմից:</string>
+ <string name="about_license">Ցույց տուր արտոնագիրը</string>
+ <string name="about_notice">Ցույց տալ ծանուցումը</string>
+ <string name="create_file">Ստեղծեք նոր նիշք</string>
+ <string name="new_textdocument">Նոր տեքստային փաստաթուղթ</string>
+ <string name="new_presentation">Նոր շնորհանդես</string>
+ <string name="new_spreadsheet">Նոր էլ․ աղյուսակ</string>
+ <string name="new_drawing">Նոր նկարչություն</string>
+ <string name="select_file_to_open">Բացելու համար ընտրեք նիշքը</string>
+ <string name="search_find_previous">Գտեք նախորդը</string>
+ <string name="file_icon_desc">նիշքի պատկերակ</string>
+ <string name="title_recents">Վերջին նիշքերը</string>
+ <string name="title_browser">Բոլոր նիշքերը</string>
+ <string name="pref_category_general">Ընդհանուր</string>
+ <string name="pref_experimental_editing">Փորձարարական ռեժիմ</string>
+ <string name="pref_developer_mode">Մշակողի ռեժիմ</string>
+ <string name="action_about">Մասին</string>
+ <string name="action_parts">Մասեր</string>
+ <string name="action_settings">Կարգավորումներ</string>
+ <string name="action_keyboard">Ցույց տալ ստեղնաշարը</string>
+ <string name="action_save">Պահել</string>
+ <string name="action_save_as">Պահել որպես…</string>
+ <string name="action_fromat">Միացնել ձևաչափը</string>
+ <string name="action_search">Փնտրում</string>
+ <string name="action_UNO_commands">Ուղարկել UNO Cmd</string>
+ <string name="message_saved">Պահպանումն ավարտված է</string>
+ <string name="password">Գաղտնաբառ</string>
+ <string name="action_undo">Հետարկել</string>
+ <string name="action_redo">Կրկին անել</string>
+ <string name="save_alert_dialog_title">Պահե՞լ փաստաթուղթը փակելուց առաջ:</string>
+ <string name="save_document">ՊԱՀԵԼ</string>
+ <string name="action_cancel">Չեղարկել</string>
+ <string name="no_save_document">ՈՉ</string>
+ <string name="action_presentation">Սահիկացուցադրություն</string>
+ <string name="action_add_slide">Ավելացնել սահիկ</string>
+ <string name="slideshow_action_back">Հետ</string>
+ <string name="calc_insert_before">Զետեղել</string>
+ <string name="calc_delete">Ջնջել</string>
+ <string name="calc_hide">Թաքցնել</string>
+ <string name="calc_show">Ցուցադրել</string>
+ <string name="calc_optimal_length">Օպտիմալ երկարություն</string>
+ <string name="calc_adjust_length">Կարգավորել երկարությունը</string>
+ <string name="calc_adjust_height">Կարգավորել Բարձրությունը</string>
+ <string name="calc_adjust_width">Կարգավորել Լայնությունը</string>
+ <string name="calc_optimal_height">Օպտիմալ բարձրություն</string>
+ <string name="calc_optimal_width">Օպտիմալ լայնություն</string>
+ <string name="calc_optimal_length_confirm">ԼԱՎ</string>
+ <string name="action_add_worksheet">Ավելացնել աշխատաթերթիկ</string>
+ <string name="action_pwd_dialog_OK">ԼԱՎ</string>
+ <string name="action_pwd_dialog_cancel">Չեղարկել</string>
+ <string name="action_pwd_dialog_title">Խնդրում ենք մուտքագրել գաղտնաբառը</string>
+ <string name="take_photo">Լուսանկարել</string>
+ <string name="select_photo">Ընտրեք Լուսանկար</string>
+ <string name="select_photo_title">Ընտրեք նկարը</string>
+ <string name="no_camera_found">Տեսախցիկ չի գտնվել</string>
+ <string name="compress_photo_smallest_size">Ամենափոքր Չափը</string>
+ <string name="compress_photo_medium_size">Միջին չափ</string>
+ <string name="compress_photo_no_compress">Մի սեղմեք</string>
+ <string name="compress_photo_title">Ցանկանու՞մ եք սեղմել լուսանկարը:</string>
+ <string name="action_copy">Պատճեն</string>
+ <string name="action_paste">Հետ տեղադրել</string>
+ <string name="action_cut">Կտրել</string>
+ <string name="action_back">Հետ</string>
+ <string name="insert_table">Տեղադրեք աղյուսակ</string>
+ <string name="select_insert_options">Ընտրեք տեղադրման ընտրանքները.</string>
+ <string name="action_rename_worksheet">Անվանափոխեք աշխատաթերթիկը</string>
+ <string name="action_delete_worksheet">Ջնջեք աշխատաթերթիկը</string>
+ <string name="action_delete_slide">Ջնջեք սահիկը</string>
+ <string name="name_already_used">Նշված անունն արդեն օգտագործվում է։</string>
+ <string name="part_deleted">Մասի ջնջված է։</string>
+ <string name="UNO_commands_string_type_hint">Տեսակ</string>
+ <string name="UNO_commands_string_value_hint">Արժեք</string>
+ <string name="UNO_commands_string_parent_value_hint">Ծնողական արժեքը</string>
+ <string name="action_exportToPDF">Արտահանել PDF</string>
+ <string name="action_print">Տպել</string>
+ <string name="tabhost_character">Նիշ</string>
+ <string name="tabhost_paragraph">Պարբերություն</string>
+ <string name="tabhost_insert">Զետեղել</string>
+ <string name="tabhost_style">Ոճ</string>
+ <string name="alert_ok">ԼԱՎ</string>
+ <string name="alert_cancel">Չեղարկել</string>
+ <string name="current_uno_command">Ընթացիկ UNO հրամանը</string>
+ <string name="display_language">Արտածիր լեզուն</string>
+ <string name="display_language_summary">Սահմանեք ցուցադրման լռելյայն լեզուն</string>
+ <string name="pdf_export_finished">PDF արտահանումն ավարտված է</string>
+ <string name="unable_to_export_pdf">Հնարավոր չէ արտահանել pdf</string>
+ <string name="unable_to_save">Հնարավոր չէ պահպանել նիշքը</string>
+ <string name="error">Սխալ</string>
+ <string name="bmp_null">Bmp is null!</string>
+ <string name="page">Էջ</string>
+ <string name="sheet">Թերթ</string>
+ <string name="slide">Սահիկ</string>
+ <string name="part">Մաս</string>
+ <string name="highlight_color">Ընդգծման գույն</string>
+ <string name="font_color">Տառատեսակի գույն</string>
+ <string name="automatic">Ինքնաշխատ</string>
+ <string name="readonly_file">Այս նիշքը միայն-կարդալու է։</string>
+ <string name="part_name_changed">Մասի անվանումը փոխված է։</string>
+ <string name="app_name">LibreOffice Դիտակ</string>
+ <string name="app_version">Version: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_privacy_policy">Գաղտնիության քաղաքականություն</string>
+ <string name="default_document_name">անվերնագիր</string>
+ <string name="pref_experimental_editing_summary">Միացնել փորձարարական խմբագրման ռեժիմը: Օգտագործեք ձեր սեփական ռիսկով:</string>
+ <string name="search_find_next">Գտեք հաջորդը</string>
+ <string name="message_saving">Փաստաթուղթը պահվում է…</string>
+ <string name="pref_developer_mode_summary">Միացրեք մշակողի ռեժիմը, որտեղ կարող եք UNO հրամաններ ուղարկել հավելվածի ներսում: Օգտագործեք ձեր սեփական ռիսկով:</string>
+ <string name="message_saving_failed">Փաստաթղթի պահպանումը ձախողվեց:</string>
+ <string name="calc_alert_double_click_optimal_length">Հուշում. Կրկնակի հպեք վերնագրի վրա՝ սահմանում է օպտիմալ լայնությունը/բարձրությունը:</string>
+ <string name="calc_optimal_length_default_text">Մուտքագրեք լրացուցիչ երկարությունը 100-րդ/մմ</string>
+ <string name="compress_photo_max_quality">Առավելագույն որակ</string>
+ <string name="action_text_copied">Տեքստը պատճենվեց սեղմատախտակին</string>
+ <string name="select_delete_options">Ընտրեք ջնջելու ընտրանքները.</string>
+ <string name="UNO_commands_string_hint">UNO հրաման</string>
+ <string name="enter_part_name">Մուտքագրեք մասի անունը</string>
+ <string name="action_rename_slide">Անվանափոխեք սահիկը</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-ia/strings.xml b/android/source/res/values-ia/strings.xml
new file mode 100644
index 000000000000..09a33ba1608f
--- /dev/null
+++ b/android/source/res/values-ia/strings.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="pref_developer_mode_summary">Activar le modo disveloppator ubi tu pote inviar commandos UNO intra le application. Usa lo sub tu proprie risco.</string>
+ <string name="app_description">LibreOffice Viewer es un visualisator de documentos basate sur LibreOffice.</string>
+ <string name="calc_show">Monstrar</string>
+ <string name="pref_developer_mode">Modo de disveloppator</string>
+ <string name="action_pwd_dialog_cancel">Cancellar</string>
+ <string name="create_file">Crear un nove file</string>
+ <string name="calc_hide">Celar</string>
+ <string name="action_UNO_commands">Inviar commando UNO</string>
+ <string name="default_document_name">sin titulo</string>
+ <string name="action_about">A proposito de</string>
+ <string name="action_fromat">Activar formato</string>
+ <string name="password">Contrasigno</string>
+ <string name="UNO_commands_string_type_hint">Typo</string>
+ <string name="slideshow_action_back">Retro</string>
+ <string name="bmp_null">Bmp non valide!</string>
+ <string name="action_paste">Collar</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="save_document">SALVEGUARDAR</string>
+ <string name="new_spreadsheet">Nove folio de calculo</string>
+ <string name="select_file_to_open">Selige un file a aperir</string>
+ <string name="unable_to_export_pdf">Non poteva exportar a PDF</string>
+ <string name="action_save_as">Salveguardar como…</string>
+ <string name="font_color">Color de littera</string>
+ <string name="new_drawing">Nove designo</string>
+ <string name="automatic">Automatic</string>
+ <string name="action_redo">Refacer</string>
+ <string name="file_icon_desc">icone de file</string>
+ <string name="title_recents">Files recente</string>
+ <string name="page">Pagina</string>
+ <string name="calc_insert_before">Inserer</string>
+ <string name="tabhost_style">Stylo</string>
+ <string name="select_photo_title">Seliger un imagine</string>
+ <string name="no_save_document">NON</string>
+ <string name="new_textdocument">Nove documento de texto</string>
+ <string name="action_print">Imprimer</string>
+ <string name="new_presentation">Nove presentation</string>
+ <string name="pref_experimental_editing">Modo experimental</string>
+ <string name="calc_delete">Deler</string>
+ <string name="action_undo">Disfacer</string>
+ <string name="app_vendor">Iste version es fornite per $VENDOR.</string>
+ <string name="action_pwd_dialog_title">Insere le contrasigno</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="action_parts">Partes</string>
+ <string name="display_language_summary">Definir le lingua predefinite del interfacie</string>
+ <string name="pref_category_general">General</string>
+ <string name="action_text_copied">Texto copiate al area de transferentia</string>
+ <string name="action_exportToPDF">Exportar a PDF</string>
+ <string name="action_keyboard">Monstrar le claviero</string>
+ <string name="about_privacy_policy">Politica de confidentialitate</string>
+ <string name="action_presentation">Presentation de diapositivas</string>
+ <string name="select_photo">Seliger un photo</string>
+ <string name="action_copy">Copiar</string>
+ <string name="tabhost_insert">Inserer</string>
+ <string name="action_search">Cerca</string>
+ <string name="no_camera_found">Necun camera trovate</string>
+ <string name="error">Error</string>
+ <string name="app_name_settings">Parametros del visualisator de LibreOffice</string>
+ <string name="name_already_used">Le nomine fornite jam es in uso.</string>
+ <string name="action_save">Salveguardar</string>
+ <string name="alert_ok">OK</string>
+ <string name="action_settings">Parametros</string>
+ <string name="app_version">Version: %1$s&lt;br&gt;ID de compilation: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_license">Monstrar le licentia</string>
+ <string name="title_browser">Tote le files</string>
+ <string name="unable_to_save">Non poteva salveguardar le file</string>
+ <string name="app_name">Visualisator de LibreOffice</string>
+ <string name="action_add_slide">Adder un diapositiva</string>
+ <string name="action_cancel">Cancellar</string>
+ <string name="display_language">Lingua a monstrar</string>
+ <string name="search_find_next">Trovar le sequente</string>
+ <string name="search_find_previous">Trovar le previe</string>
+ <string name="pref_experimental_editing_summary">Activar le modo de modification experimental. Usa lo sub tu proprie risco.</string>
+ <string name="readonly_file">Iste file es solo lectura</string>
+ <string name="about_notice">Monstrar le aviso</string>
+ <string name="alert_cancel">Cancellar</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-in/strings.xml b/android/source/res/values-in/strings.xml
new file mode 100644
index 000000000000..682f618e1dbe
--- /dev/null
+++ b/android/source/res/values-in/strings.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Penampil LibreOffice</string>
+ <string name="app_name_settings">Pengaturan Penampil LibreOffice</string>
+ <string name="app_version">Versi: %1$s&lt;br&gt;ID Build: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">Penampil LibreOffice adalah suatu penampil dokumen yang berbasis LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Rilis ini disediakan oleh $VENDOR.</string>
+ <string name="readonly_file">Berkas ini hanya-baca.</string>
+ <string name="about_license">Tampilkan Lisensi</string>
+ <string name="about_notice">Tampilkan Pemberitahuan</string>
+ <string name="about_privacy_policy">Kebijakan Privasi</string>
+ <string name="create_file">Buat Berkas Baru</string>
+ <string name="new_textdocument">Dokumen Teks Baru</string>
+ <string name="new_presentation">Presentasi Baru</string>
+ <string name="new_spreadsheet">Lembar Kerja Baru</string>
+ <string name="new_drawing">Gambar Baru</string>
+ <string name="default_document_name">tanpa judul</string>
+ <string name="select_file_to_open">Pilih berkas yang akan dibuka</string>
+ <string name="search_find_next">Cari Selanjutnya</string>
+ <string name="file_icon_desc">fileicon</string>
+ <string name="title_recents">Berkas baru-baru Ini</string>
+ <string name="title_browser">Semua berkas</string>
+ <string name="pref_category_general">Umum</string>
+ <string name="pref_experimental_editing">Mode Eksperimen</string>
+ <string name="pref_developer_mode">Mode Pengembang</string>
+ <string name="pref_developer_mode_summary">Memfungsikan mode pengembang dimana Anda dapat mengirim perintah-perintah UNO di dalam app. Risiko Anda tanggung sendiri.</string>
+ <string name="action_about">Tentang</string>
+ <string name="action_settings">Pengaturan</string>
+ <string name="action_keyboard">Tampilkan papan ketik</string>
+ <string name="action_save">Simpan</string>
+ <string name="action_fromat">Fungsikan Format</string>
+ <string name="action_search">Cari</string>
+ <string name="action_UNO_commands">Kirim Perintah UNO</string>
+ <string name="message_saved">Penyimpanan selesai</string>
+ <string name="message_saving">Menyimpan dokumen…</string>
+ <string name="message_saving_failed">Penyimpanan dokumen gagal.</string>
+ <string name="password">Kata Sandi</string>
+ <string name="action_undo">Tak Jadi</string>
+ <string name="action_redo">Jadi Lagi</string>
+ <string name="action_parts">Bagian</string>
+ <string name="action_cancel">Batal</string>
+ <string name="no_save_document">TIDAK</string>
+ <string name="action_add_slide">Tambah Salindia</string>
+ <string name="action_cut">Potong</string>
+ <string name="insert_table">Sisip tabel</string>
+ <string name="select_insert_options">Pilih opsi sisip:</string>
+ <string name="select_delete_options">Pilih opsi hapus:</string>
+ <string name="action_rename_worksheet">Ubah nama lembar kerja</string>
+ <string name="action_delete_worksheet">Hapus lembar kerja</string>
+ <string name="action_delete_slide">Hapus salindia</string>
+ <string name="name_already_used">Nama yang diberikan sudah terpakai.</string>
+ <string name="part_name_changed">Nama bagian telah diubah.</string>
+ <string name="UNO_commands_string_hint">Perintah UNO</string>
+ <string name="UNO_commands_string_type_hint">Tipe</string>
+ <string name="UNO_commands_string_value_hint">Nilai</string>
+ <string name="UNO_commands_string_parent_value_hint">Nilai Induk</string>
+ <string name="action_exportToPDF">Ekspor Ke PDF</string>
+ <string name="action_print">Cetak</string>
+ <string name="tabhost_character">Karakter</string>
+ <string name="tabhost_paragraph">Paragraf</string>
+ <string name="tabhost_insert">Sisip</string>
+ <string name="tabhost_style">Gaya</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Batal</string>
+ <string name="current_uno_command">Perintah UNO saat ini</string>
+ <string name="display_language">Bahasa Tampilan</string>
+ <string name="display_language_summary">Atur bahasa tampilan baku</string>
+ <string name="pdf_export_finished">Ekspor PDF telah selesai</string>
+ <string name="unable_to_export_pdf">Tidak bisa mengekspor ke pdf</string>
+ <string name="unable_to_save">Tidak bisa menyimpan berkas</string>
+ <string name="error">Galat</string>
+ <string name="enter_part_name">Masukkan suatu nama bagian</string>
+ <string name="bmp_null">Bmp adalah null!</string>
+ <string name="page">Halaman</string>
+ <string name="sheet">Lembar</string>
+ <string name="slide">Salindia</string>
+ <string name="part">Bagian</string>
+ <string name="highlight_color">Warna Penyorotan</string>
+ <string name="font_color">Warna Fonta</string>
+ <string name="action_rename_slide">Ubah Nama Salindia</string>
+ <string name="automatic">Otomatis</string>
+ <string name="search_find_previous">Cari Sebelumnya</string>
+ <string name="save_document">SIMPAN</string>
+ <string name="pref_experimental_editing_summary">Memfungsikan mode penyuntingan eksperimen. Risiko Anda tanggung sendiri.</string>
+ <string name="save_alert_dialog_title">Simpan dokumen sebelum menutup?</string>
+ <string name="action_presentation">Pertunjukan salindia</string>
+ <string name="action_back">Mundur</string>
+ <string name="action_text_copied">Teks disalin ke papan klip</string>
+ <string name="part_deleted">Bagian telah dihapus.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-is/strings.xml b/android/source/res/values-is/strings.xml
new file mode 100644
index 000000000000..ba8d367ce4a9
--- /dev/null
+++ b/android/source/res/values-is/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">LibreOffice-skoðari</string>
+ <string name="app_name_settings">Stillingar LibreOffice-skoðara</string>
+ <string name="app_version">Útgáfa: %1$s&lt;br&gt;Byggingarauðkenni: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_privacy_policy">Meðferð persónuupplýsinga</string>
+ <string name="create_file">Búa til nýja skrá</string>
+ <string name="search_find_next">Finna næsta</string>
+ <string name="search_find_previous">Finna fyrra</string>
+ <string name="action_save_as">Vista sem…</string>
+ <string name="page">Síða</string>
+ <string name="sheet">Blað</string>
+ <string name="slide">Skyggna</string>
+ <string name="part">Hluti</string>
+ <string name="highlight_color">Áherslulitur</string>
+ <string name="font_color">Litur á letri</string>
+ <string name="action_rename_slide">Endurnefna skyggnu</string>
+ <string name="automatic">Sjálfvirkt</string>
+ <string name="app_description">LibreOffice-skoðarinn er skjalaskoðari byggður á LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">"Þessi útgáfa var gefin út af $VENDOR."</string>
+ <string name="readonly_file">Þessi skrá er aðeins lesanleg.</string>
+ <string name="about_license">Birta notkunarleyfi</string>
+ <string name="about_notice">Birta tilkynningu</string>
+ <string name="new_textdocument">Nýtt textaskjal</string>
+ <string name="new_presentation">Ný kynning</string>
+ <string name="new_spreadsheet">Nýr töflureiknir</string>
+ <string name="new_drawing">Ný teikning</string>
+ <string name="default_document_name">ónefnt</string>
+ <string name="select_file_to_open">Veldu skrá til að opna</string>
+ <string name="title_recents">Nýlegar skrár</string>
+ <string name="title_browser">Allar skrár</string>
+ <string name="pref_category_general">Almennt</string>
+ <string name="pref_experimental_editing">Tilraunahamur</string>
+ <string name="pref_experimental_editing_summary">Virkjaðu ham á tilraunastigi. Notist á eigin ábyrgð.</string>
+ <string name="pref_developer_mode">Forritarahamur</string>
+ <string name="pref_developer_mode_summary">Virkjaðu forritaraham þar sem þú getur sent UNO-skipanir innan forritsins. Notist á eigin ábyrgð.</string>
+ <string name="action_about">Um hugbúnaðinn</string>
+ <string name="action_parts">Hlutar</string>
+ <string name="action_settings">Stillingar</string>
+ <string name="action_keyboard">Birta lyklaborð</string>
+ <string name="action_save">Vista</string>
+ <string name="action_fromat">Virkja snið</string>
+ <string name="action_search">Leita</string>
+ <string name="action_UNO_commands">Senda UNO-skipun</string>
+ <string name="message_saved">Vistun lokið</string>
+ <string name="message_saving">Vista skjalið…</string>
+ <string name="message_saving_failed">Vistun skjalsins mistókst.</string>
+ <string name="password">Lykilorð</string>
+ <string name="action_undo">Afturkalla</string>
+ <string name="action_redo">Endurgera</string>
+ <string name="save_alert_dialog_title">Vista skjalið áður en því er lokað\?</string>
+ <string name="save_document">VISTA</string>
+ <string name="action_cancel">Hætta við</string>
+ <string name="no_save_document">NEI</string>
+ <string name="action_presentation">Skyggnusýning</string>
+ <string name="action_add_slide">Bæta við skyggnu</string>
+ <string name="slideshow_action_back">Til baka</string>
+ <string name="calc_insert_before">Setja inn</string>
+ <string name="calc_delete">Eyða</string>
+ <string name="calc_hide">Fela</string>
+ <string name="calc_show">Birta</string>
+ <string name="calc_optimal_length">Besta lengd</string>
+ <string name="calc_adjust_length">Aðlaga lengd</string>
+ <string name="calc_adjust_height">Aðlaga hæð</string>
+ <string name="calc_adjust_width">Aðlaga breidd</string>
+ <string name="calc_optimal_height">Besta hæð</string>
+ <string name="calc_optimal_width">Besta breidd</string>
+ <string name="calc_optimal_length_confirm">Í lagi</string>
+ <string name="calc_optimal_length_default_text">Settu inn viðbótarlengd í hundruðustu hlutum mm</string>
+ <string name="calc_alert_double_click_optimal_length">Ábending: Tvíbank á fyrirsögn setur bestu breidd/hæð.</string>
+ <string name="action_add_worksheet">Bæta við töflureikniblaði</string>
+ <string name="action_pwd_dialog_OK">Í lagi</string>
+ <string name="action_pwd_dialog_cancel">Hætta við</string>
+ <string name="action_pwd_dialog_title">Settu inn lykilorð</string>
+ <string name="take_photo">Taka ljósmynd</string>
+ <string name="select_photo">Veldu ljósmynd</string>
+ <string name="select_photo_title">Veldu mynd</string>
+ <string name="no_camera_found">Engin myndavél fannst</string>
+ <string name="compress_photo_smallest_size">Minnsta stærð</string>
+ <string name="compress_photo_medium_size">Miðlungsstærð</string>
+ <string name="compress_photo_max_quality">Hámarksgæði</string>
+ <string name="compress_photo_no_compress">Ekki þjappa</string>
+ <string name="compress_photo_title">Viltu þjappa ljósmyndinni\?</string>
+ <string name="action_copy">Afrita</string>
+ <string name="action_paste">Líma</string>
+ <string name="action_cut">Klippa</string>
+ <string name="action_back">Til baka</string>
+ <string name="action_text_copied">Texti afritaður á klippispjaldið</string>
+ <string name="insert_table">Setja inn töflu</string>
+ <string name="select_insert_options">Veldu valkosti innsetingar:</string>
+ <string name="select_delete_options">Veldu valkosti eyðingar:</string>
+ <string name="action_rename_worksheet">Endurnefna vinnublað</string>
+ <string name="action_delete_worksheet">Eyða vinnublaði</string>
+ <string name="action_delete_slide">Eyða skyggnu</string>
+ <string name="name_already_used">Uppgefið heiti er þegar í notkun.</string>
+ <string name="part_name_changed">Heiti hlutans hefur verið breytt.</string>
+ <string name="part_deleted">Hluta hefur verið eytt.</string>
+ <string name="UNO_commands_string_hint">UNO-skipun</string>
+ <string name="UNO_commands_string_type_hint">Tegund</string>
+ <string name="UNO_commands_string_value_hint">Gildi</string>
+ <string name="UNO_commands_string_parent_value_hint">Yfirgildi</string>
+ <string name="action_exportToPDF">Flytja út í PDF</string>
+ <string name="action_print">Prenta</string>
+ <string name="tabhost_character">Stafur</string>
+ <string name="tabhost_paragraph">Málsgrein</string>
+ <string name="tabhost_insert">Setja inn</string>
+ <string name="tabhost_style">Stíll</string>
+ <string name="alert_ok">Í lagi</string>
+ <string name="alert_cancel">Hætta við</string>
+ <string name="current_uno_command">Fyrirliggjandi UNO-skipun</string>
+ <string name="display_language">Birt tungumál</string>
+ <string name="display_language_summary">Settu sjálfgefið birtingartungumál</string>
+ <string name="pdf_export_finished">Útflutningi í PDF er lokið</string>
+ <string name="unable_to_export_pdf">Tókst ekki að flytja út í PDF</string>
+ <string name="unable_to_save">Get ekki vistað skrá</string>
+ <string name="error">Villa</string>
+ <string name="enter_part_name">Settu inn heiti á hluta</string>
+ <string name="bmp_null">Bmp er núll!</string>
+ <string name="file_icon_desc">skráartákn</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-it/strings.xml b/android/source/res/values-it/strings.xml
new file mode 100644
index 000000000000..35dade166124
--- /dev/null
+++ b/android/source/res/values-it/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">Impostazioni del Visualizzatore di LibreOffice</string>
+ <string name="app_credits">https://it.libreoffice.org/</string>
+ <string name="app_vendor">Versione fornita da $VENDOR.</string>
+ <string name="readonly_file">Questo file è di sola lettura.</string>
+ <string name="about_license">Mostra licenza</string>
+ <string name="app_name">Visualizzatore di LibreOffice</string>
+ <string name="app_description">Il Visualizzatore di LibreOffice è un\'app per visualizzare i documenti basata su LibreOffice.</string>
+ <string name="about_notice">Mostra avviso</string>
+ <string name="new_textdocument">Nuovo documento di testo</string>
+ <string name="new_presentation">Nuova presentazione</string>
+ <string name="new_spreadsheet">Nuovo foglio di calcolo</string>
+ <string name="new_drawing">Nuovo disegno</string>
+ <string name="default_document_name">senza titolo</string>
+ <string name="select_file_to_open">Seleziona file da aprire</string>
+ <string name="app_version">Versione: %1$s&lt;br&gt;ID Build: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="title_recents">File recenti</string>
+ <string name="title_browser">Tutti i file</string>
+ <string name="pref_category_general">Generale</string>
+ <string name="pref_experimental_editing">Modalità sperimentale</string>
+ <string name="pref_experimental_editing_summary">Attiva la modalità di modifica sperimentale a tuo rischio e sotto la tua responsabilità.</string>
+ <string name="pref_developer_mode">Modalità sviluppatore</string>
+ <string name="pref_developer_mode_summary">Attiva la modalità sviluppatore per inviare comandi UNO direttamente dall\'app. Il suo uso è a tuo rischio e sotto la tua responsabilità.</string>
+ <string name="action_about">Informazioni</string>
+ <string name="action_parts">Parti</string>
+ <string name="action_settings">Impostazioni</string>
+ <string name="action_keyboard">Mostra tastiera</string>
+ <string name="action_search">Cerca</string>
+ <string name="action_UNO_commands">Invia comando UNO</string>
+ <string name="message_saved">Salvataggio completato</string>
+ <string name="message_saving">Salvataggio del documento…</string>
+ <string name="message_saving_failed">Impossibile salvare il documento.</string>
+ <string name="password">Password</string>
+ <string name="action_undo">Annulla</string>
+ <string name="action_redo">Ripeti</string>
+ <string name="save_document">SALVA</string>
+ <string name="action_cancel">Annulla</string>
+ <string name="no_save_document">NO</string>
+ <string name="action_presentation">Presentazione</string>
+ <string name="action_add_slide">Aggiungi diapositiva</string>
+ <string name="action_save">Salva</string>
+ <string name="action_fromat">Attiva formato</string>
+ <string name="save_alert_dialog_title">Salvare il documento prima di chiuderlo\?</string>
+ <string name="pdf_export_finished">Esportazione in PDF terminata</string>
+ <string name="calc_show">Mostra</string>
+ <string name="action_pwd_dialog_cancel">Annulla</string>
+ <string name="create_file">Crea nuovo file</string>
+ <string name="slide">Diapositiva</string>
+ <string name="part_name_changed">Il nome della parte è stato modificato.</string>
+ <string name="compress_photo_max_quality">Massima qualità</string>
+ <string name="calc_hide">Nascondi</string>
+ <string name="select_insert_options">Scegli opzioni di inserimento:</string>
+ <string name="UNO_commands_string_type_hint">Tipo</string>
+ <string name="current_uno_command">Comando UNO attuale</string>
+ <string name="slideshow_action_back">Indietro</string>
+ <string name="bmp_null">File Bitmap non valido.</string>
+ <string name="action_paste">Incolla</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="calc_adjust_length">Regola la lunghezza</string>
+ <string name="part">Parte</string>
+ <string name="unable_to_export_pdf">Impossibile esportare in PDF</string>
+ <string name="action_save_as">Salva con nome…</string>
+ <string name="font_color">Colore carattere</string>
+ <string name="action_rename_worksheet">Rinomina foglio di lavoro</string>
+ <string name="calc_optimal_length">Lunghezza ottimale</string>
+ <string name="enter_part_name">Inserisci un nome per la parte</string>
+ <string name="automatic">Automatico</string>
+ <string name="action_delete_slide">Elimina diapositiva</string>
+ <string name="action_cut">Taglia</string>
+ <string name="file_icon_desc">iconafile</string>
+ <string name="page">Pagina</string>
+ <string name="calc_insert_before">Inserisci</string>
+ <string name="calc_optimal_length_default_text">Inserisci lunghezza aggiuntiva in centesimi di millimetro</string>
+ <string name="tabhost_style">Stile</string>
+ <string name="select_photo_title">Seleziona immagine</string>
+ <string name="calc_optimal_width">Larghezza ottimale</string>
+ <string name="action_delete_worksheet">Elimina foglio di lavoro</string>
+ <string name="highlight_color">Colore evidenziazione</string>
+ <string name="action_print">Stampa</string>
+ <string name="calc_adjust_width">Regola la larghezza</string>
+ <string name="action_add_worksheet">Aggiungi foglio di calcolo</string>
+ <string name="tabhost_paragraph">Paragrafo</string>
+ <string name="action_back">Indietro</string>
+ <string name="calc_delete">Elimina</string>
+ <string name="part_deleted">La parte è stata eliminata.</string>
+ <string name="action_pwd_dialog_title">Inserisci password</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="compress_photo_medium_size">Dimensione media</string>
+ <string name="display_language_summary">Imposta lingua di visualizzazione predefinita</string>
+ <string name="select_delete_options">Scegli opzioni di eliminazione:</string>
+ <string name="action_text_copied">Testo copiato negli appunti</string>
+ <string name="action_exportToPDF">Esporta in PDF</string>
+ <string name="action_rename_slide">Rinomina diapositiva</string>
+ <string name="about_privacy_policy">Informativa sulla riservatezza</string>
+ <string name="UNO_commands_string_parent_value_hint">Valore padre</string>
+ <string name="compress_photo_smallest_size">Dimensione minima</string>
+ <string name="select_photo">Seleziona foto</string>
+ <string name="compress_photo_no_compress">Nessuna compressione</string>
+ <string name="action_copy">Copia</string>
+ <string name="tabhost_insert">Inserisci</string>
+ <string name="no_camera_found">Fotocamera non trovata</string>
+ <string name="error">Errore</string>
+ <string name="name_already_used">Il nome specificato è già in uso.</string>
+ <string name="UNO_commands_string_hint">Comando UNO</string>
+ <string name="alert_ok">OK</string>
+ <string name="UNO_commands_string_value_hint">Valore</string>
+ <string name="sheet">Foglio</string>
+ <string name="compress_photo_title">Comprimere la foto\?</string>
+ <string name="take_photo">Fai una foto</string>
+ <string name="unable_to_save">Impossibile salvare il file</string>
+ <string name="insert_table">Inserisci tabella</string>
+ <string name="calc_adjust_height">Regola l\'altezza</string>
+ <string name="display_language">Mostra lingua</string>
+ <string name="search_find_next">Trova successivo</string>
+ <string name="search_find_previous">Trova precedente</string>
+ <string name="alert_cancel">Annulla</string>
+ <string name="calc_optimal_height">Altezza ottimale</string>
+ <string name="tabhost_character">Carattere</string>
+ <string name="calc_alert_double_click_optimal_length">Suggerimento: doppio tocco su un\'intestazione imposta altezza/larghezza ottimale.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-ja/strings.xml b/android/source/res/values-ja/strings.xml
new file mode 100644
index 000000000000..a6b3daec9354
--- /dev/null
+++ b/android/source/res/values-ja/strings.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources></resources> \ No newline at end of file
diff --git a/android/source/res/values-kk/strings.xml b/android/source/res/values-kk/strings.xml
new file mode 100644
index 000000000000..a6b3daec9354
--- /dev/null
+++ b/android/source/res/values-kk/strings.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources></resources> \ No newline at end of file
diff --git a/android/source/res/values-ne/strings.xml b/android/source/res/values-ne/strings.xml
new file mode 100644
index 000000000000..430de40d93d2
--- /dev/null
+++ b/android/source/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_version">संस्करण: %1$s&lt;br&gt;बिल्ड आइडी: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">यो संस्करण $VENDOR द्वारा प्रदान गरिएको हो।</string>
+ <string name="readonly_file">यो फाइल हेर्न-मात्र-मिल्ने छ।</string>
+ <string name="about_notice">सूचना देखाउनुहोस्</string>
+ <string name="new_textdocument">नयाँ पाठ कागजात</string>
+ <string name="new_presentation">नयाँ प्रस्तुति</string>
+ <string name="new_spreadsheet">नयाँ स्प्रेडसिट</string>
+ <string name="new_drawing">नयाँ ड्रइङ</string>
+ <string name="select_file_to_open">खोल्नको लागि फाइल रोज्नुहोस्</string>
+ <string name="file_icon_desc">फाइलआइकन</string>
+ <string name="title_recents">हालका फाइलहरू</string>
+ <string name="pref_category_general">सामान्य</string>
+ <string name="pref_experimental_editing">प्रयोगात्मक मोड</string>
+ <string name="app_name">लिब्रेअफिस भ्युअर</string>
+ <string name="app_name_settings">लिब्रेअफिस भ्युअर सेटिङ</string>
+ <string name="app_description">लिब्रेअफिस भ्युअर लिब्रेअफिसमा आधारित कागजात भ्युअर हो।</string>
+ <string name="default_document_name">शीर्षक नभएको</string>
+ <string name="about_license">इजाजतपत्र देखाउनुहोस्</string>
+ <string name="title_browser">सबै फाइलहरू</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-night/colors.xml b/android/source/res/values-night/colors.xml
new file mode 100644
index 000000000000..c6260c191d3e
--- /dev/null
+++ b/android/source/res/values-night/colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="background_floating">@color/background_floating_material_dark</color>
+
+ <color name="toolbar_foreground">#efefef</color>
+</resources>
diff --git a/android/source/res/values-nl/strings.xml b/android/source/res/values-nl/strings.xml
new file mode 100644
index 000000000000..1e8879288993
--- /dev/null
+++ b/android/source/res/values-nl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">LibreOffice Viewer-instellingen</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Deze uitgave is geleverd door $VENDOR.</string>
+ <string name="readonly_file">Dit bestand is alleen-lezen.</string>
+ <string name="about_license">Licentie inzien</string>
+ <string name="about_notice">Notitie weergeven</string>
+ <string name="about_privacy_policy">Privacybeleid</string>
+ <string name="create_file">Nieuw bestand maken</string>
+ <string name="new_presentation">Nieuwe presentatie</string>
+ <string name="new_spreadsheet">Nieuw werkblad</string>
+ <string name="new_drawing">Nieuwe tekening</string>
+ <string name="default_document_name">naamloos</string>
+ <string name="select_file_to_open">Selecteer te openen bestand</string>
+ <string name="search_find_next">Volgende zoeken</string>
+ <string name="search_find_previous">Vorige zoeken</string>
+ <string name="file_icon_desc">Bestandspictogram</string>
+ <string name="title_recents">Recent geopende bestanden</string>
+ <string name="title_browser">Alle bestanden</string>
+ <string name="pref_category_general">Algemeen</string>
+ <string name="pref_experimental_editing_summary">Schakel de experimentele bewerkingsmodus in. Gebruik op eigen risico.</string>
+ <string name="pref_developer_mode">Ontwikkelaarsmodus</string>
+ <string name="action_about">Info</string>
+ <string name="action_parts">Gedeeltes</string>
+ <string name="action_settings">Instellingen</string>
+ <string name="action_keyboard">Toetsenbord weergeven</string>
+ <string name="action_save">Opslaan</string>
+ <string name="action_search">Zoeken</string>
+ <string name="action_fromat">Indeling inschakelen</string>
+ <string name="message_saving">Het document wordt opgeslagen…</string>
+ <string name="message_saving_failed">Opslaan van het document is mislukt.</string>
+ <string name="password">Wachtwoord</string>
+ <string name="action_undo">Ongedaan maken</string>
+ <string name="action_redo">Opnieuw</string>
+ <string name="save_document">OPSLAAN</string>
+ <string name="action_cancel">Annuleren</string>
+ <string name="no_save_document">Nee</string>
+ <string name="action_presentation">Presentatie</string>
+ <string name="action_add_slide">Dia toevoegen</string>
+ <string name="slideshow_action_back">Terug</string>
+ <string name="calc_insert_before">Invoegen</string>
+ <string name="calc_delete">Verwijderen</string>
+ <string name="calc_hide">Verbergen</string>
+ <string name="calc_show">Weergeven</string>
+ <string name="calc_optimal_length">Optimale lengte</string>
+ <string name="calc_adjust_length">Lengte aanpassen</string>
+ <string name="calc_adjust_height">Hoogte aanpassen</string>
+ <string name="calc_adjust_width">Breedte aanpassen</string>
+ <string name="calc_optimal_height">Optimale hoogte</string>
+ <string name="calc_optimal_width">Optimale breedte</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="calc_alert_double_click_optimal_length">Tip: Dubbeltik op een koptekst om de optimale breedte/hoogte in te stellen.</string>
+ <string name="action_add_worksheet">Werkblad toevoegen</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="action_pwd_dialog_cancel">Annuleren</string>
+ <string name="action_pwd_dialog_title">Wachtwoord invoeren alstublieft</string>
+ <string name="take_photo">Foto maken</string>
+ <string name="select_photo">Foto selecteren</string>
+ <string name="select_photo_title">Afbeelding selecteren</string>
+ <string name="no_camera_found">Geen camera gevonden</string>
+ <string name="compress_photo_smallest_size">Kleinste maat</string>
+ <string name="compress_photo_medium_size">Middelgroot</string>
+ <string name="compress_photo_no_compress">Niet comprimeren</string>
+ <string name="compress_photo_title">Wilt u de foto comprimeren\?</string>
+ <string name="action_paste">Plakken</string>
+ <string name="action_cut">Knippen</string>
+ <string name="insert_table">Tabel invoegen</string>
+ <string name="select_insert_options">Invoegopties selecteren:</string>
+ <string name="select_delete_options">Verwijderopties selecteren:</string>
+ <string name="action_rename_worksheet">Werkblad hernoemen</string>
+ <string name="action_delete_worksheet">Werkblad verwijderen</string>
+ <string name="action_delete_slide">Dia verwijderen</string>
+ <string name="name_already_used">De opgegeven naam wordt al gebruikt.</string>
+ <string name="part_deleted">De sectie is verwijderd.</string>
+ <string name="UNO_commands_string_hint">UNO-opdracht</string>
+ <string name="UNO_commands_string_type_hint">Type</string>
+ <string name="UNO_commands_string_value_hint">Waarde</string>
+ <string name="UNO_commands_string_parent_value_hint">Bovenliggende waarde</string>
+ <string name="action_exportToPDF">Als PDF exporteren</string>
+ <string name="action_print">Afdrukken</string>
+ <string name="tabhost_character">Teken</string>
+ <string name="tabhost_paragraph">Alinea</string>
+ <string name="tabhost_insert">Invoegen</string>
+ <string name="tabhost_style">Opmaakprofiel</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Annuleren</string>
+ <string name="current_uno_command">Huidige UNO-opdracht</string>
+ <string name="display_language">Taal weergeven</string>
+ <string name="pdf_export_finished">PDF-export voltooit</string>
+ <string name="unable_to_export_pdf">Kan niet exporteren naar PDF</string>
+ <string name="unable_to_save">Kan bestand niet opslaan</string>
+ <string name="error">Fout</string>
+ <string name="enter_part_name">Voer de sectienaam in</string>
+ <string name="bmp_null">Bmp is null!</string>
+ <string name="sheet">Blad</string>
+ <string name="slide">Dia</string>
+ <string name="part">Sectie</string>
+ <string name="highlight_color">Kleur benadrukken</string>
+ <string name="action_rename_slide">Dia hernoemen</string>
+ <string name="automatic">Automatisch</string>
+ <string name="action_UNO_commands">UNO-opdracht sturen</string>
+ <string name="app_version">Versie: %1$s&lt;br&gt;Build ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="new_textdocument">Volgend tekstdocument</string>
+ <string name="app_description">LibreOffice Viewer is een documentviewer gebaseerd op LibreOffice.</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="pref_experimental_editing">Experimentele modus</string>
+ <string name="pref_developer_mode_summary">Schakel de ontwikkelaarsmodus in, waarin u UNO-opdrachten binnen de app kunt verzenden. Gebruik op eigen risico.</string>
+ <string name="action_save_as">Opslaan als…</string>
+ <string name="message_saved">Opslaan voltooit</string>
+ <string name="save_alert_dialog_title">Het document opslaan voordat u het sluit\?</string>
+ <string name="calc_optimal_length_default_text">Extra lengte invoeren in 100ste/mm</string>
+ <string name="compress_photo_max_quality">Maximale kwaliteit</string>
+ <string name="action_copy">Kopiëren</string>
+ <string name="action_back">Terug</string>
+ <string name="action_text_copied">Tekst naar het klembord gekopieerd</string>
+ <string name="part_name_changed">De naam voor de sectie is gewijzigd.</string>
+ <string name="display_language_summary">De standaard weergavetaal instellen</string>
+ <string name="page">Pagina</string>
+ <string name="font_color">Tekstkleur</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-pa/strings.xml b/android/source/res/values-pa/strings.xml
new file mode 100644
index 000000000000..92fd72bdc265
--- /dev/null
+++ b/android/source/res/values-pa/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="action_save_as">…ਵਜੋਂ ਸੰਭਾਲੋ</string>
+ <string name="compress_photo_medium_size">ਮੱਧਮ ਆਕਾਰ</string>
+ <string name="app_description">LibreOffice ਦਰਸ਼ਕ LibreOffice ਉੱਤੇ ਅਧਾਰਿਤ ਦਸਤਾਵੇਜ਼ ਦਰਸ਼ਕ ਹੈ।</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">ਇਹ ਰੀਲਿਜ਼ $VENDOR ਵਲੋਂ ਤਿਆਰ ਕੀਤਾ ਗਿਆ ਸੀ।</string>
+ <string name="readonly_file">ਇਹ ਫਾਈਲ ਸਿਰਫ਼ ਪੜ੍ਹਨ ਲਈ ਹੈ।</string>
+ <string name="about_license">ਲਸੰਸ ਵੇਖਾਓ</string>
+ <string name="about_notice">ਨੋਟਿਸ ਵੇਖਾਓ</string>
+ <string name="create_file">ਨਵੀਂ ਫਾਈਲ ਬਣਾਓ</string>
+ <string name="new_textdocument">ਨਵਾਂ ਟੈਕਸਟ ਦਸਤਾਵੇਜ਼</string>
+ <string name="new_presentation">ਨਵੀਂ ਪੇਸ਼ਕਾਰੀ</string>
+ <string name="new_spreadsheet">ਨਵੀਂ ਸਪਰੈਡਸ਼ੀਟ</string>
+ <string name="new_drawing">ਨਵੀਂ ਡਰਾਇੰਗ</string>
+ <string name="select_file_to_open">ਖੋਲ੍ਹਣ ਲਈ ਫਾਈਲ ਚੁਣੋ</string>
+ <string name="title_recents">ਸੱਜਰੀਆਂ ਫਾਈਲਾਂ</string>
+ <string name="title_browser">ਸਾਰੀਆਂ ਫਾਈਲਾਂ</string>
+ <string name="pref_category_general">ਆਮ</string>
+ <string name="pref_experimental_editing">ਤਜਰਬੇਅਧੀਨ ਢੰਗ</string>
+ <string name="pref_developer_mode">ਡਿਵੈਲਪਰ ਢੰਗ</string>
+ <string name="action_about">ਇਸ ਬਾਰੇ</string>
+ <string name="action_parts">ਹਿੱਸੇ</string>
+ <string name="action_settings">ਸੈਟਿੰਗਾਂ</string>
+ <string name="action_keyboard">ਕੀਬੋਰਡ ਵੇਖਾਓ</string>
+ <string name="action_save">ਸੰਭਾਲੋ</string>
+ <string name="action_fromat">ਫਾਰਮੈਟ ਸਮਰੱਥ ਕਰੋ</string>
+ <string name="action_search">ਖੋਜੋ</string>
+ <string name="message_saved">ਸੰਭਾਲਣਾ ਸੰਭਾਲੋ</string>
+ <string name="message_saving_failed">ਦਸਤਾਵੇਜ਼ ਸੰਭਾਲਣ ਲਈ ਅਸਫ਼ਲ ਹੈ।</string>
+ <string name="password">ਪਾਸਵਰਡ</string>
+ <string name="action_undo">ਵਾਪਸ ਲਵੋ</string>
+ <string name="action_redo">ਫੇਰ ਕਰੋ</string>
+ <string name="save_document">ਸੰਭਾਲੋ</string>
+ <string name="action_cancel">ਰੱਦ ਕਰੋ</string>
+ <string name="no_save_document">ਨਹੀਂ</string>
+ <string name="action_presentation">ਸਲਾਈਡ ਸ਼ੋਅ</string>
+ <string name="slideshow_action_back">ਪਿੱਛੇ</string>
+ <string name="calc_insert_before">ਸ਼ਾਮਲ ਕਰੋ</string>
+ <string name="calc_delete">ਹਟਾਓ</string>
+ <string name="calc_hide">ਓਹਲੇ</string>
+ <string name="calc_show">ਵੇਖਾਓ</string>
+ <string name="calc_adjust_length">ਲੰਬਾਈ ਅਡਜੱਸਟ ਕਰੋ</string>
+ <string name="calc_adjust_height">ਉਚਾਈ ਅਡਜੱਸਟ ਕਰੋ</string>
+ <string name="calc_adjust_width">ਚੌੜਾਈ ਅਡਜੱਸਟ ਕਰੋ</string>
+ <string name="calc_optimal_width">ਚੌੜਾਈ ਅਨੁਕੂਲ ਕਰੋ</string>
+ <string name="calc_optimal_length_confirm">ਠੀਕ ਹੈ</string>
+ <string name="action_add_worksheet">ਵਰਕਸ਼ੀਟ ਜੋੜੋ</string>
+ <string name="action_pwd_dialog_OK">ਠੀਕ ਹੈ</string>
+ <string name="action_pwd_dialog_cancel">ਰੱਦ ਕਰੋ</string>
+ <string name="action_pwd_dialog_title">ਪਾਸਵਰਡ ਦਿਓ</string>
+ <string name="select_photo_title">ਤਸਵੀਰ ਚੁਣੋ</string>
+ <string name="no_camera_found">ਕੋਈ ਕੈਮਰਾ ਨਹੀਂ ਲੱਭਿਆ</string>
+ <string name="compress_photo_smallest_size">ਸਭ ਤੋਂ ਛੋਟਾ ਆਕਾਰ</string>
+ <string name="compress_photo_max_quality">ਵੱਧ ਤੋਂ ਵੱਧ ਕੁਆਲਟੀ</string>
+ <string name="compress_photo_no_compress">ਕੰਪਰੈਸ ਨਾ ਕਰੋ</string>
+ <string name="action_copy">ਕਾਪੀ ਕਰੋ</string>
+ <string name="action_paste">ਚੇਪੋ</string>
+ <string name="action_cut">ਕੱਟੋ</string>
+ <string name="action_back">ਪਿੱਛੇ</string>
+ <string name="insert_table">ਸਾਰਣੀ ਸ਼ਾਮਲ ਕਰੋ</string>
+ <string name="select_insert_options">ਸ਼ਾਮਲ ਕਰਨ ਦੀਆਂ ਚੋਣਾਂ ਚੁਣੋ:</string>
+ <string name="select_delete_options">ਹਟਾਉਣ ਦੀਆਂ ਚੋਣਾਂ ਚੁਣੋ:</string>
+ <string name="action_delete_worksheet">ਵਰਕਸ਼ੀਟ ਹਟਾਓ</string>
+ <string name="action_delete_slide">ਸਲਾਈਡ ਨੂੰ ਹਟਾਓ</string>
+ <string name="action_exportToPDF">PDF ਵਜੋਂ ਐਕਸਪੋਰਟ ਕਰੋ</string>
+ <string name="action_print">ਛਾਪੋ</string>
+ <string name="tabhost_character">ਅੱਖਰ</string>
+ <string name="tabhost_paragraph">ਪ੍ਹੈਰਾ</string>
+ <string name="tabhost_insert">ਸ਼ਾਮਲ ਕਰੋ</string>
+ <string name="alert_ok">ਠੀਕ ਹੈ</string>
+ <string name="alert_cancel">ਰੱਦ ਕਰੋ</string>
+ <string name="display_language_summary">ਮੂਲ ਦਿਖਾਉਣ ਵਾਲੀ ਭਾਸ਼ਾ ਵਜੋਂ ਸੈੱਟ ਕਰੋ</string>
+ <string name="about_privacy_policy">ਪਰਦੇਦਾਰੀ ਨੀਤੀ</string>
+ <string name="default_document_name">ਬਿਨਾਂ-ਨਾਂ</string>
+ <string name="select_photo">ਫੋਟੋ ਚੁਣੋ</string>
+ <string name="unable_to_export_pdf">PDF ਵਜੋਂ ਐਕਸਪੋਰਟ ਕਰਨ ਲਈ ਅਸਮਰੱਥ</string>
+ <string name="error">ਗਲਤੀ</string>
+ <string name="enter_part_name">ਭਾਗ ਦਾ ਨਾਂ ਦਿਓ</string>
+ <string name="page">ਸਫ਼ਾ</string>
+ <string name="sheet">ਸ਼ੀਟ</string>
+ <string name="slide">ਸਲਾਈਡ</string>
+ <string name="part">ਹਿੱਸਾ</string>
+ <string name="highlight_color">ਉਭਾਰਨ ਲਈ ਰੰਗ</string>
+ <string name="font_color">ਫ਼ੋਂਟ ਦਾ ਰੰਗ</string>
+ <string name="automatic">ਆਪਣੇ-ਆਪ</string>
+ <string name="app_name">LibreOffice ਦਰਸ਼ਕ</string>
+ <string name="app_name_settings">LibreOffice ਦਰਸ਼ਕ ਸੈਟਿੰਗਾਂ</string>
+ <string name="app_version">ਵਰਜ਼ਨ: %1$s&lt;br&gt;ਬਿਲਡ ID: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="search_find_next">ਅੱਗੇ ਲੱਭੋ</string>
+ <string name="pref_experimental_editing_summary">ਤਜਰਬੇ ਅਧੀਨ ਸੋਧ ਢੰਗ ਨੂੰ ਸਮਰੱਥ ਕਰੋ। ਇਸ ਨੂੰ ਆਪਣੀ ਜੁੰਮੇਵਾਰੀ ਉੱਤੇ ਵਰਤੋਂ।</string>
+ <string name="search_find_previous">ਪਿੱਛੇ ਲੱਭੋ</string>
+ <string name="file_icon_desc">ਫਾਈਲ-ਆਈਕਾਨ</string>
+ <string name="message_saving">…ਦਸਤਾਵੇਜ਼ ਸੰਭਾਲਿਆ ਜਾ ਰਿਹਾ ਹੈ</string>
+ <string name="save_alert_dialog_title">ਕੀ ਬੰਦ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਦਸਤਾਵੇਜ਼ ਨੂੰ ਸੰਭਾਲਣਾ ਹੈ\?</string>
+ <string name="action_text_copied">ਲਿਖਤ ਨੂੰ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਕਾਪੀ ਗਿਆ</string>
+ <string name="action_add_slide">ਸਲਾਈਡ ਜੋੜੋ</string>
+ <string name="take_photo">ਫੋਟੋ ਲਵੋ</string>
+ <string name="action_rename_worksheet">ਵਰਕਸ਼ੀਟ ਦਾ ਨਾਂ ਬਦਲੋ</string>
+ <string name="tabhost_style">ਸਟਾਈਲ</string>
+ <string name="display_language">ਦਿਖਾਉਣ ਲਈ ਭਾਸ਼ਾ</string>
+ <string name="pdf_export_finished">PDF ਐਕਸਪੋਰਟ ਕਰਨਾ ਪੂਰਾ ਹੋਇਆ</string>
+ <string name="unable_to_save">ਫਾਈਲ ਸੰਭਾਲਣ ਲਈ ਅਸਮਰੱਥ</string>
+ <string name="action_rename_slide">ਸਲਾਈਡ ਦਾ ਨਾਂ ਬਦਲੋ</string>
+ <string name="calc_optimal_length">ਅਨੁਕੂਲ ਲੰਬਾਈ</string>
+ <string name="calc_optimal_height">ਉਚਾਈ ਅਨੁਕੂਲ ਕਰੋ</string>
+ <string name="compress_photo_title">ਕੀ ਤੁਸੀਂ ਫੋਟੋ ਨੂੰ ਕੰਪਰੈੱਸ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ\?</string>
+ <string name="action_UNO_commands">UNO ਕਮਾਂਡ ਭੇਜੋ</string>
+ <string name="UNO_commands_string_hint">UNO ਕਮਾਂਡ</string>
+ <string name="UNO_commands_string_type_hint">ਕਿਸਮ</string>
+ <string name="UNO_commands_string_value_hint">ਮੁੱਲ</string>
+ <string name="UNO_commands_string_parent_value_hint">ਮੁੱਢਲਾ ਮੁੱਲ</string>
+ <string name="current_uno_command">ਮੌਜੂਦਾ UNO ਕਮਾਂਡ</string>
+ <string name="name_already_used">ਦਿੱਤਾ ਨਾਂ ਪਹਿਲਾਂ ਹੀ ਵਰਤਿਆ ਗਿਆ ਹੈ।</string>
+ <string name="part_name_changed">ਪਾਰਟ ਦਾ ਨਾਂ ਬਦਲਿਆ ਜਾ ਚੁੱਕਾ ਹੈ।</string>
+ <string name="part_deleted">ਪਾਰਟ ਨੂੰ ਹਟਾਇਆ ਜਾ ਚੁੱਕਾ ਹੈ।</string>
+ <string name="bmp_null">bmp ਨਲ ਹੈ!</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-pl/strings.xml b/android/source/res/values-pl/strings.xml
new file mode 100644
index 000000000000..01cb0a597d89
--- /dev/null
+++ b/android/source/res/values-pl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="about_license">Pokaż licencję</string>
+ <string name="pref_experimental_editing_summary">Włącz eksperymentalny tryb edycji. Używaj na własne ryzyko.</string>
+ <string name="action_rename_slide">Zmień nazwę slajdu</string>
+ <string name="calc_optimal_height">Optymalna wysokość</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="app_description">LibreOffice Viewer to przeglądarka dokumentów oparta na LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="about_privacy_policy">Polityka prywatności</string>
+ <string name="create_file">Utwórz nowy plik</string>
+ <string name="new_textdocument">Nowy dokument tekstowy</string>
+ <string name="new_presentation">Nowa prezentacja</string>
+ <string name="new_spreadsheet">Nowy arkusz kalkulacyjny</string>
+ <string name="new_drawing">Nowy rysunek</string>
+ <string name="about_notice">Pokaż uwagi</string>
+ <string name="select_file_to_open">Wybierz plik do otwarcia</string>
+ <string name="search_find_previous">Znajdź poprzednie</string>
+ <string name="file_icon_desc">ikona pliku</string>
+ <string name="title_recents">Ostatnie pliki</string>
+ <string name="title_browser">Wszystkie pliki</string>
+ <string name="pref_category_general">Ogólne</string>
+ <string name="pref_experimental_editing">Tryb eksperymentalny</string>
+ <string name="pref_developer_mode">Tryb programisty</string>
+ <string name="pref_developer_mode_summary">Włącz tryb programisty, w którym możesz wysyłać polecenia UNO w aplikacji. Używaj na własne ryzyko.</string>
+ <string name="action_parts">Części</string>
+ <string name="action_settings">Ustawienia</string>
+ <string name="action_keyboard">Pokaż klawiaturę</string>
+ <string name="action_about">O aplikacji</string>
+ <string name="action_fromat">Włącz formatowanie</string>
+ <string name="action_search">Szukaj</string>
+ <string name="action_UNO_commands">Wyślij polecenie UNO</string>
+ <string name="message_saved">Zapisywanie ukończone</string>
+ <string name="message_saving">Zapisywanie dokumentu…</string>
+ <string name="message_saving_failed">Zapisanie dokumentu nie powiodło się.</string>
+ <string name="password">Hasło</string>
+ <string name="action_undo">Cofnij</string>
+ <string name="action_redo">Ponów</string>
+ <string name="save_alert_dialog_title">Zapisać dokument przed zamknięciem\?</string>
+ <string name="save_document">ZAPISZ</string>
+ <string name="action_cancel">Anuluj</string>
+ <string name="no_save_document">NIE</string>
+ <string name="action_add_slide">Dodaj slajd</string>
+ <string name="slideshow_action_back">Wstecz</string>
+ <string name="calc_insert_before">Wstaw</string>
+ <string name="calc_hide">Ukryj</string>
+ <string name="calc_show">Pokaż</string>
+ <string name="calc_adjust_length">Dostosuj długość</string>
+ <string name="calc_adjust_height">Dostosuj wysokość</string>
+ <string name="calc_optimal_length">Optymalna długość</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="action_add_worksheet">Dodaj arkusz</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="action_pwd_dialog_cancel">Anuluj</string>
+ <string name="take_photo">Zrób zdjęcie</string>
+ <string name="select_photo">Wybierz zdjęcie</string>
+ <string name="select_photo_title">Wybierz obraz</string>
+ <string name="no_camera_found">Nie znaleziono aparatu</string>
+ <string name="compress_photo_smallest_size">Najmniejszy rozmiar</string>
+ <string name="compress_photo_medium_size">Średni rozmiar</string>
+ <string name="compress_photo_max_quality">Maksymalna jakość</string>
+ <string name="compress_photo_no_compress">Nie kompresuj</string>
+ <string name="compress_photo_title">Czy chcesz skompresować zdjęcie\?</string>
+ <string name="action_copy">Kopiuj</string>
+ <string name="calc_optimal_length_default_text">Wpisz dodatkową długość w setnych/mm</string>
+ <string name="action_pwd_dialog_title">Wpisz hasło</string>
+ <string name="action_cut">Wytnij</string>
+ <string name="action_back">Wstecz</string>
+ <string name="insert_table">Wstaw tabelę</string>
+ <string name="select_insert_options">Wybierz opcje wstawiania:</string>
+ <string name="select_delete_options">Wybierz opcje usuwania:</string>
+ <string name="action_rename_worksheet">Zmień nazwę arkusza</string>
+ <string name="action_delete_worksheet">Usuń arkusz</string>
+ <string name="action_delete_slide">Usuń slajd</string>
+ <string name="name_already_used">Podana nazwa jest już używana.</string>
+ <string name="part_name_changed">Nazwa części została zmieniona.</string>
+ <string name="UNO_commands_string_hint">Polecenie UNO</string>
+ <string name="UNO_commands_string_type_hint">Typ</string>
+ <string name="UNO_commands_string_parent_value_hint">Wartość nadrzędna</string>
+ <string name="action_exportToPDF">Eksportuj do PDF</string>
+ <string name="action_print">Drukuj</string>
+ <string name="tabhost_character">Znak</string>
+ <string name="tabhost_paragraph">Akapit</string>
+ <string name="tabhost_insert">Wstaw</string>
+ <string name="tabhost_style">Styl</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Anuluj</string>
+ <string name="display_language_summary">Ustaw domyślny język wyświetlania</string>
+ <string name="display_language">Język wyświetlania</string>
+ <string name="pdf_export_finished">Zakończono eksport do PDF</string>
+ <string name="unable_to_export_pdf">Nie można wyeksportować do PDF</string>
+ <string name="unable_to_save">Nie można zapisać pliku</string>
+ <string name="error">Błąd</string>
+ <string name="bmp_null">BMP jest zerowy!</string>
+ <string name="page">Strona</string>
+ <string name="sheet">Arkusz</string>
+ <string name="slide">Slajd</string>
+ <string name="part">Część</string>
+ <string name="highlight_color">Kolor wyróżnienia</string>
+ <string name="font_color">Kolor czcionki</string>
+ <string name="app_vendor">To wydanie zostało dostarczone przez $VENDOR.</string>
+ <string name="action_save_as">Zapisz jako…</string>
+ <string name="action_presentation">Pokaz slajdów</string>
+ <string name="calc_delete">Usuń</string>
+ <string name="part_deleted">Część została usunięta.</string>
+ <string name="current_uno_command">Aktualne polecenie UNO</string>
+ <string name="enter_part_name">Wpisz nazwę części</string>
+ <string name="calc_optimal_width">Optymalna szerokość</string>
+ <string name="app_name_settings">Ustawienia LibreOffice Viewer</string>
+ <string name="app_version">Wersja: %1$s&lt;br&gt;Identyfikator kompilacji: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="readonly_file">Ten plik jest tylko do odczytu.</string>
+ <string name="default_document_name">Bez tytułu</string>
+ <string name="search_find_next">Znajdź następne</string>
+ <string name="action_save">Zapisz</string>
+ <string name="calc_adjust_width">Dostosuj szerokość</string>
+ <string name="UNO_commands_string_value_hint">Wartość</string>
+ <string name="calc_alert_double_click_optimal_length">Wskazówka: dwukrotne stuknięcie nagłówka ustawia optymalną szerokość/wysokość.</string>
+ <string name="action_paste">Wklej</string>
+ <string name="action_text_copied">Tekst skopiowano do schowka</string>
+ <string name="automatic">Automatyczny</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-pt-rBR/strings.xml b/android/source/res/values-pt-rBR/strings.xml
new file mode 100644
index 000000000000..36045ea672e9
--- /dev/null
+++ b/android/source/res/values-pt-rBR/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Leitor de LibreOffice</string>
+ <string name="app_name_settings">Configuração do leitor de LibreOffice</string>
+ <string name="app_description">Esta aplicação é um leitor de documentos baseado no LibreOffice.</string>
+ <string name="app_credits">https://pt-br.libreoffice.org</string>
+ <string name="app_vendor">Esta versão foi fornecida por $VENDOR.</string>
+ <string name="readonly_file">Este arquivo é somente leitura.</string>
+ <string name="about_license">Mostrar Licença</string>
+ <string name="about_notice">Mostar aviso</string>
+ <string name="new_textdocument">Novo documento de texto</string>
+ <string name="new_presentation">Nova apersentação</string>
+ <string name="new_spreadsheet">Nova planilha</string>
+ <string name="new_drawing">Novo desenho</string>
+ <string name="default_document_name">Sem título</string>
+ <string name="file_icon_desc">Ícone de arquivo</string>
+ <string name="title_recents">Arquivos recentes</string>
+ <string name="title_browser">Todos os arquivos</string>
+ <string name="pref_category_general">Geral</string>
+ <string name="pref_experimental_editing">Modo experimental</string>
+ <string name="pref_developer_mode">Modo de desenvolvimento</string>
+ <string name="app_version">Versão: %1$s&lt;br&gt;ID da montagem: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="select_file_to_open">Selecione o arquivo a abrir</string>
+ <string name="pref_experimental_editing_summary">Ativar o modo de edição experimental. Use por sua conta e risco.</string>
+ <string name="pref_developer_mode_summary">Ativar o modo de desenvolvedor para enviar comandos UNO dentro da aplicação. Use por sua conta e risco.</string>
+ <string name="message_saving">Salvando o arquivo…</string>
+ <string name="action_about">Sobre</string>
+ <string name="action_parts">Partes</string>
+ <string name="action_settings">Confirgurações</string>
+ <string name="action_keyboard">Mostrar teclado</string>
+ <string name="action_save">Salvar</string>
+ <string name="action_save_as">Salvar como…</string>
+ <string name="action_fromat">Ativar formato</string>
+ <string name="action_search">Pesquisar</string>
+ <string name="action_UNO_commands">Enviar comando UNO</string>
+ <string name="message_saved">Arquivo salvo</string>
+ <string name="message_saving_failed">Não foi possível salvar o documento.</string>
+ <string name="about_privacy_policy">Política de privacidade</string>
+ <string name="create_file">Criar um arquivo</string>
+ <string name="search_find_next">Localizar próxima</string>
+ <string name="search_find_previous">Localizar anterior</string>
+ <string name="password">Senha</string>
+ <string name="action_undo">Desfazer</string>
+ <string name="action_redo">Refazer</string>
+ <string name="save_document">SALVAR</string>
+ <string name="action_cancel">Cancelar</string>
+ <string name="no_save_document">NÃO</string>
+ <string name="action_presentation">Apresentação de slides</string>
+ <string name="action_add_slide">Adicionar slide</string>
+ <string name="slideshow_action_back">Voltar</string>
+ <string name="calc_insert_before">Inserir</string>
+ <string name="calc_delete">Excluir</string>
+ <string name="calc_hide">Ocultar</string>
+ <string name="calc_show">Mostrar</string>
+ <string name="calc_optimal_length">Tamanho ideal</string>
+ <string name="calc_adjust_length">Ajustar tamanho</string>
+ <string name="calc_adjust_height">Ajustar altura</string>
+ <string name="calc_adjust_width">Ajustar largura</string>
+ <string name="calc_optimal_height">Altura ideal</string>
+ <string name="calc_optimal_width">Largura ideal</string>
+ <string name="calc_optimal_length_confirm">OK</string>
+ <string name="save_alert_dialog_title">Salvar documento antes de fechar\?</string>
+ <string name="action_add_worksheet">Adicionar planilha</string>
+ <string name="action_pwd_dialog_OK">OK</string>
+ <string name="calc_optimal_length_default_text">Insira o comprimento extra em centésimos de milímetro.</string>
+ <string name="calc_alert_double_click_optimal_length">Dica: tocar duas vezes no cabeçalho define a altura/largura ideal.</string>
+ <string name="part_name_changed">O nome da parte foi alterado.</string>
+ <string name="action_pwd_dialog_cancel">Cancelar</string>
+ <string name="action_pwd_dialog_title">Digite a senha</string>
+ <string name="take_photo">Fotografar</string>
+ <string name="select_photo">Selecionar foto</string>
+ <string name="select_photo_title">Selecionar figura</string>
+ <string name="no_camera_found">Sem câmera disponível</string>
+ <string name="compress_photo_smallest_size">Menor tamanho</string>
+ <string name="compress_photo_medium_size">Tamanho médio</string>
+ <string name="compress_photo_max_quality">Qualidade máxima</string>
+ <string name="compress_photo_no_compress">Não comprimir</string>
+ <string name="compress_photo_title">Deseja comprimir a foto\?</string>
+ <string name="action_copy">Copiar</string>
+ <string name="action_paste">Colar</string>
+ <string name="action_cut">Cortar</string>
+ <string name="action_back">Voltar</string>
+ <string name="action_text_copied">Teto copiado para área de transferência</string>
+ <string name="insert_table">Inserir tabela</string>
+ <string name="select_insert_options">Selecionar opções para inserir:</string>
+ <string name="select_delete_options">Selecionar opções para excluir:</string>
+ <string name="action_rename_worksheet">Renomear planilha</string>
+ <string name="action_delete_worksheet">Excluir planilha</string>
+ <string name="action_delete_slide">Excluir slide</string>
+ <string name="name_already_used">O nome já existe.</string>
+ <string name="part_deleted">A parte foi excluída.</string>
+ <string name="UNO_commands_string_hint">Comando UNO</string>
+ <string name="UNO_commands_string_type_hint">Tipo</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor superior</string>
+ <string name="action_exportToPDF">Exportar em PDF</string>
+ <string name="action_print">Imprimir</string>
+ <string name="tabhost_character">Caractere</string>
+ <string name="tabhost_paragraph">Parágrafo</string>
+ <string name="tabhost_insert">Inserir</string>
+ <string name="tabhost_style">Estilo</string>
+ <string name="alert_ok">OK</string>
+ <string name="alert_cancel">Cancelar</string>
+ <string name="current_uno_command">Comando UNO atual</string>
+ <string name="display_language">Exibir idioma</string>
+ <string name="display_language_summary">Definir o idioma padrão de exibição</string>
+ <string name="unable_to_export_pdf">Não foi possível exportar em PDF</string>
+ <string name="error">Erro</string>
+ <string name="enter_part_name">Digite um nome para a parte</string>
+ <string name="bmp_null">Bmp é nulo!</string>
+ <string name="page">Página</string>
+ <string name="sheet">Planilha</string>
+ <string name="slide">Slide</string>
+ <string name="part">Parte</string>
+ <string name="highlight_color">Cor de destaque</string>
+ <string name="font_color">Cor da fonte</string>
+ <string name="automatic">Automático</string>
+ <string name="pdf_export_finished">Exportação em PDF terminada</string>
+ <string name="unable_to_save">Não foi possível salvar o arquivo</string>
+ <string name="action_rename_slide">Renomear slide</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-pt/strings.xml b/android/source/res/values-pt/strings.xml
new file mode 100644
index 000000000000..018fb3e8c575
--- /dev/null
+++ b/android/source/res/values-pt/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="pdf_export_finished">Exportação PDF terminada</string>
+ <string name="pref_developer_mode_summary">Ativa o modo de desenvolvedor para enviar comandos UNO na aplicação. Use por sua conta e risco.</string>
+ <string name="app_description">O visualizador LibreOffice é baseado no LibreOffice.</string>
+ <string name="calc_show">Mostrar</string>
+ <string name="pref_developer_mode">Modo de desenvolvimento</string>
+ <string name="action_pwd_dialog_cancel">Cancelar</string>
+ <string name="create_file">Criar novo ficheiro</string>
+ <string name="slide">Diapositivo</string>
+ <string name="part_name_changed">Parte do nome foi alterado.</string>
+ <string name="compress_photo_max_quality">Qualidade máxima</string>
+ <string name="calc_hide">Ocultar</string>
+ <string name="action_UNO_commands">Enviar comando UNO</string>
+ <string name="default_document_name">sem nome</string>
+ <string name="action_about">Acerca</string>
+ <string name="action_fromat">Ativar formato</string>
+ <string name="password">Palavra-passe</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="select_insert_options">Selecione as opções de inserção:</string>
+ <string name="UNO_commands_string_type_hint">Tipo</string>
+ <string name="current_uno_command">Comando UNO atual</string>
+ <string name="slideshow_action_back">Recuar</string>
+ <string name="bmp_null">Bmp é nulo!</string>
+ <string name="action_paste">Colar</string>
+ <string name="action_pwd_dialog_OK">Aceitar</string>
+ <string name="save_document">Guardar</string>
+ <string name="calc_adjust_length">Ajustar tamanho</string>
+ <string name="new_spreadsheet">Nova folha de cálculo</string>
+ <string name="part">Parte</string>
+ <string name="select_file_to_open">Selecione o ficheiro a abrir</string>
+ <string name="unable_to_export_pdf">Não foi possível exportar para PDF</string>
+ <string name="action_save_as">Guardar como…</string>
+ <string name="save_alert_dialog_title">Guardar documento antes de fechar\?</string>
+ <string name="font_color">Cor do tipo de letra</string>
+ <string name="action_rename_worksheet">Mudar nome da folha</string>
+ <string name="message_saving_failed">Não foi possível guardar o documento.</string>
+ <string name="calc_optimal_length">Tamanho ideal</string>
+ <string name="enter_part_name">Introduza um nome</string>
+ <string name="new_drawing">Novo desenho</string>
+ <string name="automatic">Automático</string>
+ <string name="action_delete_slide">Eliminar diapositivo</string>
+ <string name="action_redo">Refazer</string>
+ <string name="action_cut">Cortar</string>
+ <string name="file_icon_desc">ícone</string>
+ <string name="title_recents">Recentes</string>
+ <string name="page">Página</string>
+ <string name="calc_insert_before">Inserir</string>
+ <string name="calc_optimal_length_default_text">Introduza o comprimento extra em centésimos de milímetro.</string>
+ <string name="message_saving">A guardar…</string>
+ <string name="tabhost_style">Estilo</string>
+ <string name="select_photo_title">Selecionar imagem</string>
+ <string name="calc_optimal_width">Largura ideal</string>
+ <string name="action_delete_worksheet">Eliminar folha</string>
+ <string name="no_save_document">Não</string>
+ <string name="highlight_color">Cor de destaque</string>
+ <string name="new_textdocument">Novo documento de texto</string>
+ <string name="action_print">Imprimir</string>
+ <string name="calc_adjust_width">Ajustar largura</string>
+ <string name="action_add_worksheet">Adicionar folha</string>
+ <string name="new_presentation">Nova apresentação</string>
+ <string name="tabhost_paragraph">Parágrafo</string>
+ <string name="action_back">Recuar</string>
+ <string name="pref_experimental_editing">Modo experimental</string>
+ <string name="calc_delete">Eliminar</string>
+ <string name="part_deleted">A parte foi eliminada.</string>
+ <string name="action_undo">Desfazer</string>
+ <string name="app_vendor">Esta versão foi disponibilizada por $VENDOR.</string>
+ <string name="action_pwd_dialog_title">Introduza a palavra-passe</string>
+ <string name="calc_optimal_length_confirm">Aceitar</string>
+ <string name="action_parts">Partes</string>
+ <string name="compress_photo_medium_size">Tamanho médio</string>
+ <string name="display_language_summary">Defina o idioma de exibição padrão</string>
+ <string name="select_delete_options">Selecione as opções de eliminação:</string>
+ <string name="pref_category_general">Geral</string>
+ <string name="action_text_copied">Teto copiado para a área de transferência</string>
+ <string name="action_exportToPDF">Exportar para PDF</string>
+ <string name="action_rename_slide">Mudar nome do diapositivo</string>
+ <string name="action_keyboard">Mostrar teclado</string>
+ <string name="about_privacy_policy">Política de privacidade</string>
+ <string name="action_presentation">Apresentação</string>
+ <string name="UNO_commands_string_parent_value_hint">Valor superior</string>
+ <string name="compress_photo_smallest_size">Menor tamanho</string>
+ <string name="select_photo">Selecionar foto</string>
+ <string name="compress_photo_no_compress">Não comprimir</string>
+ <string name="action_copy">Copiar</string>
+ <string name="tabhost_insert">Inserir</string>
+ <string name="action_search">Pesquisar</string>
+ <string name="message_saved">Guardado</string>
+ <string name="no_camera_found">Câmara não encontrada</string>
+ <string name="error">Erro</string>
+ <string name="app_name_settings">Definições</string>
+ <string name="name_already_used">Este nome já está a ser utilizado.</string>
+ <string name="action_save">Guardar</string>
+ <string name="UNO_commands_string_hint">Comando UNO</string>
+ <string name="alert_ok">Aceitar</string>
+ <string name="UNO_commands_string_value_hint">Valor</string>
+ <string name="action_settings">Definições</string>
+ <string name="sheet">Folha</string>
+ <string name="compress_photo_title">Deseja comprimir a foto\?</string>
+ <string name="app_version">Versão: %1$s&lt;br&gt;ID da compilação: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_license">Mostrar licença</string>
+ <string name="title_browser">Todos os ficheiros</string>
+ <string name="take_photo">Obter foto</string>
+ <string name="unable_to_save">Não foi possível guardar o ficheiro</string>
+ <string name="app_name">Visualizador LibreOffice</string>
+ <string name="insert_table">Inserir tabela</string>
+ <string name="action_add_slide">Adicionar diapositivo</string>
+ <string name="action_cancel">Cancelar</string>
+ <string name="calc_adjust_height">Ajustar altura</string>
+ <string name="display_language">Idioma de exibição</string>
+ <string name="search_find_next">Localizar seguinte</string>
+ <string name="search_find_previous">Localizar anterior</string>
+ <string name="pref_experimental_editing_summary">Ativar o modo de edição experimental. Use por sua conta e risco.</string>
+ <string name="readonly_file">Este ficheiro é apenas de leitura.</string>
+ <string name="about_notice">Mostar aviso</string>
+ <string name="alert_cancel">Cancelar</string>
+ <string name="calc_optimal_height">Altura ideal</string>
+ <string name="tabhost_character">Carácter</string>
+ <string name="calc_alert_double_click_optimal_length">Dica: dois toques no cabeçalho define a altura/largura ideal.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-sk/strings.xml b/android/source/res/values-sk/strings.xml
new file mode 100644
index 000000000000..b83ec58936b9
--- /dev/null
+++ b/android/source/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_description">LibreOffice Viewer je prehliadač dokumentov založený na LibreOffice.</string>
+ <string name="default_document_name">bez názvu</string>
+ <string name="action_about">Info</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="new_spreadsheet">Nový tabuľkový dokument</string>
+ <string name="select_file_to_open">Vyberte súbor, ktorý chcete otvoriť</string>
+ <string name="new_drawing">Nová kresba</string>
+ <string name="title_recents">Posledné súbory</string>
+ <string name="new_textdocument">Nový textový dokument</string>
+ <string name="new_presentation">Nová prezentácia</string>
+ <string name="app_vendor">Dodávateľom tohto produktu je $VENDOR.</string>
+ <string name="pref_category_general">Všeobecné</string>
+ <string name="app_name_settings">Nastavenia LibreOffice Viewer</string>
+ <string name="app_version">Verzia: %1$s&lt;br&gt;ID zostavenia: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="about_license">Zobraziť licenciu</string>
+ <string name="title_browser">Všetky súbory</string>
+ <string name="app_name">LibreOffice Viewer</string>
+ <string name="readonly_file">Táto súbor je len na čítanie.</string>
+ <string name="about_notice">Zobraziť oznam</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-sl/strings.xml b/android/source/res/values-sl/strings.xml
new file mode 100644
index 000000000000..f245e39bb429
--- /dev/null
+++ b/android/source/res/values-sl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name_settings">Nastavitve Pregledovalnika LibreOffice</string>
+ <string name="app_version">Različica: %1$s&lt;br&gt;ID gradnje: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">Pregledovalnik LibreOffice je pregledovalnik dokumentov, zasnovan na LibreOffice.</string>
+ <string name="app_credits">https://sl.libreoffice.org</string>
+ <string name="readonly_file">Ta datoteka je samo za branje.</string>
+ <string name="about_license">Pokaži dovoljenje</string>
+ <string name="new_drawing">Nova risba</string>
+ <string name="create_file">Ustvari novo datoteko</string>
+ <string name="new_presentation">Nova predstavitev</string>
+ <string name="new_spreadsheet">Nova preglednica</string>
+ <string name="default_document_name">neimenovano</string>
+ <string name="new_textdocument">Nov besedilni dokument</string>
+ <string name="about_notice">Pokaži obvestilo</string>
+ <string name="about_privacy_policy">Politika zasebnosti</string>
+ <string name="title_browser">Vse datoteke</string>
+ <string name="pref_experimental_editing">Poskusni način</string>
+ <string name="action_save">Shrani</string>
+ <string name="action_settings">Nastavitve</string>
+ <string name="title_recents">Nedavne datoteke</string>
+ <string name="message_saved">Shranjevanje dokončano</string>
+ <string name="action_save_as">Shrani kot …</string>
+ <string name="action_about">O programu</string>
+ <string name="pref_developer_mode">Razvijalski način</string>
+ <string name="action_keyboard">Pokaži tipkovnico</string>
+ <string name="message_saving_failed">Shranjevanje dokumenta je spodletelo.</string>
+ <string name="action_parts">Deli</string>
+ <string name="action_UNO_commands">Pošlji ukaz UNO</string>
+ <string name="file_icon_desc">Ikona datoteke</string>
+ <string name="action_search">Išči</string>
+ <string name="action_fromat">Omogoči oblikovanje</string>
+ <string name="pref_developer_mode_summary">Omogočite način za razvijalce, v katerem lahko v aplikaciji pošiljate ukaze UNO. Uporabljajte na lastno odgovornost.</string>
+ <string name="search_find_next">Najdi naslednje</string>
+ <string name="search_find_previous">Najdi prejšnje</string>
+ <string name="action_add_slide">Dodaj prosojnico</string>
+ <string name="action_cancel">Prekliči</string>
+ <string name="calc_delete">Izbriši</string>
+ <string name="action_undo">Razveljavi</string>
+ <string name="action_redo">Uveljavi</string>
+ <string name="save_document">SHRANI</string>
+ <string name="action_presentation">Projekcija</string>
+ <string name="slideshow_action_back">Nazaj</string>
+ <string name="no_save_document">NE</string>
+ <string name="calc_show">Pokaži</string>
+ <string name="calc_hide">Skrij</string>
+ <string name="action_pwd_dialog_OK">V redu</string>
+ <string name="action_pwd_dialog_cancel">Prekliči</string>
+ <string name="calc_adjust_length">Prilagodi dolžino</string>
+ <string name="calc_adjust_height">Prilagodi višino</string>
+ <string name="calc_adjust_width">Prilagodi širino</string>
+ <string name="calc_optimal_height">Optimalna višina</string>
+ <string name="calc_optimal_width">Optimalna širina</string>
+ <string name="select_photo_title">Izberite sliko</string>
+ <string name="no_camera_found">Kamere ni mogoče najti</string>
+ <string name="action_add_worksheet">Dodaj delovni list</string>
+ <string name="calc_optimal_length_default_text">Vnesite dodatno dolžino v stotinah/mm</string>
+ <string name="action_pwd_dialog_title">Vnesite geslo</string>
+ <string name="take_photo">Naredi fotografijo</string>
+ <string name="select_photo">Izberite fotografijo</string>
+ <string name="action_paste">Prilepi</string>
+ <string name="UNO_commands_string_value_hint">Vrednost</string>
+ <string name="alert_ok">V redu</string>
+ <string name="error">Napaka</string>
+ <string name="tabhost_paragraph">Odstavek</string>
+ <string name="tabhost_insert">Vstavi</string>
+ <string name="alert_cancel">Prekliči</string>
+ <string name="page">Stran</string>
+ <string name="sheet">Delovni list</string>
+ <string name="slide">Prosojnica</string>
+ <string name="insert_table">Vstavi tabelo</string>
+ <string name="action_delete_slide">Izbriši prosojnico</string>
+ <string name="action_cut">Izreži</string>
+ <string name="UNO_commands_string_type_hint">Vrsta</string>
+ <string name="tabhost_style">Slog</string>
+ <string name="display_language">Prikaži jezik</string>
+ <string name="current_uno_command">Trenutni ukaz UNO</string>
+ <string name="action_back">Nazaj</string>
+ <string name="action_print">Natisni</string>
+ <string name="tabhost_character">Znak</string>
+ <string name="compress_photo_medium_size">Srednja velikost</string>
+ <string name="compress_photo_max_quality">Najvišja kakovost</string>
+ <string name="compress_photo_no_compress">Ne stisni</string>
+ <string name="action_rename_worksheet">Preimenuj delovni list</string>
+ <string name="action_delete_worksheet">Izbriši delovni list</string>
+ <string name="compress_photo_smallest_size">Najmanjša velikost</string>
+ <string name="part_deleted">Del je bil izbrisan.</string>
+ <string name="part_name_changed">Ime dela je bilo spremenjeno.</string>
+ <string name="name_already_used">Dano ime je že v rabi.</string>
+ <string name="select_insert_options">Izberite možnosti vstavljanja:</string>
+ <string name="select_delete_options">Izberite možnosti brisanja:</string>
+ <string name="enter_part_name">Vnesite ime dela</string>
+ <string name="display_language_summary">Določite privzeti jezik za prikaz</string>
+ <string name="pdf_export_finished">Izvoz v PDF je dokončan</string>
+ <string name="unable_to_export_pdf">Izvoz v PDF ni možen</string>
+ <string name="unable_to_save">Datoteke ni mogoče shraniti</string>
+ <string name="part">Del</string>
+ <string name="UNO_commands_string_parent_value_hint">Nadrejena vrednost</string>
+ <string name="bmp_null">Bmp je ničen!</string>
+ <string name="font_color">Barva pisave</string>
+ <string name="automatic">Samodejno</string>
+ <string name="action_rename_slide">Preimenuj prosojnico</string>
+ <string name="highlight_color">Barva poudarjanja</string>
+ <string name="app_name">Pregledovalnik LibreOffice</string>
+ <string name="app_vendor">Ta izdelek je dal na voljo $VENDOR.</string>
+ <string name="pref_category_general">Splošno</string>
+ <string name="UNO_commands_string_hint">Ukaz UNO</string>
+ <string name="message_saving">Shranjevanje dokumenta …</string>
+ <string name="calc_optimal_length">Optimalna dolžina</string>
+ <string name="compress_photo_title">Ali želite stisniti fotografijo\?</string>
+ <string name="password">Geslo</string>
+ <string name="action_copy">Kopiraj</string>
+ <string name="calc_insert_before">Vstavi</string>
+ <string name="calc_optimal_length_confirm">V redu</string>
+ <string name="pref_experimental_editing_summary">Omogočite poskusni način urejanja. Uporabljajte na lastno odgovornost.</string>
+ <string name="action_exportToPDF">Izvozi v PDF</string>
+ <string name="select_file_to_open">Izberite datoteko, ki jo želite odpreti.</string>
+ <string name="save_alert_dialog_title">Ali želite shraniti dokument pred zapiranjem\?</string>
+ <string name="action_text_copied">Besedilo je kopirano v odložišče</string>
+ <string name="calc_alert_double_click_optimal_length">Namig: dvakrat tapnite glavo, da nastavite optimalno širino/višino.</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-tr/strings.xml b/android/source/res/values-tr/strings.xml
index 3bada4ded6be..d981956e988b 100644
--- a/android/source/res/values-tr/strings.xml
+++ b/android/source/res/values-tr/strings.xml
@@ -1,149 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
-
<string name="app_name">LibreOffice Görüntüleyici</string>
<string name="app_name_settings">LibreOffice Görüntüleyici Ayarları</string>
-
- <string name="app_about_name"><b>LibreOffice Görüntüleyici \'Beta\'</b></string>
- <string name="app_version">Versiyon: %1$s\nBuild ID: %2$s</string>
+ <string name="app_version">Versiyon: %1$s&lt;br&gt;Build ID: &lt;a href="https://hub.libreoffice.org/git-core/%2$s"&gt;%2$s&lt;/a&gt;</string>
<string name="app_description">LibreOffice Görüntüleyici LibreOffice tabanlı bir belge görüntüleyicisidir.</string>
<string name="app_credits">https://www.libreoffice.org</string>
<string name="app_vendor">Bu sürüm $VENDOR tarafından derlenmiştir.</string>
- <string name="temp_file_saving_disabled">Bu dosya salt okunabilir haldedir. Kaydetme devredışı.</string>
-
+ <string name="readonly_file">Bu dosya salt okunabilir haldedir.</string>
<string name="about_license">Lisansı Görüntüle</string>
<string name="about_notice">Bildiriyi Görüntüle</string>
- <string name="about_moreinfo">Daha Fazla Bilgi</string>
- <string name="back_again_to_quit">Çıkış için geri tuşuna tekrar basınız.</string>
-
<string name="new_textdocument">Yeni Kelime İşlemci</string>
<string name="new_presentation">Yeni Sunum</string>
<string name="new_spreadsheet">Yeni Hesap Tablosu</string>
<string name="new_drawing">Yeni Çizim</string>
<string name="default_document_name">adsız</string>
-
- <string name="browser_app_name">LibreOffice Tarayıcı</string>
- <string name="menu_search">Ara</string>
- <string name="list_view">Liste</string>
- <string name="grid_view">Grid</string>
- <string name="filter">Şununla filtrele:</string>
- <string name="search_not_found">Söz dizimi bulunamadı.</string>
- <string name="sort">Şununla sırala:</string>
- <string name="sort_smallest">Küçükten büyüğe</string>
- <string name="sort_largest">Büyükten küçüğe</string>
- <string name="sort_az">A-Z</string>
- <string name="sort_za">Z-A</string>
- <string name="sort_oldest">Eskiden yeniye</string>
- <string name="sort_newest">Yeniden eskiye</string>
- <string name="menu_sort_size">Boyuta Göre Sırala</string>
- <string name="menu_sort_az">Alfabetik Sırala</string>
- <string name="menu_sort_modified">Tarihe Göre Sırala</string>
- <string name="menu_preferences">Seçenekler</string>
<string name="file_icon_desc">dosya_simgesi</string>
<string name="title_recents">Son açılan dosyalar</string>
<string name="title_browser">Tüm dosyalar</string>
- <!-- Pref keys as resources ; Not currently used -->
- <string name="EXPLORER_VIEW_TYPE_KEY">EXPLORER_VIEW_TYPE</string>
- <string name="CURRENT_DIRECTORY_KEY">CURRENT_DIRECTORY</string>
- <string name="pref_category_explorer">Dosya Gezgini Ayarları</string>
<string name="pref_category_general">Genel</string>
<string name="pref_experimental_editing">Deneysel Mod</string>
<string name="pref_experimental_editing_summary">Deneysel düzenleme modunu etkinleştirin. Kullanım riski size aittir.</string>
- <string name="pref_show_hidden_files">Gizli Dosyalar ve Dizinler</string>
- <string name="pref_show_hidden_files_summary">Gizli dosyalar ve dizinleri göstermeyi etkinleştir.</string>
<string name="pref_developer_mode">Geliştirici Modu</string>
<string name="pref_developer_mode_summary">Geliştirici modunu etkinleştirerek UNO komutları gönderin. Kullanım riski size aittir.</string>
-
<string name="action_about">Hakkında</string>
<string name="action_parts">Bölümler</string>
<string name="action_settings">Ayarlar</string>
- <string name="open">Aç</string>
- <string name="share">Paylaş</string>
- <string name="share_via">Şununla paylaş</string>
-
- <!-- Document browser filters -->
- <string name="filter_everything">Hepsi</string>
- <string name="filter_documents">Kelime İşlemci</string>
- <string name="filter_spreadsheets">Hesap Tablosu</string>
- <string name="filter_presentations">Sunum</string>
- <string name="filter_drawings">Çizimler</string>
-
- <!-- Document provider names -->
- <string name="document_locations">Belge dizinleri</string>
- <string name="close_document_locations">Belge dizinlerini kapat</string>
- <string name="local_documents">Belgeler</string>
- <string name="local_file_system">Yerel dosya sistemi</string>
- <string name="external_sd_file_system">Harici SD</string>
- <string name="otg_file_system">OTG cihazı (deneysel)</string>
- <string name="owncloud">Uzak sunucu</string>
- <string name="usb_connected_configure">USB bağlantısı yapıldı, cihazınızın ayarlarını yapınız.</string>
-
- <string name="owncloud_wrong_connection">ownCloud sunucusuna bağlanılamadı. Ayarlarınızı kontrol ediniz.</string>
- <string name="owncloud_unauthorized">ownCloud sunucusuna giriş yapılamadı. Ayarlarınızı kontrol ediniz.</string>
- <string name="owncloud_unspecified_error">ownCloud sunucusuna bağlanırken belirtilmemiş bir hata oluştu. Lütfen daha sonra tekrar deneyiniz veya ayarlarınızı kontrol ediniz.</string>
-
- <string name="ext_document_provider_error">Geçersiz dizin. SD kart ayarlarınızı kontrol ediniz.</string>
- <string name="legacy_extsd_missing_error">Geçersiz dizin. SD kartınızı veya SD kart ayarlarınızı kontrol ediniz.</string>
- <string name="otg_missing_error">Geçersiz dizin. OTG cihazınızı veya OTG cihazı ayarlarınızı kontrol ediniz.</string>
-
<!-- Edit action names -->
- <string name="action_bold">Kalın</string>
- <string name="action_underline">Altı çizgili</string>
- <string name="action_italic">Yana yatık</string>
- <string name="action_strikeout">Üzeri çizgili</string>
<string name="action_keyboard">Klaveyi göster</string>
<string name="action_save">Kaydet</string>
<string name="action_fromat">Biçimlendirmeyi etkinleştir.</string>
<string name="action_search">Ara</string>
<string name="action_UNO_commands">UNO komutu yolla</string>
-
<!-- Feedback messages -->
<string name="message_saved">Kaydetme tamamlandı.</string>
<string name="message_saving">Belge kaydediliyor…</string>
- <string name="message_save_incomplete">Kayıt tamamlanmadı. Değişiklik yapıldı mı?</string>
- <string name="create_new_file_success">"Yeni dosya oluşturuldu - "</string>
- <string name="create_new_file_error">Yeni dosya oluşturma başarısız. Lütfen dosya ismini kontrol ediniz.</string>
-
- <!-- Document provider settings -->
- <string name="storage_provider_settings">Depolama sağlayıcısı ayarları</string>
- <string name="owncloud_settings">ownCloud ayarları</string>
- <string name="physical_storage_settings">Fiziksel depolama ayarları</string>
- <string name="external_sd_path">Harici SD yolu</string>
- <string name="otg_device_path">OTG cihazı yolu</string>
- <string name="otg_warning">Deneysel özellik: OTG cihazı yazılabilir ise kullanın</string>
- <string name="server_url">Sunucu URL</string>
- <string name="server_url_and_port">ownCloud sunucusu URL ve port</string>
- <string name="user_name">Kullanıcı Adı</string>
<string name="password">Parola</string>
<string name="action_undo">Geri Al</string>
<string name="action_redo">Yinele</string>
-
- <!-- Directory browser strings -->
- <string name="up_description">Üst dizin</string>
- <string name="confirm_label">Onayla</string>
- <string name="cancel_label">İptal</string>
- <string name="search_label">Git</string>
- <string name="directory_browser_label">Dizin Seç</string>
- <string name="bad_directory">Geçersiz dizin</string>
- <string name="current_dir">Şuan ki dizin: %1$s</string>
-
<!-- Save Alert dialog strings -->
<string name="save_alert_dialog_title">Değişiklikleri kaydetmek istiyor musunuz?</string>
<string name="save_document">Kaydet</string>
<string name="action_cancel">İptal</string>
<string name="no_save_document">Hayır</string>
-
- <!-- Create New Document Dialog Strings -->
- <string name="create_new_document_title">Dosya ismi girin</string>
- <string name="action_create">OLUŞTUR</string>
-
<!-- Presentation Mode Strings -->
<string name="action_presentation">Slayt Gösterisi</string>
<string name="action_add_slide">Slayt Ekle</string>
- <string name="alert_copy_svg_slide_show_to_clipboard">Cihazınız uygulama içi slayt gösterisini desteklemiyor. Sunumu panoya kopyaladık. Lütfen ev tuşuna basıp modern bir tarayıcı açıp arama çubuğuna yapıştırın ve sunumu görüntüleyin.</string>
- <string name="alert_copy_svg_slide_show_to_clipboard_dismiss">Tamam</string>
<string name="slideshow_action_back">Geri</string>
-
<!-- Calc Header Menu Strings -->
<string name="calc_insert_before">Ekle</string>
<string name="calc_delete">Sil</string>
@@ -159,12 +61,10 @@
<string name="calc_optimal_length_default_text">Extra uzunluk giriniz: 100th/mm</string>
<string name="calc_alert_double_click_optimal_length">İpucu: Başlığa çift dokunuş en iyi uzunluk ve genişliği ayarlar.</string>
<string name="action_add_worksheet">Hesap Tablosu Ekle</string>
-
<!-- Password dialog strings -->
<string name="action_pwd_dialog_OK">Tamam</string>
<string name="action_pwd_dialog_cancel">İptal</string>
<string name="action_pwd_dialog_title">Lütfen parola giriniz.</string>
-
<!-- Insert Image Strings -->
<string name="take_photo">Fotoğraf Çek</string>
<string name="select_photo">Fotoğraf Seç</string>
@@ -175,7 +75,6 @@
<string name="compress_photo_max_quality">Maksimum Kalite</string>
<string name="compress_photo_no_compress">Sıkıştırma yapma</string>
<string name="compress_photo_title">Fotoğrafı sıkıştırmak ister misiniz?</string>
-
<!-- Clipboard Actions -->
<string name="action_copy">Kopyala</string>
<string name="action_paste">Yapıştır</string>
@@ -203,7 +102,6 @@
<item>Sütun Sil</item>
<item>Tablo Sil</item>
</string-array>
-
<!-- UNO cmd controller Strings -->
<string name="UNO_commands_string_hint">UNO Komutu</string>
<string name="UNO_commands_string_type_hint">Tip</string>
@@ -217,23 +115,13 @@
<string name="tabhost_style">Biçim</string>
<string name="alert_ok">Tamam</string>
<string name="alert_cancel">İptal</string>
- <string name="unable_to_go_further">Daha fazla ilerlenemiyor.</string>
<string name="current_uno_command">Şuan ki UNO komutu</string>
- <string name="pref_sort_summary">Dosyaların nasıl sıralanacağını seçiniz. A-Z, Z-A ya da boyuta göre.</string>
- <string name="pref_viewmode_summary">Dosyaları grid veya liste şeklinde görüntüle.</string>
- <string name="pref_file_explorer_title">Dosya Gezgini</string>
- <string name="pref_sort_title">Dosya Sıralaması</string>
- <string name="pref_filter_title">Varsayılan Dosya Filtrelemesi</string>
- <string name="pref_filter_summary">Varsayılan dosya filtrelemesini seç</string>
<string name="display_language">Uygulama Dili</string>
<string name="display_language_summary">Varsayılan dili değiştir</string>
<string name="unable_to_export_pdf">Pdf dışa aktarılamıyor.</string>
- <string name="pdf_exported_at">Şu konumda pdf\'e aktarıldı: </string>
- <string name="printing_not_supported">Cihazınız yazdırmayı desteklemiyor.</string>
<string name="error">Hata</string>
<string name="enter_part_name">Bölüm ismi girin.</string>
<string name="bmp_null">Bmp boş!</string>
- <string name="directory_not_saved">Dizin kaydedilmedi.</string>
<string name="page">Sayfa</string>
<string name="sheet">Tablo</string>
<string name="slide">Slayt</string>
@@ -241,4 +129,14 @@
<string name="highlight_color">Vurgulama Rengi</string>
<string name="font_color">Metin Rengi</string>
<string name="action_rename_slide">Slaytı yeniden adlandır</string>
-</resources>
+ <string name="about_privacy_policy">Gizlilik Politikası</string>
+ <string name="action_save_as">Farklı Kaydet…</string>
+ <string name="automatic">Otomatik</string>
+ <string name="create_file">Yeni Dosya Oluştur</string>
+ <string name="search_find_next">Sonrakini Bul</string>
+ <string name="search_find_previous">Öncekini Bul</string>
+ <string name="pdf_export_finished">PDF dışa aktarıldı</string>
+ <string name="unable_to_save">Dosya kaydedilemiyor</string>
+ <string name="message_saving_failed">Belge kaydedilemedi.</string>
+ <string name="select_file_to_open">Açılacak dosyayı seçin</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-uk/strings.xml b/android/source/res/values-uk/strings.xml
new file mode 100644
index 000000000000..e6048cc3dff0
--- /dev/null
+++ b/android/source/res/values-uk/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">Оглядач LibreOffice</string>
+ <string name="app_description">Оглядач LibreOffice - це програма, яка може відкривати документи LibreOffice.</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">Цей випуск постачає $VENDOR.</string>
+ <string name="readonly_file">Цей файл лише для читання.</string>
+ <string name="about_license">Показати ліцензію</string>
+ <string name="about_notice">Показати Примітки</string>
+ <string name="new_presentation">Нова презентація</string>
+ <string name="new_spreadsheet">Нова електронна таблиця</string>
+ <string name="new_drawing">Новий рисунок</string>
+ <string name="default_document_name">без назви</string>
+ <string name="select_file_to_open">Оберіть файл для відкриття</string>
+ <string name="file_icon_desc">піктограма</string>
+ <string name="create_file">Створити новий файл</string>
+ <string name="search_find_next">Знайти наступне</string>
+ <string name="search_find_previous">Знайти попереднє</string>
+ <string name="title_browser">Всі файли</string>
+ <string name="pref_category_general">Загальне</string>
+ <string name="pref_developer_mode">Режим розробника</string>
+ <string name="pref_developer_mode_summary">Активувати режим розробника, де у межах додатка можна надсилати команди UNO. Використовуйте на власний ризик.</string>
+ <string name="action_about">Про програму</string>
+ <string name="action_parts">Частини</string>
+ <string name="action_settings">Параметри</string>
+ <string name="action_save">Зберегти</string>
+ <string name="action_fromat">Увімкнути форматування</string>
+ <string name="action_search">Пошук</string>
+ <string name="action_UNO_commands">Надіслати кмд UNO</string>
+ <string name="message_saved">Збережено</string>
+ <string name="message_saving">Запис документа…</string>
+ <string name="password">Пароль</string>
+ <string name="action_undo">Відміна</string>
+ <string name="action_redo">Повтор</string>
+ <string name="save_alert_dialog_title">Зберегти документ перед закриттям\?</string>
+ <string name="save_document">Зберегти</string>
+ <string name="action_cancel">Відмовитись</string>
+ <string name="no_save_document">НІ</string>
+ <string name="action_presentation">Слайд-шоу</string>
+ <string name="action_add_slide">Додати слайд</string>
+ <string name="slideshow_action_back">Назад</string>
+ <string name="calc_delete">Вилучити</string>
+ <string name="calc_hide">Приховати</string>
+ <string name="calc_show">Показати</string>
+ <string name="calc_optimal_length">Оптимальна довжина</string>
+ <string name="calc_adjust_length">Припасувати довжину</string>
+ <string name="calc_adjust_height">Припасувати висоту</string>
+ <string name="calc_adjust_width">Припасувати ширину</string>
+ <string name="calc_optimal_width">Оптимальна ширина</string>
+ <string name="calc_optimal_length_confirm">ОК</string>
+ <string name="action_add_worksheet">Додати робочий аркуш</string>
+ <string name="action_pwd_dialog_OK">ОК</string>
+ <string name="action_pwd_dialog_cancel">Відмовитись</string>
+ <string name="action_pwd_dialog_title">Введіть пароль</string>
+ <string name="take_photo">Зробити фото</string>
+ <string name="select_photo">Обрати фото</string>
+ <string name="select_photo_title">Обрати зображення</string>
+ <string name="no_camera_found">Камера не знайдена</string>
+ <string name="compress_photo_smallest_size">Найменший розмір</string>
+ <string name="compress_photo_medium_size">Середній розмір</string>
+ <string name="compress_photo_max_quality">Макс. якість</string>
+ <string name="compress_photo_no_compress">Не стискати</string>
+ <string name="compress_photo_title">Бажаєте стиснути фото\?</string>
+ <string name="action_copy">Копіювати</string>
+ <string name="action_cut">Вирізати</string>
+ <string name="action_text_copied">Текст скопійовано до буфера</string>
+ <string name="insert_table">Вставити таблицю</string>
+ <string name="select_delete_options">Оберіть параметри видалення:</string>
+ <string name="action_rename_worksheet">Перейменувати аркуш</string>
+ <string name="action_delete_worksheet">Вилучити аркуш</string>
+ <string name="action_delete_slide">Вилучити слайд</string>
+ <string name="part_name_changed">Частину назви змінено.</string>
+ <string name="part_deleted">Частину видалено.</string>
+ <string name="UNO_commands_string_hint">Команда UNO</string>
+ <string name="UNO_commands_string_type_hint">Тип</string>
+ <string name="UNO_commands_string_value_hint">Значення</string>
+ <string name="UNO_commands_string_parent_value_hint">Значення батьківського елемента</string>
+ <string name="action_exportToPDF">Експортувати в PDF</string>
+ <string name="tabhost_paragraph">Абзац</string>
+ <string name="tabhost_insert">Вставити</string>
+ <string name="tabhost_style">Стиль</string>
+ <string name="alert_ok">ОК</string>
+ <string name="alert_cancel">Відміна</string>
+ <string name="current_uno_command">Поточна команда UNO</string>
+ <string name="display_language">Мова на екрані</string>
+ <string name="pdf_export_finished">Експорт до PDF завершено</string>
+ <string name="unable_to_export_pdf">Неможливо експортувати в PDF</string>
+ <string name="unable_to_save">Неможливо зберегти файл</string>
+ <string name="error">Помилка</string>
+ <string name="enter_part_name">Введіть частину назви</string>
+ <string name="page">Сторінка</string>
+ <string name="sheet">Аркуш</string>
+ <string name="slide">Слайд</string>
+ <string name="part">Частина</string>
+ <string name="highlight_color">Колір виділення</string>
+ <string name="font_color">Колір шрифта</string>
+ <string name="action_rename_slide">Перейменувати слайд</string>
+ <string name="automatic">Автоматично</string>
+ <string name="app_version">Версія: %1$s&lt;br&gt;ID збірки: &lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_name_settings">Налаштування Оглядача LibreOffice</string>
+ <string name="new_textdocument">Новий текстовий документ</string>
+ <string name="title_recents">Попередні файли</string>
+ <string name="about_privacy_policy">Політика приватності</string>
+ <string name="action_save_as">Зберегти як…</string>
+ <string name="calc_optimal_height">Оптимальна висота</string>
+ <string name="name_already_used">Така назва вже використовується.</string>
+ <string name="select_insert_options">Оберіть параметри вставки:</string>
+ <string name="pref_experimental_editing">Експериментальний режим</string>
+ <string name="calc_optimal_length_default_text">Введіть додаткову довжину у 100th/мм</string>
+ <string name="action_paste">Вставити</string>
+ <string name="pref_experimental_editing_summary">Активуйте експериментальний режим редагування. Використовуйте на власний ризик.</string>
+ <string name="action_keyboard">Показати клавіатуру</string>
+ <string name="message_saving_failed">Запис документа перервано.</string>
+ <string name="calc_insert_before">Вставити</string>
+ <string name="calc_alert_double_click_optimal_length">Підказка: подвійний тиць на заголовку встановлює оптимальну ширину/висоту.</string>
+ <string name="action_back">Назад</string>
+ <string name="action_print">Друк</string>
+ <string name="tabhost_character">Символ</string>
+ <string name="display_language_summary">Встановити типову мову</string>
+ <string name="bmp_null">Bmp має нульове значення!</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values-zh-rTW/strings.xml b/android/source/res/values-zh-rTW/strings.xml
new file mode 100644
index 000000000000..60de641f125e
--- /dev/null
+++ b/android/source/res/values-zh-rTW/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">LibreOffice 檢視器</string>
+ <string name="app_name_settings">LibreOffice 檢視器設定</string>
+ <string name="app_version">版本:%1$s&lt;br&gt;建置 ID:&lt;a href=https://hub.libreoffice.org/git-core/%2$s&gt;%2$s&lt;/a&gt;</string>
+ <string name="app_description">LibreOffice 檢視器是以 LibreOffice 為基礎開發的文件檢視器。</string>
+ <string name="app_credits">https://www.libreoffice.org</string>
+ <string name="app_vendor">此版本由 $VENDOR 提供。</string>
+ <string name="readonly_file">此檔案唯讀。</string>
+ <string name="about_license">顯示授權條款</string>
+ <string name="action_keyboard">顯示鍵盤</string>
+ <string name="action_save">儲存</string>
+ <string name="action_fromat">啟用格式</string>
+ <string name="action_search">搜尋</string>
+ <string name="action_UNO_commands">傳送 UNO 命令</string>
+ <string name="message_saved">儲存完成</string>
+ <string name="message_saving">正在儲存文件……</string>
+ <string name="message_saving_failed">儲存文件失敗。</string>
+ <string name="no_camera_found">找不到相機</string>
+ <string name="compress_photo_smallest_size">最小大小</string>
+ <string name="select_photo">選取照片</string>
+ <string name="select_photo_title">選取圖片</string>
+ <string name="compress_photo_medium_size">中等大小</string>
+ <string name="compress_photo_max_quality">最高品質</string>
+ <string name="compress_photo_no_compress">不要壓縮</string>
+ <string name="action_rename_worksheet">重新命名工作表</string>
+ <string name="select_delete_options">選取刪除選項:</string>
+ <string name="action_delete_worksheet">刪除工作表</string>
+ <string name="action_delete_slide">刪除投影片</string>
+ <string name="name_already_used">指定名稱已被使用。</string>
+ <string name="part_name_changed">部份名稱已變更。</string>
+ <string name="part_deleted">部份已刪除。</string>
+ <string name="current_uno_command">目前 UNO 命令</string>
+ <string name="error">錯誤</string>
+ <string name="alert_cancel">取消</string>
+ <string name="action_save_as">另存為……</string>
+ <string name="about_privacy_policy">隱私權政策</string>
+ <string name="create_file">建立新檔案</string>
+ <string name="new_textdocument">新文字文件</string>
+ <string name="new_presentation">新簡報</string>
+ <string name="new_spreadsheet">新試算表</string>
+ <string name="new_drawing">新繪圖</string>
+ <string name="default_document_name">無題</string>
+ <string name="search_find_next">尋找下一個</string>
+ <string name="search_find_previous">尋找上一個</string>
+ <string name="file_icon_desc">檔案圖示</string>
+ <string name="title_recents">最近檔案</string>
+ <string name="title_browser">所有檔案</string>
+ <string name="pref_category_general">一般</string>
+ <string name="pref_experimental_editing">實驗性模式</string>
+ <string name="pref_developer_mode">開發者模式</string>
+ <string name="pref_developer_mode_summary">啟用開發者模式,您可以在應用程式內傳送 UNO 命令。使用風險自負。</string>
+ <string name="action_about">關於</string>
+ <string name="action_parts">部份</string>
+ <string name="action_settings">設定</string>
+ <string name="password">密碼</string>
+ <string name="action_undo">取消動作</string>
+ <string name="action_redo">再次動作</string>
+ <string name="save_alert_dialog_title">關閉前儲存文件?</string>
+ <string name="save_document">儲存</string>
+ <string name="action_cancel">取消</string>
+ <string name="action_add_slide">新增投影片</string>
+ <string name="slideshow_action_back">返回</string>
+ <string name="calc_insert_before">插入</string>
+ <string name="calc_delete">刪除</string>
+ <string name="calc_hide">隱藏</string>
+ <string name="calc_show">顯示</string>
+ <string name="calc_adjust_height">調整高度</string>
+ <string name="calc_adjust_width">調整寬度</string>
+ <string name="calc_adjust_length">調整長度</string>
+ <string name="calc_optimal_length">最適長度</string>
+ <string name="calc_optimal_height">最適高度</string>
+ <string name="calc_optimal_width">最適寬度</string>
+ <string name="calc_optimal_length_confirm">確定</string>
+ <string name="calc_alert_double_click_optimal_length">提示:輕點標題列兩次可以設定最適寬度/高度。</string>
+ <string name="action_add_worksheet">新增工作表</string>
+ <string name="action_pwd_dialog_OK">確定</string>
+ <string name="action_pwd_dialog_cancel">取消</string>
+ <string name="action_pwd_dialog_title">請輸入密碼</string>
+ <string name="take_photo">拍照</string>
+ <string name="compress_photo_title">您想要壓縮照片嗎?</string>
+ <string name="action_copy">複製</string>
+ <string name="action_paste">貼上</string>
+ <string name="action_cut">剪下</string>
+ <string name="action_back">返回</string>
+ <string name="action_text_copied">文字已複製到剪貼簿</string>
+ <string name="insert_table">插入表格</string>
+ <string name="select_insert_options">選取插入選項:</string>
+ <string name="UNO_commands_string_hint">UNO 命令</string>
+ <string name="UNO_commands_string_type_hint">類型</string>
+ <string name="UNO_commands_string_value_hint">值</string>
+ <string name="UNO_commands_string_parent_value_hint">上層值</string>
+ <string name="action_exportToPDF">匯出為 PDF</string>
+ <string name="action_print">列印</string>
+ <string name="tabhost_character">字元</string>
+ <string name="tabhost_paragraph">段落</string>
+ <string name="tabhost_insert">插入</string>
+ <string name="tabhost_style">樣式</string>
+ <string name="alert_ok">確定</string>
+ <string name="display_language">顯示語言</string>
+ <string name="pdf_export_finished">PDF 匯出結束</string>
+ <string name="unable_to_export_pdf">無法匯出為 PDF</string>
+ <string name="unable_to_save">無法儲存檔案</string>
+ <string name="enter_part_name">輸入部份名稱</string>
+ <string name="bmp_null">Bmp 為空!</string>
+ <string name="page">頁面</string>
+ <string name="sheet">工作表</string>
+ <string name="slide">投影片</string>
+ <string name="part">部份</string>
+ <string name="highlight_color">標明色彩</string>
+ <string name="font_color">字型色彩</string>
+ <string name="action_rename_slide">重新命名投影片</string>
+ <string name="automatic">自動</string>
+ <string name="select_file_to_open">選取要開啟的檔案</string>
+ <string name="about_notice">顯示注意事項</string>
+ <string name="no_save_document">否</string>
+ <string name="display_language_summary">設定預設顯示語言</string>
+ <string name="pref_experimental_editing_summary">啟用實驗性編輯模式。使用風險自負。</string>
+ <string name="calc_optimal_length_default_text">輸入額外長度(以 100th/mm 為單位)</string>
+ <string name="action_presentation">投影片放映</string>
+</resources> \ No newline at end of file
diff --git a/android/source/res/values/arrays.xml b/android/source/res/values/arrays.xml
index edea6443b419..832bca781572 100644
--- a/android/source/res/values/arrays.xml
+++ b/android/source/res/values/arrays.xml
@@ -1,62 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <integer-array name="FilterTypeValues">
- <item >-1</item>
- <item >0</item>
- <item >1</item>
- <item >2</item>
- </integer-array>
- <string-array name="FilterTypeStringValues">
- <item >-1</item>
- <item >0</item>
- <item >1</item>
- <item >2</item>
- <item >3</item>
- </string-array>
<string-array name="SupportedLanguagesValues">
<item>SYSTEM_DEFAULT_LANGUAGE</item>
<item >de</item>
<item >en</item>
<item >tr</item>
</string-array>
- <string-array name="SortModeStringValues">
- <item >0</item>
- <item >1</item>
- <item >2</item>
- <item >3</item>
- <item >4</item>
- <item >5</item>
- </string-array>
- <!-- View Mode names,values -->
- <string-array name="ViewModeNames">
- <item >@string/grid_view</item>
- <item >@string/list_view</item>
- </string-array>
- <string-array name="ViewModeStringValues">
- <item >0</item>
- <item >1</item>
- </string-array>
- <string-array name="FilterTypeNames">
- <item>@string/filter_everything</item>
- <item>@string/filter_documents</item>
- <item>@string/filter_spreadsheets</item>
- <item>@string/filter_presentations</item>
- <item>@string/filter_drawings</item>
- </string-array>
<string-array name="SupportedLanguages">
<item>(System Default)</item>
<item>Deutsch</item>
<item>English</item>
<item>Turkçe</item>
</string-array>
- <string-array name="SortModeNames">
- <item >@string/sort_az</item>
- <item >@string/sort_za</item>
- <item >@string/sort_oldest</item>
- <item >@string/sort_newest</item>
- <item >@string/sort_largest</item>
- <item >@string/sort_smallest</item>
- </string-array>
-
-
</resources>
diff --git a/android/source/res/values/colors.xml b/android/source/res/values/colors.xml
index 3defb9a3ea83..4642a2b8f1c1 100644
--- a/android/source/res/values/colors.xml
+++ b/android/source/res/values/colors.xml
@@ -4,6 +4,11 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources>
+
+ <!-- "?attr/colorBackgroundFloating" could be used directly instead for API level >= 23,
+ but current minimum API level is lower. Overridden for dark theme in values-night/color.xml. -->
+ <color name="background_floating">@color/background_floating_material_light</color>
+
<color name="background_light">#FAFAFA</color> <!--Material Grey 50-->
<color name="background_normal">#F5F5F5</color> <!--Material Grey 100-->
<color name="background_private">#FF292C29</color>
@@ -93,7 +98,6 @@
<color name="panel_grid_item_image_background">#D1D9E1</color>
<color name="toolbar_foreground">#3e3e3e</color>
- <color name="toolbar_background">#ffffff</color>
<color name="handle_color">#26a69a</color>
diff --git a/android/source/res/values/dimens.xml b/android/source/res/values/dimens.xml
index ca91a2f30a1f..8753fad07101 100644
--- a/android/source/res/values/dimens.xml
+++ b/android/source/res/values/dimens.xml
@@ -11,7 +11,6 @@
<dimen name="toolbar_height">256dp</dimen>
<dimen name="calc_header_width">48dp</dimen>
<dimen name="calc_header_height">24dp</dimen>
- <dimen name="calc_toolbar_height">40dp</dimen>
<dimen name="calc_address_bar_width">96dp</dimen>
<dimen name="new_doc_fab_tweak_top">-11dp</dimen>
<dimen name="new_doc_fab_tweak_bottom">-7dp</dimen>
diff --git a/android/source/res/values/integers.xml b/android/source/res/values/integers.xml
deleted file mode 100644
index aeb71c3997d1..000000000000
--- a/android/source/res/values/integers.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
- <integer name="grid_view_integer">0</integer>
-
-</resources> \ No newline at end of file
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index 3669d0a2ed90..3766db146098 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -4,95 +4,44 @@
<string name="app_name">LibreOffice Viewer</string>
<string name="app_name_settings">LibreOffice Viewer Settings</string>
- <string name="app_about_name"><b>LibreOffice Viewer \'Beta\'</b></string>
- <string name="app_version">Version: %1$s\nBuild ID: %2$s</string>
+ <string name="app_version">Version: %1$s&lt;br&gt;Build ID: &lt;a href=&quot;https://hub.libreoffice.org/git-core/%2$s&quot;&gt;%2$s&lt;/a&gt;</string>
<string name="app_description">LibreOffice Viewer is a document viewer based on LibreOffice.</string>
<string name="app_credits">https://www.libreoffice.org</string>
<string name="app_vendor">This release was supplied by $VENDOR.</string>
- <string name="temp_file_saving_disabled">This file is read-only, saving is disabled.</string>
+ <string name="readonly_file">This file is read-only.</string>
<string name="about_license">Show License</string>
<string name="about_notice">Show Notice</string>
- <string name="about_moreinfo">More Info</string>
- <string name="back_again_to_quit">Press back again to quit</string>
+ <string name="about_privacy_policy">Privacy Policy</string>
+ <string name="create_file">Create New File</string>
<string name="new_textdocument">New Text Document</string>
<string name="new_presentation">New Presentation</string>
<string name="new_spreadsheet">New Spreadsheet</string>
<string name="new_drawing">New Drawing</string>
<string name="default_document_name">untitled</string>
- <string name="browser_app_name">LibreOffice Browser</string>
- <string name="menu_search">Search</string>
- <string name="list_view">List</string>
- <string name="grid_view">Grid</string>
- <string name="filter">Filter by</string>
- <string name="search_not_found">Keyword not found</string>
- <string name="sort">Sort by</string>
- <string name="sort_smallest">Smallest first</string>
- <string name="sort_largest">Largest first</string>
- <string name="sort_az">A-Z</string>
- <string name="sort_za">Z-A</string>
- <string name="sort_oldest">Oldest first</string>
- <string name="sort_newest">Newest first</string>
- <string name="menu_sort_size">Sort By Size</string>
- <string name="menu_sort_az">Sort A-Z</string>
- <string name="menu_sort_modified">Sort by Date</string>
- <string name="menu_preferences">Preferences</string>
+ <string name="select_file_to_open">Select file to open</string>
+
+ <string name="search_find_next">Find Next</string>
+ <string name="search_find_previous">Find Previous</string>
<string name="file_icon_desc">fileicon</string>
<string name="title_recents">Recent files</string>
<string name="title_browser">All files</string>
- <!-- Pref keys as resources ; Not currently used -->
- <string name="EXPLORER_VIEW_TYPE_KEY">EXPLORER_VIEW_TYPE</string>
- <string name="CURRENT_DIRECTORY_KEY">CURRENT_DIRECTORY</string>
- <string name="pref_category_explorer">File Explorer Settings</string>
<string name="pref_category_general">General</string>
<string name="pref_experimental_editing">Experimental Mode</string>
<string name="pref_experimental_editing_summary">Enable the experimental editing mode. Use at your own risk.</string>
- <string name="pref_show_hidden_files">Hidden Files/Folders</string>
- <string name="pref_show_hidden_files_summary">Enable to show hidden files/folders</string>
<string name="pref_developer_mode">Developer Mode</string>
<string name="pref_developer_mode_summary">Enable developer mode where you can send UNO commands within app. Use at your own risk.</string>
<string name="action_about">About</string>
<string name="action_parts">Parts</string>
<string name="action_settings">Settings</string>
- <string name="open">Open</string>
- <string name="share">Share</string>
- <string name="share_via">Share via</string>
-
- <!-- Document browser filters -->
- <string name="filter_everything">Everything</string>
- <string name="filter_documents">Documents</string>
- <string name="filter_spreadsheets">Spreadsheets</string>
- <string name="filter_presentations">Presentations</string>
- <string name="filter_drawings">Drawings</string>
-
- <!-- Document provider names -->
- <string name="document_locations">Document locations</string>
- <string name="close_document_locations">Close document locations</string>
- <string name="local_documents">Documents directory</string>
- <string name="local_file_system">Local file system</string>
- <string name="external_sd_file_system">External SD</string>
- <string name="otg_file_system">OTG device (experimental)</string>
- <string name="owncloud">Remote server</string>
- <string name="usb_connected_configure">USB connected, configure your device.</string>
-
- <string name="owncloud_wrong_connection">Cannot connect to ownCloud server. Check your configuration.</string>
- <string name="owncloud_unauthorized">Cannot log into ownCloud server. Check your configuration.</string>
- <string name="owncloud_unspecified_error">Unspecified error connecting to ownCloud server. Check your configuration and/or try later.</string>
-
- <string name="ext_document_provider_error">Invalid root file. Check your sd card configuration.</string>
- <string name="legacy_extsd_missing_error">Invalid root file. Check your external sd card and/or configuration.</string>
- <string name="otg_missing_error">Invalid root file. Check your OTG device and/or configuration.</string>
<!-- Edit action names -->
- <string name="action_bold">Bold</string>
- <string name="action_underline">Underline</string>
- <string name="action_italic">Italic</string>
- <string name="action_strikeout">Strike Out</string>
<string name="action_keyboard">Show keyboard</string>
<string name="action_save">Save</string>
+ <string name="action_save_as">Save As…</string>
<string name="action_fromat">Enable Format</string>
<string name="action_search">Search</string>
<string name="action_UNO_commands">Send UNO Cmd</string>
@@ -100,48 +49,21 @@
<!-- Feedback messages -->
<string name="message_saved">Save complete</string>
<string name="message_saving">Saving the document…</string>
- <string name="message_save_incomplete">Save incomplete. Were there any changes?</string>
- <string name="create_new_file_success">"Created new file - "</string>
- <string name="create_new_file_error">Unable to create new file, please check entered file name.</string>
-
- <!-- Document provider settings -->
- <string name="storage_provider_settings">Storage provider settings</string>
- <string name="owncloud_settings">ownCloud settings</string>
- <string name="physical_storage_settings">Physical storage settings</string>
- <string name="external_sd_path">External SD path</string>
- <string name="otg_device_path">OTG device path</string>
- <string name="otg_warning">Experimental Feature: Use only if OTG device is writable.</string>
- <string name="server_url">Server URL</string>
- <string name="server_url_and_port">URL and port of the ownCloud server.</string>
- <string name="user_name">User name</string>
+ <string name="message_saving_failed">Saving the document failed.</string>
+
<string name="password">Password</string>
<string name="action_undo">Undo</string>
<string name="action_redo">Redo</string>
- <!-- Directory browser strings -->
- <string name="up_description">To parent directory</string>
- <string name="confirm_label">Confirm</string>
- <string name="cancel_label">Cancel</string>
- <string name="search_label">Go</string>
- <string name="directory_browser_label">Choose Directory</string>
- <string name="bad_directory">Invalid directory path</string>
- <string name="current_dir">Current Directory: %1$s</string>
-
<!-- Save Alert dialog strings -->
<string name="save_alert_dialog_title">Save the document before closing?</string>
<string name="save_document">SAVE</string>
<string name="action_cancel">Cancel</string>
<string name="no_save_document">NO</string>
- <!-- Create New Document Dialog Strings -->
- <string name="create_new_document_title">Enter file name</string>
- <string name="action_create">CREATE</string>
-
<!-- Presentation Mode Strings -->
<string name="action_presentation">Slide show</string>
<string name="action_add_slide">Add Slide</string>
- <string name="alert_copy_svg_slide_show_to_clipboard">Your Android device doesn\'t support in-app svg slideshow. We copied the slideshow link to clipboard. Please press home button, open a modern web browser, paste in the address bar, and go.</string>
- <string name="alert_copy_svg_slide_show_to_clipboard_dismiss">OK</string>
<string name="slideshow_action_back">Back</string>
<!-- Calc Header Menu Strings -->
@@ -217,23 +139,15 @@
<string name="tabhost_style">Style</string>
<string name="alert_ok">OK</string>
<string name="alert_cancel">Cancel</string>
- <string name="unable_to_go_further">Unable to go further.</string>
<string name="current_uno_command">Current UNO command</string>
- <string name="pref_sort_summary">Select how to order files: A-Z, by size or by date.</string>
- <string name="pref_viewmode_summary">View files as a grid or in a list.</string>
- <string name="pref_file_explorer_title">File explorer layout</string>
- <string name="pref_sort_title">File Order</string>
- <string name="pref_filter_title">Default File Filter</string>
- <string name="pref_filter_summary">Set which file filter should be used by default.</string>
<string name="display_language">Display Language</string>
<string name="display_language_summary">Set the default display language</string>
+ <string name="pdf_export_finished">PDF export finished</string>
<string name="unable_to_export_pdf">Unable to export to pdf</string>
- <string name="pdf_exported_at">Exported to PDF at</string>
- <string name="printing_not_supported">Your device does not support printing</string>
+ <string name="unable_to_save">Unable to save file</string>
<string name="error">Error</string>
<string name="enter_part_name">Enter a part name</string>
<string name="bmp_null">Bmp is null!</string>
- <string name="directory_not_saved">Directory not saved.</string>
<string name="page">Page</string>
<string name="sheet">Sheet</string>
<string name="slide">Slide</string>
@@ -241,4 +155,5 @@
<string name="highlight_color">Highlight Color</string>
<string name="font_color">Font Color</string>
<string name="action_rename_slide">Rename Slide</string>
+ <string name="automatic">Automatic</string>
</resources>
diff --git a/android/source/res/values/themes.xml b/android/source/res/values/themes.xml
index 8576f9c221ec..bf815b5c659f 100644
--- a/android/source/res/values/themes.xml
+++ b/android/source/res/values/themes.xml
@@ -2,17 +2,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="LibreOfficeTheme" parent="LibreOfficeTheme.Base"/>
- <style name="LibreOfficeTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
+ <style name="LibreOfficeTheme.Base" parent="Theme.AppCompat.DayNight.NoActionBar">
</style>
<style name="ListItemText">
<item name="android:gravity">center_vertical</item>
- <item name="android:textColor">@android:color/black</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">14sp</item>
</style>
- <style name="LibreOfficeTheme.Toolbar" parent="Theme.AppCompat.Light.NoActionBar">
- <item name="colorPrimary">@color/toolbar_background</item>
+ <style name="LibreOfficeTheme.Toolbar" parent="Theme.AppCompat.DayNight.NoActionBar">
</style>
<style name="LibreOfficeTheme.NavigationView">
diff --git a/android/source/res/xml/documentprovider_preferences.xml b/android/source/res/xml/documentprovider_preferences.xml
deleted file mode 100644
index bb5f087ddf71..000000000000
--- a/android/source/res/xml/documentprovider_preferences.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- This file is part of the LibreOffice project.
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
- -->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <PreferenceCategory
- android:title="@string/owncloud_settings"
- android:key="pref_key_owncloud_settings">
- <EditTextPreference
- android:key="pref_server_url"
- android:title="@string/server_url"
- android:summary="@string/server_url_and_port"
- android:hint="https://server:port/" />
- <EditTextPreference
- android:key="pref_user_name"
- android:title="@string/user_name" />
- <EditTextPreference
- android:key="pref_password"
- android:title="@string/password"
- android:password="true" />
- </PreferenceCategory>
- <PreferenceCategory
- android:title="@string/physical_storage_settings">
- <PreferenceScreen
- android:title="@string/external_sd_path"
- android:key="pref_extsd_path_uri">
- </PreferenceScreen>
- <PreferenceScreen
- android:title="@string/otg_device_path"
- android:key="pref_otg_path_uri"
- android:summary="@string/otg_warning">
- </PreferenceScreen>
- </PreferenceCategory>
-
-</PreferenceScreen>
diff --git a/android/source/res/xml/libreoffice_preferences.xml b/android/source/res/xml/libreoffice_preferences.xml
index d418dd559f86..052efacb2e3e 100644
--- a/android/source/res/xml/libreoffice_preferences.xml
+++ b/android/source/res/xml/libreoffice_preferences.xml
@@ -1,37 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
- android:title="@string/pref_category_explorer"
- android:key="PREF_CATEGORY_EXPLORER">
- <ListPreference
- android:title="@string/pref_filter_title"
- android:summary="@string/pref_filter_summary"
- android:entries="@array/FilterTypeNames"
- android:entryValues="@array/FilterTypeStringValues"
- android:defaultValue="-1"
- android:key="FILTER_MODE"/>
- <ListPreference
- android:summary="@string/pref_sort_summary"
- android:key="SORT_MODE"
- android:title="@string/pref_sort_title"
- android:entries="@array/SortModeNames"
- android:defaultValue="0"
- android:entryValues="@array/SortModeStringValues"/>
- <ListPreference
- android:entries="@array/ViewModeNames"
- android:entryValues="@array/ViewModeStringValues"
- android:defaultValue="@integer/grid_view_integer"
- android:title="@string/pref_file_explorer_title"
- android:key="EXPLORER_VIEW_TYPE"
- android:summary="@string/pref_viewmode_summary" />
-
- <CheckBoxPreference
- android:title="@string/pref_show_hidden_files"
- android:key="ENABLE_SHOW_HIDDEN_FILES"
- android:summary="@string/pref_show_hidden_files_summary"
- android:defaultValue="false" />
- </PreferenceCategory>
- <PreferenceCategory
android:title="@string/pref_category_general"
android:key="PREF_CATEGORY_GENERAL">
diff --git a/android/source/src/java/org/libreoffice/AboutDialogFragment.java b/android/source/src/java/org/libreoffice/AboutDialogFragment.java
index 6c944bae7ef1..0d9fc45856ef 100644
--- a/android/source/src/java/org/libreoffice/AboutDialogFragment.java
+++ b/android/source/src/java/org/libreoffice/AboutDialogFragment.java
@@ -18,21 +18,16 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.v4.app.DialogFragment;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
import android.text.Html;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.TextView;
-import java.io.File;
-
public class AboutDialogFragment extends DialogFragment {
- private static final String DEFAULT_DOC_PATH = "/assets/example.odt";
-
-
@NonNull @Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
@@ -45,66 +40,60 @@ public class AboutDialogFragment extends DialogFragment {
int defaultColor = textView.getTextColors().getDefaultColor();
textView.setTextColor(defaultColor);
- // Take care of placeholders in the version and vendor text views.
- TextView versionView = messageView.findViewById(R.id.about_version);
- TextView vendorView = messageView.findViewById(R.id.about_vendor);
+ // Take care of placeholders and set text in version and vendor text views.
try
{
String versionName = getActivity().getPackageManager()
.getPackageInfo(getActivity().getPackageName(), 0).versionName;
- String[] tokens = versionName.split("/");
- if (tokens.length == 3)
- {
- String version = String.format(versionView.getText().toString().replace("\n", "<br/>"),
- tokens[0], "<a href=\"https://hub.libreoffice.org/git-core/" + tokens[1] + "\">" + tokens[1] + "</a>");
- @SuppressWarnings("deprecation") // since 24 with additional option parameter
- Spanned versionString = Html.fromHtml(version);
- versionView.setText(versionString);
- versionView.setMovementMethod(LinkMovementMethod.getInstance());
- String vendor = vendorView.getText().toString();
- vendor = vendor.replace("$VENDOR", tokens[2]);
- vendorView.setText(vendor);
- }
- else
- throw new PackageManager.NameNotFoundException();
+ String version = String.format(getString(R.string.app_version), versionName, BuildConfig.BUILD_ID_SHORT);
+ @SuppressWarnings("deprecation") // since 24 with additional option parameter
+ Spanned versionString = Html.fromHtml(version);
+ TextView versionView = messageView.findViewById(R.id.about_version);
+ versionView.setText(versionString);
+ versionView.setMovementMethod(LinkMovementMethod.getInstance());
+ TextView vendorView = messageView.findViewById(R.id.about_vendor);
+ String vendor = getString(R.string.app_vendor).replace("$VENDOR", BuildConfig.VENDOR);
+ vendorView.setText(vendor);
}
catch (PackageManager.NameNotFoundException e)
{
- versionView.setText("");
- vendorView.setText("");
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder .setIcon(R.drawable.lo_icon)
+ builder .setIcon(R.mipmap.ic_launcher)
.setTitle(R.string.app_name)
.setView(messageView)
.setNegativeButton(R.string.about_license, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
- loadFromAbout("/assets/license.txt");
+ loadFromAbout(R.raw.license);
dialog.dismiss();
}
})
.setPositiveButton(R.string.about_notice, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
- loadFromAbout("/assets/notice.txt");
- dialog.dismiss();
- }
- })
- .setNeutralButton(R.string.about_moreinfo, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- loadFromAbout(DEFAULT_DOC_PATH);
+ loadFromAbout(R.raw.notice);
dialog.dismiss();
}
});
+ // when privacy policy URL is set (via '--with-privacy-policy-url=<url>' autogen option),
+ // add button to open that URL
+ final String privacyUrl = BuildConfig.PRIVACY_POLICY_URL;
+ if (!privacyUrl.isEmpty() && privacyUrl != "undefined") {
+ builder.setNeutralButton(R.string.about_privacy_policy, (DialogInterface dialog, int id) -> {
+ Intent openPrivacyUrlIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyUrl));
+ startActivity(openPrivacyUrlIntent);
+ dialog.dismiss();
+ });
+ }
+
return builder.create();
}
- private void loadFromAbout(String input) {
- Intent i = new Intent(Intent.ACTION_VIEW, Uri.fromFile(new File(input)));
+ private void loadFromAbout(int resourceId) {
+ Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/" + resourceId));
String packageName = getActivity().getApplicationContext().getPackageName();
ComponentName componentName = new ComponentName(packageName, LibreOfficeMainActivity.class.getName());
i.setComponent(componentName);
diff --git a/android/source/src/java/org/libreoffice/ColorPaletteAdapter.java b/android/source/src/java/org/libreoffice/ColorPaletteAdapter.java
index 6ec6aa138f66..16d8a977864f 100644
--- a/android/source/src/java/org/libreoffice/ColorPaletteAdapter.java
+++ b/android/source/src/java/org/libreoffice/ColorPaletteAdapter.java
@@ -1,7 +1,7 @@
package org.libreoffice;
import android.content.Context;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,12 +12,12 @@ import android.widget.ImageButton;
public class ColorPaletteAdapter extends RecyclerView.Adapter<ColorPaletteAdapter.ColorPaletteViewHolder> {
- int[][] color_palette;
- Context mContext;
- int upperSelectedBox = -1;
- int selectedBox = 0;
- boolean animate;
- ColorPaletteListener colorPaletteListener;
+ private int[][] color_palette;
+ private final Context mContext;
+ private int upperSelectedBox = -1;
+ private int selectedBox = 0;
+ private boolean animate;
+ private final ColorPaletteListener colorPaletteListener;
public ColorPaletteAdapter(Context mContext, ColorPaletteListener colorPaletteListener) {
this.mContext = mContext;
@@ -36,6 +36,10 @@ public class ColorPaletteAdapter extends RecyclerView.Adapter<ColorPaletteAdapte
return selectedBox;
}
+ public int getUpperSelectedBox() {
+ return upperSelectedBox;
+ }
+
@Override
public void onBindViewHolder(final ColorPaletteViewHolder holder, int position) {
@@ -128,4 +132,4 @@ public class ColorPaletteAdapter extends RecyclerView.Adapter<ColorPaletteAdapte
}
-} \ No newline at end of file
+}
diff --git a/android/source/src/java/org/libreoffice/ColorPickerAdapter.java b/android/source/src/java/org/libreoffice/ColorPickerAdapter.java
index c93d5a01bbb4..a17dd264fb99 100644
--- a/android/source/src/java/org/libreoffice/ColorPickerAdapter.java
+++ b/android/source/src/java/org/libreoffice/ColorPickerAdapter.java
@@ -3,7 +3,7 @@ package org.libreoffice;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,12 +12,11 @@ import android.widget.ImageButton;
public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.ColorPickerViewHolder> {
- Context mContext;
- ColorPaletteAdapter colorPaletteAdapter;
- ColorPaletteListener colorPaletteListener;
- int[] colorList;
- int[][] colorPalette = new int[11][8];
- int selectedBox = 0;
+ private final Context mContext;
+ private final ColorPaletteAdapter colorPaletteAdapter;
+ private final ColorPaletteListener colorPaletteListener;
+ private final int[] colorList;
+ private final int[][] colorPalette = new int[11][8];
public ColorPickerAdapter(Context mContext, final ColorPaletteAdapter colorPaletteAdapter, ColorPaletteListener colorPaletteListener) {
this.mContext = mContext;
@@ -41,10 +40,11 @@ public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.
public void onBindViewHolder(final ColorPickerViewHolder holder, int position) {
holder.colorBox.setBackgroundColor(colorList[position]);
- if (selectedBox != position)
- holder.colorBox.setImageDrawable(null);
- else {
+ if (colorPaletteAdapter.getUpperSelectedBox() == position
+ && colorPaletteAdapter.getSelectedBox() >= 0) {
holder.colorBox.setImageResource(R.drawable.ic_done_white_12dp);
+ } else {
+ holder.colorBox.setImageDrawable(null);
}
holder.colorBox.setOnClickListener(new View.OnClickListener() {
@@ -64,12 +64,20 @@ public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.
private void setPosition(int position) {
- this.selectedBox = position;
selectSubColor(position, position==0?0:3);
colorPaletteListener.applyColor(colorList[position]);
updateAdapter();
}
+ /**
+ * Switches to first palette, but doesn't mark any color as selected.
+ * Use this if no color in the palette matches the actual one.
+ */
+ public void unselectColors() {
+ colorPaletteAdapter.changePosition(0, -1);
+ updateAdapter();
+ }
+
private void selectSubColor(int position1, int position2) {
colorPaletteAdapter.setPosition(position1, position2);
}
@@ -88,7 +96,15 @@ public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.
int red_shade = red;
int green_shade = green;
int blue_shade = blue;
- if (i != 0) {
+ if (i == 0) {
+ colorPalette[0][0] = colorList[i];
+ for (int k = 1; k < 7; k++) {
+ red_tint = (int) (red_tint + (255 - red_tint) * 0.25);
+ green_tint = (int) (green_tint + (255 - green_tint) * 0.25);
+ blue_tint = (int) (blue_tint + (255 - blue_tint) * 0.25);
+ colorPalette[i][k] = (Color.rgb(red_tint, green_tint, blue_tint));
+ }
+ } else {
colorPalette[i][3] = colorList[i];
for (int k = 2; k >= 0; k--) {
red_shade = (int) (red_shade * 0.75);
@@ -102,48 +118,28 @@ public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.
blue_tint = (int) (blue_tint + (255 - blue_tint) * 0.45);
colorPalette[i][k] = (Color.rgb(red_tint, green_tint, blue_tint));
}
- } else {
- colorPalette[0][0] = colorList[i];
- for (int k = 1; k < 7; k++) {
- red_tint = (int) (red_tint + (255 - red_tint) * 0.25);
- green_tint = (int) (green_tint + (255 - green_tint) * 0.25);
- blue_tint = (int) (blue_tint + (255 - blue_tint) * 0.25);
- colorPalette[i][k] = (Color.rgb(red_tint, green_tint, blue_tint));
- }
}
- }
- for (int i = 0; i < 11; i++){
- this.colorPalette[i][7] = (Color.rgb(255, 255, 255)); // last one is always white
+ colorPalette[i][7] = Color.WHITE; // last one is always white
}
colorPaletteAdapter.setColorPalette(colorPalette);
}
public void findSelectedTextColor(int color) {
- /*
- Libreoffice recognizes -1 as Black
- */
- if (color == -1) {
- colorPaletteAdapter.changePosition(0, 0);
- selectedBox = 0;
- updateAdapter();
- return;
- }
- /*
- Find the color if the palette points another color
- */
- if (colorPalette[selectedBox][colorPaletteAdapter.getSelectedBox()] != color) {
- for (int i = 0; i < 11; i++) {
- for (int k = 0; k < 8; k++) {
- if (colorPalette[i][k] == color) {
- colorPaletteAdapter.changePosition(i, k);
- selectedBox = i;
- updateAdapter();
- return;
- }
+ // try to find and highlight the color in the existing palettes
+ for (int i = 0; i < 11; i++) {
+ for (int k = 0; k < 8; k++) {
+ if (colorPalette[i][k] == color) {
+ colorPaletteAdapter.changePosition(i, k);
+ updateAdapter();
+ return;
}
}
}
+
+ // no color in the palettes matched
+ unselectColors();
}
+
private void updateAdapter(){
LOKitShell.getMainHandler().post(new Runnable() {
@Override
@@ -163,4 +159,4 @@ public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.
this.colorBox = itemView.findViewById(R.id.fontColorBox);
}
}
-} \ No newline at end of file
+}
diff --git a/android/source/src/java/org/libreoffice/DocumentPartViewListAdapter.java b/android/source/src/java/org/libreoffice/DocumentPartViewListAdapter.java
index a576fc67dcb2..a0ed871a40d2 100644
--- a/android/source/src/java/org/libreoffice/DocumentPartViewListAdapter.java
+++ b/android/source/src/java/org/libreoffice/DocumentPartViewListAdapter.java
@@ -19,7 +19,6 @@ import android.widget.TextView;
import java.util.List;
public class DocumentPartViewListAdapter extends ArrayAdapter<DocumentPartView> {
- private static final String LOGTAG = DocumentPartViewListAdapter.class.getSimpleName();
private final Activity activity;
private final ThumbnailCreator thumbnailCollector;
diff --git a/android/source/src/java/org/libreoffice/FontController.java b/android/source/src/java/org/libreoffice/FontController.java
index a00e13e1485c..72f35d8b42d8 100644
--- a/android/source/src/java/org/libreoffice/FontController.java
+++ b/android/source/src/java/org/libreoffice/FontController.java
@@ -2,12 +2,13 @@ package org.libreoffice;
import android.graphics.Color;
import android.graphics.Rect;
-import android.support.design.widget.BottomSheetBehavior;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
+import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
@@ -23,12 +24,15 @@ import java.util.Iterator;
public class FontController implements AdapterView.OnItemSelectedListener {
+ /** -1 as value in ".uno:Color" et al. means "automatic color"/no color set. */
+ private static final int COLOR_AUTO = -1;
+
private boolean mFontNameSpinnerSet = false;
private boolean mFontSizeSpinnerSet = false;
private final LibreOfficeMainActivity mActivity;
- private final ArrayList<String> mFontList = new ArrayList<String>();
- private final ArrayList<String> mFontSizes = new ArrayList<String>();
- private final HashMap<String, ArrayList<String>> mAllFontSizes = new HashMap<String, ArrayList<String>>();
+ private final ArrayList<String> mFontList = new ArrayList<>();
+ private final ArrayList<String> mFontSizes = new ArrayList<>();
+ private final HashMap<String, ArrayList<String>> mAllFontSizes = new HashMap<>();
private String mCurrentFontSelected = null;
private String mCurrentFontSizeSelected = null;
@@ -45,29 +49,44 @@ public class FontController implements AdapterView.OnItemSelectedListener {
final ColorPaletteListener colorPaletteListener = new ColorPaletteListener() {
@Override
public void applyColor(int color) {
- sendFontColorChange(color);
+ sendFontColorChange(color, false);
}
@Override
public void updateColorPickerPosition(int color) {
- if (null == colorPickerAdapter) return;
- colorPickerAdapter.findSelectedTextColor(color + 0xFF000000);
- changeFontColorBoxColor(color + 0xFF000000);
+ if (colorPickerAdapter == null) {
+ return;
+ }
+ if (color == COLOR_AUTO) {
+ colorPickerAdapter.unselectColors();
+ changeFontColorBoxColor(Color.TRANSPARENT);
+ return;
+ }
+ final int colorWithAlpha = color | 0xFF000000;
+ colorPickerAdapter.findSelectedTextColor(colorWithAlpha);
+ changeFontColorBoxColor(colorWithAlpha);
}
};
final ColorPaletteListener backColorPaletteListener = new ColorPaletteListener() {
@Override
public void applyColor(int color) {
- sendFontBackColorChange(color);
+ sendFontBackColorChange(color, false);
}
@Override
public void updateColorPickerPosition(int color) {
- if(backColorPickerAdapter != null)
- backColorPickerAdapter.findSelectedTextColor(color + 0xFF000000);
- changeFontBackColorBoxColor(color + 0xFF000000);
-
+ if (backColorPickerAdapter == null) {
+ return;
+ }
+ if (color == COLOR_AUTO) {
+ backColorPickerAdapter.unselectColors();
+ changeFontBackColorBoxColor(Color.TRANSPARENT);
+ return;
+ }
+ final int colorWithAlpha = color | 0xFF000000;
+ backColorPickerAdapter.findSelectedTextColor(colorWithAlpha);
+ changeFontBackColorBoxColor(colorWithAlpha);
}
};
@@ -77,11 +96,7 @@ public class FontController implements AdapterView.OnItemSelectedListener {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
- if(color == -1){ //Libreoffice recognizes -1 as black
- fontColorPickerButton.setBackgroundColor(Color.BLACK);
- }else{
- fontColorPickerButton.setBackgroundColor(color);
- }
+ fontColorPickerButton.setBackgroundColor(color);
}
});
}
@@ -92,12 +107,7 @@ public class FontController implements AdapterView.OnItemSelectedListener {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
- if(color == -1){ //Libreoffice recognizes -1 as black
- fontBackColorPickerButton.setBackgroundColor(Color.BLACK);
- }else{
- fontBackColorPickerButton.setBackgroundColor(color);
-
- }
+ fontBackColorPickerButton.setBackgroundColor(color);
}
});
}
@@ -132,12 +142,12 @@ public class FontController implements AdapterView.OnItemSelectedListener {
}
}
- private void sendFontColorChange(int color){
+ private void sendFontColorChange(int color, boolean keepAlpha){
try {
JSONObject json = new JSONObject();
JSONObject valueJson = new JSONObject();
valueJson.put("type", "long");
- valueJson.put("value", 0x00FFFFFF & color);
+ valueJson.put("value", keepAlpha ? color : 0x00FFFFFF & color);
json.put("Color", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Color", json.toString()));
@@ -152,21 +162,18 @@ public class FontController implements AdapterView.OnItemSelectedListener {
* 0x00FFFFFF & color operation removes the alpha which is FF,
* if we don't remove it, the color value becomes negative which is not recognized by LOK
*/
- private void sendFontBackColorChange(int color){
+ private void sendFontBackColorChange(int color, boolean keepAlpha) {
try {
JSONObject json = new JSONObject();
JSONObject valueJson = new JSONObject();
valueJson.put("type", "long");
- valueJson.put("value", 0x00FFFFFF & color);
- if(mActivity.isSpreadsheet()){
+ valueJson.put("value", keepAlpha ? color : 0x00FFFFFF & color);
+ if(mActivity.getTileProvider().isSpreadsheet()){
json.put("BackgroundColor", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:BackgroundColor", json.toString()));
- }else if(mActivity.getTileProvider().isPresentation()){
+ }else {
json.put("CharBackColor", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CharBackColor", json.toString()));
- }else {
- json.put("BackColor", valueJson);
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:BackColor", json.toString()));
}
changeFontBackColorBoxColor(color);
@@ -213,7 +220,7 @@ public class FontController implements AdapterView.OnItemSelectedListener {
String key = keys.next();
mFontList.add(key);
JSONArray array = jObject2.getJSONArray(key);
- fontSizes = new ArrayList<String>();
+ fontSizes = new ArrayList<>();
for (int i = 0; i < array.length(); i++) {
fontSizes.add(array.getString(i));
}
@@ -237,14 +244,14 @@ public class FontController implements AdapterView.OnItemSelectedListener {
private void setupFontNameSpinner() {
Spinner fontSpinner = mActivity.findViewById(R.id.font_name_spinner);
- ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, mFontList);
+ ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(mActivity, android.R.layout.simple_spinner_item, mFontList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fontSpinner.setAdapter(dataAdapter);
}
private void setupFontSizeSpinner() {
Spinner fontSizeSpinner = mActivity.findViewById(R.id.font_size_spinner);
- ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, mFontSizes);
+ ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(mActivity, android.R.layout.simple_spinner_item, mFontSizes);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fontSizeSpinner.setAdapter(dataAdapter);
}
@@ -306,6 +313,10 @@ public class FontController implements AdapterView.OnItemSelectedListener {
fontColorPicker.setOnClickListener(clickListener);
fontColorPickerButton.setOnClickListener(clickListener);
+ final Button autoColorButton = colorPickerLayout.findViewById(R.id.button_auto_color);
+ autoColorButton.setOnClickListener(view -> {
+ sendFontColorChange(COLOR_AUTO, true);
+ });
}
private void setupBackColorPicker(){
@@ -365,6 +376,10 @@ public class FontController implements AdapterView.OnItemSelectedListener {
fontColorPicker.setOnClickListener(clickListener);
fontColorPickerButton.setOnClickListener(clickListener);
+ final Button autoColorButton = backColorPickerLayout.findViewById(R.id.button_auto_color);
+ autoColorButton.setOnClickListener(view -> {
+ sendFontBackColorChange(COLOR_AUTO, true);
+ });
}
public void selectFont(final String fontName) {
diff --git a/android/source/src/java/org/libreoffice/FormattingController.java b/android/source/src/java/org/libreoffice/FormattingController.java
index a34c4c41ee29..49e81eb69784 100644
--- a/android/source/src/java/org/libreoffice/FormattingController.java
+++ b/android/source/src/java/org/libreoffice/FormattingController.java
@@ -11,8 +11,8 @@ import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
-import android.support.design.widget.Snackbar;
-import android.support.v4.content.FileProvider;
+import com.google.android.material.snackbar.Snackbar;
+import androidx.core.content.FileProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -40,7 +40,7 @@ class FormattingController implements View.OnClickListener {
private static final int SELECT_PHOTO = 2;
private static final int IMAGE_BUFFER_SIZE = 4 * 1024;
- private LibreOfficeMainActivity mContext;
+ private final LibreOfficeMainActivity mContext;
private String mCurrentPhotoPath;
FormattingController(LibreOfficeMainActivity context) {
@@ -48,6 +48,8 @@ class FormattingController implements View.OnClickListener {
mContext.findViewById(R.id.button_insertFormatListBullets).setOnClickListener(this);
mContext.findViewById(R.id.button_insertFormatListNumbering).setOnClickListener(this);
+ mContext.findViewById(R.id.button_increaseIndent).setOnClickListener(this);
+ mContext.findViewById(R.id.button_decreaseIndent).setOnClickListener(this);
mContext.findViewById(R.id.button_bold).setOnClickListener(this);
mContext.findViewById(R.id.button_italic).setOnClickListener(this);
@@ -84,70 +86,51 @@ class FormattingController implements View.OnClickListener {
button.getBackground().setState(new int[]{android.R.attr.state_selected});
}
- switch(button.getId()) {
-
- case R.id.button_insertFormatListBullets:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:DefaultBullet"));
- break;
-
- case R.id.button_insertFormatListNumbering:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:DefaultNumbering"));
- break;
-
- case R.id.button_bold:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Bold"));
- break;
- case R.id.button_italic:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Italic"));
- break;
- case R.id.button_strikethrough:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Strikeout"));
- break;
- case R.id.button_clearformatting:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:ResetAttributes"));
- break;
- case R.id.button_underlined:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:UnderlineDouble"));
- break;
- case R.id.button_align_left:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:LeftPara"));
- break;
- case R.id.button_align_center:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CenterPara"));
- break;
- case R.id.button_align_right:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:RightPara"));
- break;
- case R.id.button_align_justify:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:JustifyPara"));
- break;
- case R.id.button_insert_line:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Line"));
- break;
- case R.id.button_insert_rect:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Rect"));
- break;
- case R.id.button_font_shrink:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Shrink"));
- break;
- case R.id.button_font_grow:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Grow"));
- break;
- case R.id.button_subscript:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SubScript"));
- break;
- case R.id.button_superscript:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SuperScript"));
- break;
- case R.id.button_insert_picture:
- insertPicture();
- break;
- case R.id.button_insert_table:
- insertTable();
- break;
- case R.id.button_delete_table:
- deleteTable();
- break;
+ final int buttonId = button.getId();
+ if (buttonId == R.id.button_insertFormatListBullets) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:DefaultBullet"));
+ } else if (buttonId == R.id.button_insertFormatListNumbering) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:DefaultNumbering"));
+ } else if (buttonId == R.id.button_increaseIndent) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:IncrementIndent"));
+ } else if (buttonId == R.id.button_decreaseIndent) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:DecrementIndent"));
+ } else if (buttonId == R.id.button_bold) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Bold"));
+ } else if (buttonId == R.id.button_italic) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Italic"));
+ } else if (buttonId == R.id.button_strikethrough) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Strikeout"));
+ } else if (buttonId == R.id.button_clearformatting) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:ResetAttributes"));
+ } else if (buttonId == R.id.button_underlined) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:UnderlineDouble"));
+ } else if (buttonId == R.id.button_align_left) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:LeftPara"));
+ } else if (buttonId == R.id.button_align_center) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CenterPara"));
+ } else if (buttonId == R.id.button_align_right) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:RightPara"));
+ } else if (buttonId == R.id.button_align_justify) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:JustifyPara"));
+ } else if (buttonId == R.id.button_insert_line) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Line"));
+ } else if (buttonId == R.id.button_insert_rect) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Rect"));
+ } else if (buttonId == R.id.button_font_shrink) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Shrink"));
+ } else if (buttonId == R.id.button_font_grow) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Grow"));
+ } else if (buttonId == R.id.button_subscript) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SubScript"));
+ }else if (buttonId == R.id.button_superscript) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SuperScript"));
+ } else if (buttonId == R.id.button_insert_picture) {
+ insertPicture();
+ } else if (buttonId == R.id.button_insert_table) {
+ insertTable();
+ } else if (buttonId == R.id.button_delete_table) {
+ deleteTable();
}
}
@@ -243,15 +226,11 @@ class FormattingController implements View.OnClickListener {
public void onClick(View v) {
int rowCount = Integer.parseInt(npRowCount.getText().toString());
int colCount = Integer.parseInt(npColCount.getText().toString());
- switch (v.getId()){
- case R.id.number_picker_rows_positive:
- if(rowCount < maxValue)
- npRowCount.setText(String.valueOf(++rowCount));
- break;
- case R.id.number_picker_cols_positive:
- if(colCount < maxValue)
- npColCount.setText(String.valueOf(++colCount));
- break;
+ final int id = v.getId();
+ if (id == R.id.number_picker_rows_positive && rowCount < maxValue) {
+ npRowCount.setText(String.valueOf(++rowCount));
+ } else if (id == R.id.number_picker_cols_positive && colCount < maxValue) {
+ npColCount.setText(String.valueOf(++colCount));
}
}
};
@@ -261,15 +240,11 @@ class FormattingController implements View.OnClickListener {
public void onClick(View v) {
int rowCount = Integer.parseInt(npRowCount.getText().toString());
int colCount = Integer.parseInt(npColCount.getText().toString());
- switch (v.getId()){
- case R.id.number_picker_rows_negative:
- if(rowCount > minValue)
- npRowCount.setText(String.valueOf(--rowCount));
- break;
- case R.id.number_picker_cols_negative:
- if(colCount > minValue)
- npColCount.setText(String.valueOf(--colCount));
- break;
+ final int id = v.getId();
+ if (id == R.id.number_picker_rows_negative && rowCount > minValue) {
+ npRowCount.setText(String.valueOf(--rowCount));
+ } else if (id == R.id.number_picker_cols_negative && colCount > minValue) {
+ npColCount.setText(String.valueOf(--colCount));
}
}
};
@@ -421,15 +396,14 @@ class FormattingController implements View.OnClickListener {
void handleActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
- mContext.pendingInsertGraphic = true;
+ compressAndInsertImage();
} else if (requestCode == SELECT_PHOTO && resultCode == Activity.RESULT_OK) {
getFileFromURI(data.getData());
- mContext.pendingInsertGraphic = true;
+ compressAndInsertImage();
}
}
- // Called by LOKitTileProvider when activity is resumed from photo/gallery/camera/cloud apps
- void popCompressImageGradeSelection() {
+ void compressAndInsertImage() {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
String[] options = {mContext.getResources().getString(R.string.compress_photo_smallest_size),
mContext.getResources().getString(R.string.compress_photo_medium_size),
@@ -493,7 +467,6 @@ class FormattingController implements View.OnClickListener {
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:InsertGraphic", rootJson.toString()));
LOKitShell.sendEvent(new LOEvent(LOEvent.REFRESH));
mContext.setDocumentChanged(true);
- mContext.pendingInsertGraphic = false;
}
private void compressImage(int grade) {
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java
index 32e9b56656dd..c48127cce67f 100644
--- a/android/source/src/java/org/libreoffice/InvalidationHandler.java
+++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java
@@ -25,12 +25,12 @@ import java.util.List;
* Parses (interprets) and handles invalidation messages from LibreOffice.
*/
public class InvalidationHandler implements Document.MessageCallback, Office.MessageCallback {
- private static String LOGTAG = InvalidationHandler.class.getSimpleName();
+ private static final String LOGTAG = InvalidationHandler.class.getSimpleName();
private final DocumentOverlay mDocumentOverlay;
private final GeckoLayerClient mLayerClient;
private OverlayState mState;
private boolean mKeyEvent = false;
- private LibreOfficeMainActivity mContext;
+ private final LibreOfficeMainActivity mContext;
private int currentTotalPageNumber = 0; // total page number of the current document
@@ -55,6 +55,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
&& messageID != Document.CALLBACK_DOCUMENT_PASSWORD
&& messageID != Document.CALLBACK_HYPERLINK_CLICKED
&& messageID != Document.CALLBACK_SEARCH_RESULT_SELECTION
+ && messageID != Document.CALLBACK_SC_FOLLOW_JUMP
&& messageID != Document.CALLBACK_TEXT_SELECTION
&& messageID != Document.CALLBACK_TEXT_SELECTION_START
&& messageID != Document.CALLBACK_TEXT_SELECTION_END)
@@ -114,6 +115,9 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
case Document.CALLBACK_CELL_CURSOR:
invalidateCellCursor(payload);
break;
+ case Document.CALLBACK_SC_FOLLOW_JUMP:
+ jumpToCell(payload);
+ break;
case Document.CALLBACK_INVALIDATE_HEADER:
invalidateHeader();
break;
@@ -139,7 +143,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
JSONObject payloadObject = new JSONObject(payload);
if (payloadObject.getString("commandName").equals(".uno:Save")) {
if (payloadObject.getString("success").equals("true")) {
- mContext.saveFilesToCloud();
+ mContext.saveFileToOriginalSource();
}
}else if(payloadObject.getString("commandName").equals(".uno:Name") ||
payloadObject.getString("commandName").equals(".uno:RenamePage")){
@@ -214,6 +218,14 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
}
}
+ private void jumpToCell(String payload) {
+ RectF cellCursorRect = convertPayloadCellToRectangle(payload);
+
+ if (cellCursorRect != null) {
+ moveViewportToMakeSelectionVisible(cellCursorRect);
+ }
+ }
+
/**
* Handles the search result selection message, which is a JSONObject
*
@@ -330,7 +342,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
mContext.getFormattingController().onToggleStateChanged(Document.NUMBERED_LIST, pressed);
} else if (parts[0].equals(".uno:Color")) {
mContext.getFontController().colorPaletteListener.updateColorPickerPosition(Integer.parseInt(value));
- } else if (mContext.getTileProvider().isTextDocument() && parts[0].equals(".uno:BackColor")) {
+ } else if (mContext.getTileProvider().isTextDocument() && (parts[0].equals(".uno:BackColor") || parts[0].equals(".uno:CharBackColor"))) {
mContext.getFontController().backColorPaletteListener.updateColorPickerPosition(Integer.parseInt(value));
} else if (mContext.getTileProvider().isPresentation() && parts[0].equals(".uno:CharBackColor")) {
mContext.getFontController().backColorPaletteListener.updateColorPickerPosition(Integer.parseInt(value));
@@ -368,6 +380,40 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
if (coordinates.length != 4) {
return null;
}
+ return convertPayloadToRectangle(coordinates);
+ }
+
+ /**
+ * Parses the payload text with rectangle coordinates and converts to rectangle in pixel coordinates
+ *
+ * @param payload - invalidation message payload text
+ * @return rectangle in pixel coordinates
+ */
+ public RectF convertPayloadCellToRectangle(String payload) {
+ String payloadWithoutWhitespace = payload.replaceAll("\\s", ""); // remove all whitespace from the string
+
+ if (payloadWithoutWhitespace.isEmpty() || payloadWithoutWhitespace.equals("EMPTY")) {
+ return null;
+ }
+
+ String[] coordinates = payloadWithoutWhitespace.split(",");
+
+ if (coordinates.length != 6 ) {
+ return null;
+ }
+ return convertPayloadToRectangle(coordinates);
+ }
+
+ /**
+ * Converts rectangle coordinates to rectangle in pixel coordinates
+ *
+ * @param coordinates - the first four items defines the rectangle
+ * @return rectangle in pixel coordinates
+ */
+ public RectF convertPayloadToRectangle(String[] coordinates) {
+ if (coordinates.length < 4 ) {
+ return null;
+ }
int x = Integer.decode(coordinates[0]);
int y = Integer.decode(coordinates[1]);
@@ -377,10 +423,10 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
float dpi = LOKitShell.getDpi(mContext);
return new RectF(
- LOKitTileProvider.twipToPixel(x, dpi),
- LOKitTileProvider.twipToPixel(y, dpi),
- LOKitTileProvider.twipToPixel(x + width, dpi),
- LOKitTileProvider.twipToPixel(y + height, dpi)
+ LOKitTileProvider.twipToPixel(x, dpi),
+ LOKitTileProvider.twipToPixel(y, dpi),
+ LOKitTileProvider.twipToPixel(x + width, dpi),
+ LOKitTileProvider.twipToPixel(y + height, dpi)
);
}
@@ -505,7 +551,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
changeStateTo(OverlayState.TRANSITION);
}
mDocumentOverlay.changeSelections(Collections.<RectF>emptyList());
- if (mContext.isSpreadsheet()) {
+ if (mContext.getTileProvider().isSpreadsheet()) {
mDocumentOverlay.showHeaderSelection(null);
}
mContext.getToolbarController().showHideClipboardCutAndCopy(false);
@@ -516,7 +562,7 @@ public class InvalidationHandler implements Document.MessageCallback, Office.Mes
}
changeStateTo(OverlayState.SELECTION);
mDocumentOverlay.changeSelections(rectangles);
- if (mContext.isSpreadsheet()) {
+ if (mContext.getTileProvider().isSpreadsheet()) {
mDocumentOverlay.showHeaderSelection(rectangles.get(0));
}
String selectedText = mContext.getTileProvider().getTextSelection("");
diff --git a/android/source/src/java/org/libreoffice/LOEvent.java b/android/source/src/java/org/libreoffice/LOEvent.java
index 4db48a5bbd6d..d1170eee12ad 100644
--- a/android/source/src/java/org/libreoffice/LOEvent.java
+++ b/android/source/src/java/org/libreoffice/LOEvent.java
@@ -33,7 +33,6 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int SWIPE_LEFT = 12;
public static final int NAVIGATION_CLICK = 13;
public static final int UNO_COMMAND = 14;
- public static final int RESUME = 15;
public static final int LOAD_NEW = 16;
public static final int SAVE_AS = 17;
public static final int UPDATE_PART_PAGE_RECT = 18;
@@ -42,6 +41,7 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int REFRESH = 21;
public static final int PAGE_SIZE_CHANGED = 22;
public static final int UNO_COMMAND_NOTIFY = 23;
+ public static final int SAVE_COPY_AS = 24;
public final int mType;
@@ -104,13 +104,6 @@ public class LOEvent implements Comparable<LOEvent> {
mValue = value;
}
- public LOEvent(int type, String key, int value) {
- mType = type;
- mTypeString = "Resume partIndex";
- mString = key;
- mPartIndex = value;
- }
-
public LOEvent(String filePath, int type) {
mType = type;
mTypeString = "Load";
diff --git a/android/source/src/java/org/libreoffice/LOKitInputConnectionHandler.java b/android/source/src/java/org/libreoffice/LOKitInputConnectionHandler.java
index bbef709af297..7b50ef5ff707 100644
--- a/android/source/src/java/org/libreoffice/LOKitInputConnectionHandler.java
+++ b/android/source/src/java/org/libreoffice/LOKitInputConnectionHandler.java
@@ -19,7 +19,7 @@ import org.mozilla.gecko.gfx.InputConnectionHandler;
* directed to this class which is then directed further to LOKitThread.
*/
public class LOKitInputConnectionHandler implements InputConnectionHandler {
- private static String LOGTAG = LOKitInputConnectionHandler.class.getSimpleName();
+ private static final String LOGTAG = LOKitInputConnectionHandler.class.getSimpleName();
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
diff --git a/android/source/src/java/org/libreoffice/LOKitShell.java b/android/source/src/java/org/libreoffice/LOKitShell.java
index c69e02669619..f6a76228e008 100644
--- a/android/source/src/java/org/libreoffice/LOKitShell.java
+++ b/android/source/src/java/org/libreoffice/LOKitShell.java
@@ -24,10 +24,10 @@ import org.mozilla.gecko.gfx.ComposedTileLayer;
* Common static LOKit functions, functions to send events.
*/
public class LOKitShell {
- private static final String LOGTAG = LOKitShell.class.getSimpleName();
-
public static float getDpi(Context context) {
- if (((LibreOfficeMainActivity)context).isSpreadsheet()) return 96f;
+ LOKitTileProvider tileProvider = ((LibreOfficeMainActivity)context).getTileProvider();
+ if (tileProvider != null && tileProvider.isSpreadsheet())
+ return 96f;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return metrics.density * 160;
}
@@ -61,7 +61,7 @@ public class LOKitShell {
}
public static boolean isEditingEnabled() {
- return LibreOfficeMainActivity.isExperimentalMode();
+ return !LibreOfficeMainActivity.isReadOnlyMode();
}
// EVENTS
@@ -119,8 +119,8 @@ public class LOKitShell {
LOKitShell.sendEvent(new LOEvent(filePath, fileFormat, LOEvent.SAVE_AS));
}
- public static void sendResumeEvent(String inputFile, int partIndex) {
- LOKitShell.sendEvent(new LOEvent(LOEvent.RESUME, inputFile, partIndex));
+ public static void sendSaveCopyAsEvent(String filePath, String fileFormat) {
+ LOKitShell.sendEvent(new LOEvent(filePath, fileFormat, LOEvent.SAVE_COPY_AS));
}
public static void sendCloseEvent() {
diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java
index e554f0800cf0..fd40c3089102 100644
--- a/android/source/src/java/org/libreoffice/LOKitThread.java
+++ b/android/source/src/java/org/libreoffice/LOKitThread.java
@@ -7,7 +7,6 @@ import android.util.Log;
import android.view.KeyEvent;
import org.libreoffice.canvas.SelectionHandle;
-import org.libreoffice.ui.LibreOfficeUIActivity;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.ComposedTileLayer;
@@ -26,13 +25,13 @@ import java.util.concurrent.LinkedBlockingQueue;
class LOKitThread extends Thread {
private static final String LOGTAG = LOKitThread.class.getSimpleName();
- private LinkedBlockingQueue<LOEvent> mEventQueue = new LinkedBlockingQueue<LOEvent>();
+ private final LinkedBlockingQueue<LOEvent> mEventQueue = new LinkedBlockingQueue<LOEvent>();
private TileProvider mTileProvider;
private InvalidationHandler mInvalidationHandler;
private ImmutableViewportMetrics mViewportMetrics;
private GeckoLayerClient mLayerClient;
- private LibreOfficeMainActivity mContext;
+ private final LibreOfficeMainActivity mContext;
LOKitThread(LibreOfficeMainActivity context) {
mContext = context;
@@ -112,7 +111,7 @@ class LOKitThread extends Thread {
/**
* Handle the geometry change + draw.
*/
- private void redraw() {
+ private void redraw(boolean resetZoomAndPosition) {
if (mLayerClient == null || mTileProvider == null) {
// called too early...
return;
@@ -122,7 +121,9 @@ class LOKitThread extends Thread {
mViewportMetrics = mLayerClient.getViewportMetrics();
mLayerClient.setViewportMetrics(mViewportMetrics);
- zoomAndRepositionTheDocument();
+ if (resetZoomAndPosition) {
+ zoomAndRepositionTheDocument();
+ }
mLayerClient.forceRedraw();
mLayerClient.forceRender();
@@ -152,9 +153,9 @@ class LOKitThread extends Thread {
/**
* Invalidate everything + handle the geometry change
*/
- private void refresh() {
+ private void refresh(boolean resetZoomAndPosition) {
mLayerClient.clearAndResetlayers();
- redraw();
+ redraw(resetZoomAndPosition);
updatePartPageRectangles();
if (mTileProvider != null && mTileProvider.isSpreadsheet()) {
updateCalcHeaders();
@@ -177,35 +178,17 @@ class LOKitThread extends Thread {
private void updatePageSize(int pageWidth, int pageHeight){
mTileProvider.setDocumentSize(pageWidth, pageHeight);
- redraw();
+ redraw(true);
}
private void updateZoomConstraints() {
if (mTileProvider == null) return;
mLayerClient = mContext.getLayerClient();
- // Set min zoom to the page width so that you cannot zoom below page width
- final float minZoom = mLayerClient.getViewportMetrics().getWidth()/mTileProvider.getPageWidth();
- mLayerClient.setZoomConstraints(new ZoomConstraints(true, 1f, minZoom, 0f));
- }
-
-
- /**
- * Resume the document with the current part
- */
-
- private void resumeDocument(String filename, int partIndex){
-
- mLayerClient = mContext.getLayerClient();
-
- mInvalidationHandler = new InvalidationHandler(mContext);
- mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, filename);
-
- if (mTileProvider.isReady()) {
- updateZoomConstraints();
- changePart(partIndex);
- } else {
- closeDocument();
- }
+ // Set default zoom to the page width and min zoom so that the whole page is visible
+ final float pageHeightZoom = mLayerClient.getViewportMetrics().getHeight() / mTileProvider.getPageHeight();
+ final float pageWidthZoom = mLayerClient.getViewportMetrics().getWidth() / mTileProvider.getPageWidth();
+ final float minZoom = Math.min(pageWidthZoom, pageHeightZoom);
+ mLayerClient.setZoomConstraints(new ZoomConstraints(pageWidthZoom, minZoom, 0f));
}
/**
@@ -216,15 +199,16 @@ class LOKitThread extends Thread {
mTileProvider.changePart(partIndex);
mViewportMetrics = mLayerClient.getViewportMetrics();
// mLayerClient.setViewportMetrics(mViewportMetrics.scaleTo(0.9f, new PointF()));
- refresh();
+ refresh(true);
LOKitShell.hideProgressSpinner(mContext);
}
/**
* Handle load document event.
* @param filePath - filePath to where the document is located
+ * @return Whether the document has been loaded successfully.
*/
- private void loadDocument(String filePath) {
+ private boolean loadDocument(String filePath) {
mLayerClient = mContext.getLayerClient();
mInvalidationHandler = new InvalidationHandler(mContext);
@@ -233,18 +217,12 @@ class LOKitThread extends Thread {
if (mTileProvider.isReady()) {
LOKitShell.showProgressSpinner(mContext);
updateZoomConstraints();
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // synchronize to avoid deletion while loading
- synchronized (LOKitThread.this) {
- refresh();
- }
- }
- });
+ refresh(true);
LOKitShell.hideProgressSpinner(mContext);
+ return true;
} else {
closeDocument();
+ return false;
}
}
@@ -254,47 +232,27 @@ class LOKitThread extends Thread {
* @param fileType - fileType what type of new document is to be loaded
*/
private void loadNewDocument(String filePath, String fileType) {
- mLayerClient = mContext.getLayerClient();
-
- mInvalidationHandler = new InvalidationHandler(mContext);
- mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, fileType);
-
- if (mTileProvider.isReady()) {
- LOKitShell.showProgressSpinner(mContext);
- updateZoomConstraints();
- refresh();
- LOKitShell.hideProgressSpinner(mContext);
-
- if (fileType.matches(LibreOfficeUIActivity.NEW_WRITER_STRING_KEY))
- mTileProvider.saveDocumentAs(filePath, "odt");
- else if (fileType.matches(LibreOfficeUIActivity.NEW_CALC_STRING_KEY))
- mTileProvider.saveDocumentAs(filePath, "ods");
- else if (fileType.matches(LibreOfficeUIActivity.NEW_IMPRESS_STRING_KEY))
- mTileProvider.saveDocumentAs(filePath, "odp");
- else
- mTileProvider.saveDocumentAs(filePath, "odg");
-
- } else {
- closeDocument();
+ boolean ok = loadDocument(fileType);
+ if (ok) {
+ mTileProvider.saveDocumentAs(filePath, true);
}
}
/**
* Save the currently loaded document.
*/
- private void saveDocumentAs(String filePath, String fileType) {
+ private void saveDocumentAs(String filePath, String fileType, boolean bTakeOwnership) {
if (mTileProvider == null) {
Log.e(LOGTAG, "Error in saving, Tile Provider instance is null");
} else {
- mTileProvider.saveDocumentAs(filePath, fileType);
+ mTileProvider.saveDocumentAs(filePath, fileType, bTakeOwnership);
}
}
/**
* Close the currently loaded document.
*/
- // needs to be synchronized to not destroy doc while it's loaded
- private synchronized void closeDocument() {
+ private void closeDocument() {
if (mTileProvider != null) {
mTileProvider.close();
mTileProvider = null;
@@ -313,16 +271,16 @@ class LOKitThread extends Thread {
loadNewDocument(event.filePath, event.fileType);
break;
case LOEvent.SAVE_AS:
- saveDocumentAs(event.filePath, event.fileType);
+ saveDocumentAs(event.filePath, event.fileType, true);
break;
- case LOEvent.RESUME:
- resumeDocument(event.mString, event.mPartIndex);
+ case LOEvent.SAVE_COPY_AS:
+ saveDocumentAs(event.filePath, event.fileType, false);
break;
case LOEvent.CLOSE:
closeDocument();
break;
case LOEvent.SIZE_CHANGED:
- redraw();
+ redraw(false);
break;
case LOEvent.CHANGE_PART:
changePart(event.mPartIndex);
@@ -376,7 +334,7 @@ class LOKitThread extends Thread {
mTileProvider.postUnoCommand(event.mString, event.mValue, event.mNotify);
break;
case LOEvent.REFRESH:
- refresh();
+ refresh(false);
break;
case LOEvent.PAGE_SIZE_CHANGED:
updatePageSize(event.mPageWidth, event.mPageHeight);
@@ -448,7 +406,7 @@ class LOKitThread extends Thread {
boolean editing = LOKitShell.isEditingEnabled();
float zoomFactor = mViewportMetrics.getZoomFactor();
- if (touchType.equals("LongPress") && editing) {
+ if (touchType.equals("LongPress")) {
mInvalidationHandler.changeStateTo(InvalidationHandler.OverlayState.TRANSITION);
mTileProvider.mouseButtonDown(documentCoordinate, 1, zoomFactor);
mTileProvider.mouseButtonUp(documentCoordinate, 1, zoomFactor);
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 0e2649337322..5d1cf12209dc 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -12,7 +12,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.os.Build;
-import android.os.Environment;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintManager;
@@ -26,7 +25,6 @@ import org.libreoffice.kit.DirectBufferAllocator;
import org.libreoffice.kit.Document;
import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
-import org.libreoffice.ui.FileUtilities;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.IntSize;
@@ -39,22 +37,22 @@ import java.nio.ByteBuffer;
*/
class LOKitTileProvider implements TileProvider {
private static final String LOGTAG = LOKitTileProvider.class.getSimpleName();
- private static int TILE_SIZE = 256;
+ private static final int TILE_SIZE = 256;
private final float mTileWidth;
private final float mTileHeight;
- private final String mInputFile;
+ private String mInputFile;
private Office mOffice;
private Document mDocument;
- private boolean mIsReady = false;
- private LibreOfficeMainActivity mContext;
+ private final boolean mIsReady;
+ private final LibreOfficeMainActivity mContext;
- private float mDPI;
+ private final float mDPI;
private float mWidthTwip;
private float mHeightTwip;
- private Document.MessageCallback mMessageCallback;
+ private final Document.MessageCallback mMessageCallback;
- private long objectCreationTime = System.currentTimeMillis();
+ private final long objectCreationTime = System.currentTimeMillis();
/**
* Initialize LOKit and load the document.
@@ -73,32 +71,16 @@ class LOKitTileProvider implements TileProvider {
mOffice.setOptionalFeatures(Document.LOK_FEATURE_DOCUMENT_PASSWORD);
mContext.setTileProvider(this);
mInputFile = input;
- File f = new File(mInputFile);
- final String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/lo_cached_" + f.getName();
-
- if(mContext.firstStart){
- File cacheFileObj = new File(cacheFile);
- if(cacheFileObj.exists()) {
- cacheFileObj.delete();
- }
- mContext.firstStart=false;
- }
Log.i(LOGTAG, "====> Loading file '" + input + "'");
- File fileToBeEncoded;
- if(isDocumentCached()){
- fileToBeEncoded = new File(cacheFile);
- }else{
- fileToBeEncoded = new File(input);
- }
+ File fileToBeEncoded = new File(input);
String encodedFileName = android.net.Uri.encode(fileToBeEncoded.getName());
mDocument = mOffice.documentLoad(
(new File(fileToBeEncoded.getParent(),encodedFileName)).getPath()
);
-
if (mDocument == null && !mContext.isPasswordProtected()) {
Log.i(LOGTAG, "====> mOffice.documentLoad() returned null, trying to restart 'Office' and loading again");
mOffice.destroy();
@@ -117,10 +99,6 @@ class LOKitTileProvider implements TileProvider {
Log.i(LOGTAG, "====> mDocument = " + mDocument);
- if(isSpreadsheet()) {
- mContext.setIsSpreadsheet(true); // Calc is treated differently e.g. DPI = 96f
- }
-
mDPI = LOKitShell.getDpi(mContext);
mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
@@ -142,27 +120,9 @@ class LOKitTileProvider implements TileProvider {
private void postLoad() {
mDocument.setMessageCallback(mMessageCallback);
- int parts = mDocument.getParts();
- Log.i(LOGTAG, "Document parts: " + parts);
- mContext.getDocumentPartView().clear();
-
+ resetParts();
// Writer documents always have one part, so hide the navigation drawer.
- if (mDocument.getDocumentType() != Document.DOCTYPE_TEXT) {
- for (int i = 0; i < parts; i++) {
- String partName = mDocument.getPartName(i);
- if (partName.isEmpty()) {
- partName = getGenericPartName(i);
- }else if (partName.startsWith("Slide") || partName.startsWith("Sheet") || partName.startsWith("Part")) {
- partName = getGenericPartName(i);
- }
- Log.i(LOGTAG, "Document part " + i + " name:'" + partName + "'");
-
- mDocument.setPart(i);
- resetDocumentSize();
- final DocumentPartView partView = new DocumentPartView(i, partName);
- mContext.getDocumentPartView().add(partView);
- }
- } else {
+ if (mDocument.getDocumentType() == Document.DOCTYPE_TEXT) {
mContext.disableNavigationDrawer();
mContext.getToolbarController().hideItem(R.id.action_parts);
}
@@ -182,14 +142,6 @@ class LOKitTileProvider implements TileProvider {
mContext.getDocumentPartViewListAdapter().notifyDataSetChanged();
}
});
- mContext.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (mContext.pendingInsertGraphic) {
- mContext.getFormattingController().popCompressImageGradeSelection();
- }
- }
- });
}
public void addPart(){
@@ -224,9 +176,9 @@ class LOKitTileProvider implements TileProvider {
}
public void resetParts(){
- int parts = mDocument.getParts();
mContext.getDocumentPartView().clear();
if (mDocument.getDocumentType() != Document.DOCTYPE_TEXT) {
+ int parts = mDocument.getParts();
for (int i = 0; i < parts; i++) {
String partName = mDocument.getPartName(i);
@@ -240,7 +192,9 @@ class LOKitTileProvider implements TileProvider {
mContext.getDocumentPartView().add(partView);
}
}
- } public void renamePart(String partName) {
+ }
+
+ public void renamePart(String partName) {
try{
for(int i=0; i<mDocument.getParts(); i++){
if(mContext.getDocumentPartView().get(i).partName.equals(partName)){
@@ -270,7 +224,7 @@ class LOKitTileProvider implements TileProvider {
public void removePart() {
try{
- if(isSpreadsheet() == false && isPresentation() == false) {
+ if (!isSpreadsheet() && !isPresentation()) {
//document must be spreadsheet or presentation
return;
}
@@ -295,38 +249,37 @@ class LOKitTileProvider implements TileProvider {
}
}
-
-
@Override
- public void saveDocumentAs(final String filePath, String format) {
+ public boolean saveDocumentAs(final String filePath, String format, boolean takeOwnership) {
+ String options = "";
+ if (takeOwnership) {
+ options = "TakeOwnership";
+ }
+
final String newFilePath = "file://" + filePath;
Log.d("saveFilePathURL", newFilePath);
LOKitShell.showProgressSpinner(mContext);
- mDocument.saveAs(newFilePath, format, "");
+ mDocument.saveAs(newFilePath, format, options);
+ final boolean ok;
if (!mOffice.getError().isEmpty()){
+ ok = true;
Log.e("Save Error", mOffice.getError());
if (format.equals("svg")) {
// error in creating temp slideshow svg file
Log.d(LOGTAG, "Error in creating temp slideshow svg file");
} else if(format.equals("pdf")){
Log.d(LOGTAG, "Error in creating pdf file");
+ } else {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
// There was some error
- mContext.showCustomStatusMessage(mContext.getString(R.string.unable_to_export_pdf));
- }
- });
- }else {
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // There was some error
- mContext.showSaveStatusMessage(true);
+ mContext.showCustomStatusMessage(mContext.getString(R.string.unable_to_save));
}
});
}
} else {
+ ok = false;
if (format.equals("svg")) {
// successfully created temp slideshow svg file
LOKitShell.getMainHandler().post(new Runnable() {
@@ -335,99 +288,49 @@ class LOKitTileProvider implements TileProvider {
mContext.startPresentation(newFilePath);
}
});
- }else if(format.equals("pdf")){
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // There was no error
- mContext.showCustomStatusMessage(mContext.getString(R.string.pdf_exported_at)+filePath);
- }
- });
- } else {
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- // There was no error
- mContext.showSaveStatusMessage(false);
- }
- });
+ } else if (takeOwnership) {
+ mInputFile = filePath;
}
}
LOKitShell.hideProgressSpinner(mContext);
+ return ok;
}
- public void exportToPDF(boolean print){
- String dir = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Documents";
- File docDir = new File(dir);
- if(!docDir.exists()){
- docDir.mkdir();
- }
- String mInputFileName = (new File(mInputFile)).getName();
- String file = mInputFileName.substring(0,(mInputFileName.length()-3))+"pdf";
- if(print){
- String cacheFile = mContext.getExternalCacheDir().getAbsolutePath()
- + "/" + file;
- mDocument.saveAs("file://"+cacheFile,"pdf","");
- printDocument(cacheFile);
- }else{
- saveDocumentAs(dir+"/"+file,"pdf");
- }
- }
-
- private void printDocument(String cacheFile) {
- if (Build.VERSION.SDK_INT >= 19) {
- try {
- PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
- PrintDocumentAdapter printAdapter = new PDFDocumentAdapter(mContext, cacheFile);
- printManager.print("Document", printAdapter, new PrintAttributes.Builder().build());
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- } else {
- mContext.showCustomStatusMessage(mContext.getString(R.string.printing_not_supported));
- }
- }
-
- public boolean isDocumentCached(){
- File input = new File(mInputFile);
- final String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/lo_cached_" + input.getName();
- File cacheFileObj = new File(cacheFile);
- if(cacheFileObj.exists())
- return true;
-
+ @Override
+ public boolean saveDocumentAs(final String filePath, boolean takeOwnership) {
+ final int docType = mDocument.getDocumentType();
+ if (docType == Document.DOCTYPE_TEXT)
+ return saveDocumentAs(filePath, "odt", takeOwnership);
+ else if (docType == Document.DOCTYPE_SPREADSHEET)
+ return saveDocumentAs(filePath, "ods", takeOwnership);
+ else if (docType == Document.DOCTYPE_PRESENTATION)
+ return saveDocumentAs(filePath, "odp", takeOwnership);
+ else if (docType == Document.DOCTYPE_DRAWING)
+ return saveDocumentAs(filePath, "odg", takeOwnership);
+
+ Log.w(LOGTAG, "Cannot determine file format from document. Not saving.");
return false;
}
- public void cacheDocument() {
- String cacheDir = mContext.getExternalCacheDir().getAbsolutePath();
- File input = new File(mInputFile);
- final String cacheFile = cacheDir + "/lo_cached_" + input.getName();
- Log.i(LOGTAG, "cacheDocument: " + cacheFile);
- if(isDocumentCached()){
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Save"));
- }else if(mDocument != null){
- mDocument.saveAs("file://"+cacheFile, FileUtilities.getExtension(input.getPath()).substring(1),"");
- }else{
- Log.w(LOGTAG, "mDocument was null when trying to save cacheDocument: " + cacheFile);
+ public void printDocument() {
+ String mInputFileName = (new File(mInputFile)).getName();
+ String file = mInputFileName.substring(0,(mInputFileName.length()-3))+"pdf";
+ String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/" + file;
+ mDocument.saveAs("file://"+cacheFile,"pdf","");
+ try {
+ PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
+ PrintDocumentAdapter printAdapter = new PDFDocumentAdapter(mContext, cacheFile);
+ printManager.print("Document", printAdapter, new PrintAttributes.Builder().build());
+
+ } catch (Exception e) {
+ e.printStackTrace();
}
}
public void saveDocument(){
- if(isDocumentCached()){
- String format = FileUtilities.getExtension(mInputFile).substring(1);
- String cacheDir = mContext.getExternalCacheDir().getAbsolutePath();
- File input = new File(mInputFile);
- final String cacheFile = cacheDir + "/lo_cached_" + input.getName();
- String path = input.getAbsolutePath();
- saveDocumentAs(path, format);
- (new File(cacheFile)).delete();
- }else{
- mContext.saveDocument();
- }
+ mContext.saveDocument();
}
-
private void setupDocumentFonts() {
String values = mDocument.getCommandValues(".uno:CharFontName");
if (values == null || values.isEmpty())
@@ -674,6 +577,14 @@ class LOKitTileProvider implements TileProvider {
}
/**
+ * @see TileProvider#isDrawing()
+ */
+ @Override
+ public boolean isDrawing() {
+ return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_DRAWING;
+ }
+
+ /**
* @see TileProvider#isTextDocument()
*/
@Override
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeApplication.java b/android/source/src/java/org/libreoffice/LibreOfficeApplication.java
index cb79219fc999..ebe54cf27c64 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeApplication.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeApplication.java
@@ -10,11 +10,11 @@
package org.libreoffice;
-import android.app.Application;
import android.content.Context;
import android.os.Handler;
+import androidx.multidex.MultiDexApplication;
-public class LibreOfficeApplication extends Application {
+public class LibreOfficeApplication extends MultiDexApplication {
private static Handler mainHandler;
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index cbc628e94e48..cf60ff37c5da 100644
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -1,6 +1,5 @@
package org.libreoffice;
-import android.app.Activity;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -9,19 +8,18 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.RectF;
import android.net.Uri;
-import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import android.support.design.widget.BottomSheetBehavior;
-import android.support.design.widget.Snackbar;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
+import android.provider.DocumentsContract;
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
+import com.google.android.material.snackbar.Snackbar;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
@@ -36,24 +34,25 @@ import android.widget.Toast;
import org.libreoffice.overlay.CalcHeadersController;
import org.libreoffice.overlay.DocumentOverlay;
-import org.libreoffice.storage.DocumentProviderFactory;
-import org.libreoffice.storage.IFile;
import org.libreoffice.ui.FileUtilities;
import org.libreoffice.ui.LibreOfficeUIActivity;
import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerView;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;
+import java.util.UUID;
/**
* Main activity of the LibreOffice App. It is started in the UI thread.
@@ -61,10 +60,11 @@ import java.util.List;
public class LibreOfficeMainActivity extends AppCompatActivity implements SettingsListenerModel.OnSettingsPreferenceChangedListener {
private static final String LOGTAG = "LibreOfficeMainActivity";
- private static final String DEFAULT_DOC_PATH = "/assets/example.odt";
- private static final String ENABLE_EXPERIMENTAL_PREFS_KEY = "ENABLE_EXPERIMENTAL";
+ public static final String ENABLE_EXPERIMENTAL_PREFS_KEY = "ENABLE_EXPERIMENTAL";
private static final String ASSETS_EXTRACTED_PREFS_KEY = "ASSETS_EXTRACTED";
private static final String ENABLE_DEVELOPER_PREFS_KEY = "ENABLE_DEVELOPER";
+ private static final int REQUEST_CODE_SAVEAS = 12345;
+ private static final int REQUEST_CODE_EXPORT_TO_PDF = 12346;
//TODO "public static" is a temporary workaround
public static LOKitThread loKitThread;
@@ -73,23 +73,20 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private static boolean mIsExperimentalMode;
private static boolean mIsDeveloperMode;
-
- private int providerId;
- private URI documentUri;
+ private static boolean mbISReadOnlyMode;
private DrawerLayout mDrawerLayout;
Toolbar toolbarTop;
private ListView mDrawerList;
- private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
+ private final List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
- private int partIndex=-1;
- private File mInputFile;
private DocumentOverlay mDocumentOverlay;
+ /** URI to save the document to. */
+ private Uri mDocumentUri;
+ /** Temporary local copy of the document. */
private File mTempFile = null;
private File mTempSlideShowFile = null;
- private String newDocumentType = null;
- public boolean firstStart = true;
BottomSheetBehavior bottomToolbarSheetBehavior;
BottomSheetBehavior toolbarColorPickerBottomSheetBehavior;
@@ -100,11 +97,10 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private SearchController mSearchController;
private UNOCommandsController mUNOCommandsController;
private CalcHeadersController mCalcHeadersController;
- private boolean mIsSpreadsheet;
private LOKitTileProvider mTileProvider;
private String mPassword;
private boolean mPasswordProtected;
- public boolean pendingInsertGraphic; // boolean indicating a pending insert graphic action, used in LOKitTileProvider.postLoad()
+ private boolean mbSkipNextRefresh;
public GeckoLayerClient getLayerClient() {
return mLayerClient;
@@ -118,17 +114,11 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
return mIsDeveloperMode;
}
- public boolean usesTemporaryFile() {
- return mTempFile != null;
- }
-
private boolean isKeyboardOpen = false;
private boolean isFormattingToolbarOpen = false;
private boolean isSearchToolbarOpen = false;
private static boolean isDocumentChanged = false;
private boolean isUNOCommandsToolbarOpen = false;
- public boolean isNewDocument = false;
- private long lastModified = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -168,8 +158,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
layerView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
- if(keyEvent.getKeyCode() != KeyEvent.KEYCODE_BACK){
- isDocumentChanged=true;
+ if(!isReadOnlyMode() && keyEvent.getKeyCode() != KeyEvent.KEYCODE_BACK){
+ setDocumentChanged(true);
}
return false;
}
@@ -178,40 +168,54 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
// create TextCursorLayer
mDocumentOverlay = new DocumentOverlay(this, layerView);
- // New document type string is not null, meaning we want to open a new document
- if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
- String newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
- String newFilePath = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_FILE_PATH_KEY);
+ mbISReadOnlyMode = !isExperimentalMode();
- // Load the new document
- loadNewDocument(newFilePath, newDocumentType);
- }
+ final Uri docUri = getIntent().getData();
+ if (docUri != null) {
+ if (docUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)
+ || docUri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
+ final boolean isReadOnlyDoc = (getIntent().getFlags() & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
+ mbISReadOnlyMode = !isExperimentalMode() || isReadOnlyDoc;
+ Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + docUri.getPath());
- if (getIntent().getData() != null) {
- if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
- if (copyFileToTemp() && mTempFile != null) {
- mInputFile = mTempFile;
- Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + getIntent().getData().getPath());
- toolbarTop.setTitle(mInputFile.getName());
- } else {
- // TODO: can't open the file
- Log.e(LOGTAG, "couldn't create temporary file from " + getIntent().getData());
- }
- } else if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_FILE)) {
- mInputFile = new File(getIntent().getData().getPath());
- Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + getIntent().getData().getPath());
- toolbarTop.setTitle(mInputFile.getName());
- // Gather data to rebuild IFile object later
- providerId = getIntent().getIntExtra(
- "org.libreoffice.document_provider_id", 0);
- documentUri = (URI) getIntent().getSerializableExtra(
- "org.libreoffice.document_uri");
+ String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), docUri);
+ toolbarTop.setTitle(displayName);
+
+ } else if (docUri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
+ mbISReadOnlyMode = true;
+ Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + docUri.getPath());
+ toolbarTop.setTitle(docUri.getLastPathSegment());
}
- } else {
- if (!isNewDocument) {
- mInputFile = new File(DEFAULT_DOC_PATH);
+ // create a temporary local copy to work with
+ boolean copyOK = copyFileToTemp(docUri) && mTempFile != null;
+ if (!copyOK) {
+ // TODO: can't open the file
+ Log.e(LOGTAG, "couldn't create temporary file from " + docUri);
+ return;
+ }
+
+ // if input doc is a template, a new doc is created and a proper URI to save to
+ // will only be available after a "Save As"
+ if (isTemplate(docUri)) {
+ toolbarTop.setTitle(R.string.default_document_name);
+ } else {
+ mDocumentUri = docUri;
}
+
+ LOKitShell.sendLoadEvent(mTempFile.getPath());
+ } else if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
+ // New document type string is not null, meaning we want to open a new document
+ String newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
+ // create a temporary local file, will be copied to the actual URI when saving
+ loadNewDocument(newDocumentType);
+ toolbarTop.setTitle(getString(R.string.default_document_name));
+ } else {
+ Log.e(LOGTAG, "No document specified. This should never happen.");
+ return;
}
+ // the loadDocument/loadNewDocument event already triggers a refresh as well,
+ // so there's no need to do another refresh in 'onStart'
+ mbSkipNextRefresh = true;
mDrawerLayout = findViewById(R.id.drawer_layout);
@@ -223,8 +227,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
mDrawerList.setOnItemClickListener(new DocumentPartClickListener());
}
- lastModified = mInputFile.lastModified();
-
mToolbarController.setupToolbars();
TabHost host = findViewById(R.id.toolbarTabHost);
@@ -274,22 +276,18 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
}
- // Loads a new Document
- private void loadNewDocument(String newFilePath, String newDocumentType) {
- mInputFile = new File(newFilePath);
- LOKitShell.sendNewDocumentLoadEvent(newFilePath, newDocumentType);
- isNewDocument = true;
- toolbarTop.setTitle(mInputFile.getName());
+ // Loads a new Document and saves it to a temporary file
+ private void loadNewDocument(String newDocumentType) {
+ String tempFileName = "LibreOffice_" + UUID.randomUUID().toString();
+ mTempFile = new File(this.getCacheDir(), tempFileName);
+ LOKitShell.sendNewDocumentLoadEvent(mTempFile.getPath(), newDocumentType);
}
public RectF getCurrentCursorPosition() {
return mDocumentOverlay.getCurrentCursorPosition();
}
- private boolean copyFileToTemp() {
- ContentResolver contentResolver = getContentResolver();
- FileChannel inputChannel = null;
- FileChannel outputChannel = null;
+ private boolean copyFileToTemp(Uri documentUri) {
// CSV files need a .csv suffix to be opened in Calc.
String suffix = null;
String intentType = getIntent().getType();
@@ -298,27 +296,9 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
suffix = ".csv";
try {
- try {
- AssetFileDescriptor assetFD = contentResolver.openAssetFileDescriptor(getIntent().getData(), "r");
- if (assetFD == null) {
- Log.e(LOGTAG, "couldn't create assetfiledescriptor from " + getIntent().getDataString());
- return false;
- }
- inputChannel = assetFD.createInputStream().getChannel();
- mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
-
- outputChannel = new FileOutputStream(mTempFile).getChannel();
- long bytesTransferred = 0;
- // might not copy all at once, so make sure everything gets copied...
- while (bytesTransferred < inputChannel.size()) {
- bytesTransferred += outputChannel.transferFrom(inputChannel, bytesTransferred, inputChannel.size());
- }
- Log.e(LOGTAG, "Success copying " + bytesTransferred + " bytes");
- return true;
- } finally {
- if (inputChannel != null) inputChannel.close();
- if (outputChannel != null) outputChannel.close();
- }
+ mTempFile = File.createTempFile("LibreOffice", suffix, this.getCacheDir());
+ final FileOutputStream outputStream = new FileOutputStream(mTempFile);
+ return copyUriToStream(documentUri, outputStream);
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
@@ -327,65 +307,150 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
/**
- * Save a new document
- * */
- public void saveAs(){
- LOKitShell.sendSaveAsEvent(mInputFile.getPath(), FileUtilities.getExtension(mInputFile.getPath()).substring(1));
- }
-
- /**
- * Save the document and invoke save on document provider to upload the file
- * to the cloud if necessary.
+ * Save the document.
*/
public void saveDocument() {
- if (!mInputFile.exists()) {
- // Needed for handling null in case new document is not created.
- mInputFile = new File(DEFAULT_DOC_PATH);
- lastModified = mInputFile.lastModified();
- }
Toast.makeText(this, R.string.message_saving, Toast.LENGTH_SHORT).show();
// local save
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND_NOTIFY, ".uno:Save", true));
}
- public void saveFilesToCloud(){
- final Activity activity = LibreOfficeMainActivity.this;
- final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- try {
- // rebuild the IFile object from the data passed in the Intent
- IFile mStorageFile = DocumentProviderFactory.getInstance()
- .getProvider(providerId).createFromUri(LibreOfficeMainActivity.this, documentUri);
- // call document provider save operation
- mStorageFile.saveDocument(mInputFile);
- }
- catch (final RuntimeException e) {
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(activity, e.getMessage(),
- Toast.LENGTH_SHORT).show();
- }
- });
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- }
- return null;
+ /**
+ * Open file chooser and save the document to the URI
+ * selected there.
+ */
+ public void saveDocumentAs() {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ String mimeType = getODFMimeTypeForDocument();
+ intent.setType(mimeType);
+ if (Build.VERSION.SDK_INT >= 26) {
+ intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, mDocumentUri);
+ }
+
+ startActivityForResult(intent, REQUEST_CODE_SAVEAS);
+ }
+
+ /**
+ * Saves the document under the given URI using ODF format
+ * and uses that URI from now on for all operations.
+ * @param newUri URI to save the document and use from now on.
+ */
+ private void saveDocumentAs(Uri newUri) {
+ mDocumentUri = newUri;
+ // save in ODF format
+ mTileProvider.saveDocumentAs(mTempFile.getPath(), true);
+ saveFileToOriginalSource();
+
+ String displayName = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), mDocumentUri);
+ toolbarTop.setTitle(displayName);
+ mbISReadOnlyMode = !isExperimentalMode();
+ getToolbarController().setupToolbars();
+ }
+
+ public void exportToPDF() {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType(FileUtilities.MIMETYPE_PDF);
+ // suggest directory and file name based on the doc
+ if (Build.VERSION.SDK_INT >= 26) {
+ intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, mDocumentUri);
+ }
+ final String displayName = toolbarTop.getTitle().toString();
+ final String suggestedFileName = FileUtilities.stripExtensionFromFileName(displayName) + ".pdf";
+ intent.putExtra(Intent.EXTRA_TITLE, suggestedFileName);
+
+ startActivityForResult(intent, REQUEST_CODE_EXPORT_TO_PDF);
+ }
+
+ private void exportToPDF(final Uri uri) {
+ boolean exportOK = false;
+ File tempFile = null;
+ try {
+ tempFile = File.createTempFile("LibreOffice_", ".pdf");
+ mTileProvider.saveDocumentAs(tempFile.getAbsolutePath(),"pdf", false);
+
+ try {
+ FileInputStream inputStream = new FileInputStream(tempFile);
+ exportOK = copyStreamToUri(inputStream, uri);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
}
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (tempFile != null && tempFile.exists()) {
+ tempFile.delete();
+ }
+ }
+
+ final int msgId = exportOK ? R.string.pdf_export_finished : R.string.unable_to_export_pdf;
+ LOKitShell.getMainHandler().post(new Runnable() {
@Override
- protected void onPostExecute(Void param) {
- Toast.makeText(activity, R.string.message_saved,
- Toast.LENGTH_SHORT).show();
- setDocumentChanged(false);
+ public void run() {
+ showCustomStatusMessage(getString(msgId));
}
- };
+ });
+ }
+
+ /**
+ * Returns the ODF MIME type that can be used for the current document,
+ * regardless of whether the document is an ODF Document or not
+ * (e.g. returns FileUtilities.MIMETYPE_OPENDOCUMENT_TEXT for a DOCX file).
+ * @return MIME type, or empty string, if no appropriate MIME type could be found.
+ */
+ private String getODFMimeTypeForDocument() {
+ if (mTileProvider.isTextDocument())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_TEXT;
+ else if (mTileProvider.isSpreadsheet())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_SPREADSHEET;
+ else if (mTileProvider.isPresentation())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_PRESENTATION;
+ else if (mTileProvider.isDrawing())
+ return FileUtilities.MIMETYPE_OPENDOCUMENT_GRAPHICS;
+ else {
+ Log.w(LOGTAG, "Cannot determine MIME type to use.");
+ return "";
+ }
+ }
- if (lastModified < mInputFile.lastModified()) {
- task.execute();
- lastModified = mInputFile.lastModified();
+ /**
+ * Returns whether the MIME type for the URI is considered one for a document template.
+ */
+ private boolean isTemplate(final Uri documentUri) {
+ final String mimeType = getContentResolver().getType(documentUri);
+ return FileUtilities.isTemplateMimeType(mimeType);
+ }
+
+ public void saveFileToOriginalSource() {
+ if (mTempFile == null || mDocumentUri == null || !mDocumentUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))
+ return;
+
+ boolean copyOK = false;
+ try {
+ final FileInputStream inputStream = new FileInputStream(mTempFile);
+ copyOK = copyStreamToUri(inputStream, mDocumentUri);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ if (copyOK) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(LibreOfficeMainActivity.this, R.string.message_saved,
+ Toast.LENGTH_SHORT).show();
+ }
+ });
+ setDocumentChanged(false);
} else {
- Toast.makeText(activity, R.string.message_save_incomplete, Toast.LENGTH_LONG).show();
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(LibreOfficeMainActivity.this, R.string.message_saving_failed,
+ Toast.LENGTH_SHORT).show();
+ }
+ });
}
}
@@ -412,28 +477,23 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
protected void onStart() {
Log.i(LOGTAG, "onStart..");
super.onStart();
- if (!isNewDocument){
- if (partIndex == -1)
- LOKitShell.sendLoadEvent(mInputFile.getPath());
- else
- LOKitShell.sendResumeEvent(mInputFile.getPath(), partIndex);
+ if (!mbSkipNextRefresh) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.REFRESH));
}
+ mbSkipNextRefresh = false;
}
@Override
protected void onStop() {
Log.i(LOGTAG, "onStop..");
- //save document to cache
- if (mTileProvider != null)
- mTileProvider.cacheDocument();
hideSoftKeyboardDirect();
- LOKitShell.sendCloseEvent();
super.onStop();
}
@Override
protected void onDestroy() {
Log.i(LOGTAG, "onDestroy..");
+ LOKitShell.sendCloseEvent();
mLayerClient.destroy();
super.onDestroy();
@@ -461,11 +521,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
- if (isNewDocument) {
- saveAs();
- } else {
- mTileProvider.saveDocument();
- }
+ mTileProvider.saveDocument();
isDocumentChanged=false;
onBackPressed();
break;
@@ -802,7 +858,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
// this function can only be called in InvalidationHandler.java
public void setPassword() {
- mTileProvider.setDocumentPassword("file://"+mInputFile.getPath(), mPassword);
+ mTileProvider.setDocumentPassword("file://" + mTempFile.getPath(), mPassword);
}
// setTileProvider is meant to let main activity have a handle of LOKit when dealing with password
@@ -844,12 +900,12 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
});
}
- public void setIsSpreadsheet(boolean b) {
- mIsSpreadsheet = b;
+ public static boolean isReadOnlyMode() {
+ return mbISReadOnlyMode;
}
- public boolean isSpreadsheet() {
- return mIsSpreadsheet;
+ public boolean hasLocationForSave() {
+ return mDocumentUri != null;
}
public static void setDocumentChanged (boolean changed) {
@@ -860,7 +916,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DocumentPartView partView = mDocumentPartViewListAdapter.getItem(position);
- partIndex = partView.partIndex;
LOKitShell.sendChangePartEvent(partView.partIndex);
mDrawerLayout.closeDrawer(mDrawerList);
}
@@ -923,12 +978,103 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
}
}
- // This method is used in LOKitTileProvider.java to show status of new file creation.
- public void showSaveStatusMessage(boolean error) {
- if (!error)
- Snackbar.make(mDrawerLayout, getString(R.string.create_new_file_success) + mInputFile.getName(), Snackbar.LENGTH_LONG).show();
- else
- Snackbar.make(mDrawerLayout, getString(R.string.create_new_file_error) + mInputFile.getName(), Snackbar.LENGTH_LONG).show(); }
+ /**
+ * Copies everything from the given input stream to the given output stream
+ * and closes both streams in the end.
+ * @return Whether copy operation was successful.
+ */
+ private boolean copyStream(InputStream inputStream, OutputStream outputStream) {
+ try {
+ byte[] buffer = new byte[4096];
+ int readBytes = inputStream.read(buffer);
+ while (readBytes != -1) {
+ outputStream.write(buffer, 0, readBytes);
+ readBytes = inputStream.read(buffer);
+ }
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ } finally {
+ try {
+ inputStream.close();
+ outputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Copies everything from the given Uri to the given OutputStream
+ * and closes the OutputStream in the end.
+ * The copy operation runs in a separate thread, but the method only returns
+ * after the thread has finished its execution.
+ * This can be used to copy in a blocking way when network access is involved,
+ * which is not allowed from the main thread, but that may happen when an underlying
+ * DocumentsProvider (like the NextCloud one) does network access.
+ */
+ private boolean copyUriToStream(final Uri inputUri, final OutputStream outputStream) {
+ class CopyThread extends Thread {
+ /** Whether copy operation was successful. */
+ private boolean result = false;
+
+ @Override
+ public void run() {
+ final ContentResolver contentResolver = getContentResolver();
+ try {
+ InputStream inputStream = contentResolver.openInputStream(inputUri);
+ result = copyStream(inputStream, outputStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ CopyThread copyThread = new CopyThread();
+ copyThread.start();
+ try {
+ // wait for copy operation to finish
+ // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
+ copyThread.join();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ return copyThread.result;
+ }
+
+ /**
+ * Copies everything from the given InputStream to the given URI and closes the
+ * InputStream in the end.
+ * @see LibreOfficeMainActivity#copyUriToStream(Uri, OutputStream)
+ * which does the same thing the other way around.
+ */
+ private boolean copyStreamToUri(final InputStream inputStream, final Uri outputUri) {
+ class CopyThread extends Thread {
+ /** Whether copy operation was successful. */
+ private boolean result = false;
+
+ @Override
+ public void run() {
+ final ContentResolver contentResolver = getContentResolver();
+ try {
+ OutputStream outputStream = contentResolver.openOutputStream(outputUri);
+ result = copyStream(inputStream, outputStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ CopyThread copyThread = new CopyThread();
+ copyThread.start();
+ try {
+ // wait for copy operation to finish
+ // NOTE: might be useful to add some indicator in UI for long copy operations involving network...
+ copyThread.join();
+ } catch(InterruptedException e) {
+ e.printStackTrace();
+ }
+ return copyThread.result;
+ }
public void showCustomStatusMessage(String message){
Snackbar.make(mDrawerLayout, message, Snackbar.LENGTH_LONG).show();
@@ -936,45 +1082,36 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
public void preparePresentation() {
if (getExternalCacheDir() != null) {
- String tempPath = getExternalCacheDir().getPath() + "/" + mInputFile.getName() + ".svg";
+ String tempPath = getExternalCacheDir().getPath() + "/" + mTempFile.getName() + ".svg";
mTempSlideShowFile = new File(tempPath);
if (mTempSlideShowFile.exists() && !isDocumentChanged) {
startPresentation("file://" + tempPath);
} else {
- LOKitShell.sendSaveAsEvent(tempPath, "svg");
+ LOKitShell.sendSaveCopyAsEvent(tempPath, "svg");
}
}
}
public void startPresentation(String tempPath) {
- // pre-KitKat android doesn't have chrome-based WebView, which is needed to show svg slideshow
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- Intent intent = new Intent(this, PresentationActivity.class);
- intent.setData(Uri.parse(tempPath));
- startActivity(intent);
- } else {
- // copy the svg file path to clipboard for the user to paste in a browser
- ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
- ClipData clip = ClipData.newPlainText("temp svg file path", tempPath);
- clipboard.setPrimaryClip(clip);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setMessage(R.string.alert_copy_svg_slide_show_to_clipboard)
- .setPositiveButton(R.string.alert_copy_svg_slide_show_to_clipboard_dismiss, null).show();
- }
+ Intent intent = new Intent(this, PresentationActivity.class);
+ intent.setData(Uri.parse(tempPath));
+ startActivity(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- mFormattingController.handleActivityResult(requestCode, resultCode, data);
- hideBottomToolbar();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_SAVEAS && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+ saveDocumentAs(fileUri);
+ } else if (requestCode == REQUEST_CODE_EXPORT_TO_PDF && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+ exportToPDF(fileUri);
+ } else {
+ mFormattingController.handleActivityResult(requestCode, resultCode, data);
+ hideBottomToolbar();
+ }
}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/source/src/java/org/libreoffice/LocaleHelper.java b/android/source/src/java/org/libreoffice/LocaleHelper.java
index 8c0e9b3fbbed..a87c63f09990 100644
--- a/android/source/src/java/org/libreoffice/LocaleHelper.java
+++ b/android/source/src/java/org/libreoffice/LocaleHelper.java
@@ -38,8 +38,7 @@ public class LocaleHelper {
Resources res = context.getResources();
Configuration cfg = res.getConfiguration();
cfg.locale = locale;
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
- cfg.setLayoutDirection(locale);
+ cfg.setLayoutDirection(locale);
res.updateConfiguration(cfg, res.getDisplayMetrics());
return context;
diff --git a/android/source/src/java/org/libreoffice/PasswordDialogFragment.java b/android/source/src/java/org/libreoffice/PasswordDialogFragment.java
index 112e35c4b7ed..08bc7f596894 100644
--- a/android/source/src/java/org/libreoffice/PasswordDialogFragment.java
+++ b/android/source/src/java/org/libreoffice/PasswordDialogFragment.java
@@ -4,9 +4,9 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.DialogFragment;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
diff --git a/android/source/src/java/org/libreoffice/PresentationActivity.java b/android/source/src/java/org/libreoffice/PresentationActivity.java
index 3308e6884fe9..ede7c0c40101 100644
--- a/android/source/src/java/org/libreoffice/PresentationActivity.java
+++ b/android/source/src/java/org/libreoffice/PresentationActivity.java
@@ -1,16 +1,14 @@
package org.libreoffice;
import android.content.Intent;
-import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v4.view.GestureDetectorCompat;
-import android.support.v7.app.AppCompatActivity;
+import androidx.annotation.Nullable;
+import androidx.core.view.GestureDetectorCompat;
+import androidx.appcompat.app.AppCompatActivity;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.ImageButton;
@@ -25,19 +23,10 @@ public class PresentationActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // First we hide the status bar
- if (Build.VERSION.SDK_INT < 16) {
- // If the Android version is lower than Jellybean, use this call to hide
- // the status bar.
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- } else {
- // If higher than Jellybean
- View decorView = getWindow().getDecorView();
- // Hide the status bar.
- int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
- decorView.setSystemUiVisibility(uiOptions);
- }
+ View decorView = getWindow().getDecorView();
+ // Hide the status bar.
+ int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
+ decorView.setSystemUiVisibility(uiOptions);
setContentView(R.layout.presentation_mode);
@@ -185,4 +174,4 @@ public class PresentationActivity extends AppCompatActivity {
private void pageRight() {
mWebView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
}
-} \ No newline at end of file
+}
diff --git a/android/source/src/java/org/libreoffice/SearchController.java b/android/source/src/java/org/libreoffice/SearchController.java
index a9414f7f7a71..6095e1fd2afe 100644
--- a/android/source/src/java/org/libreoffice/SearchController.java
+++ b/android/source/src/java/org/libreoffice/SearchController.java
@@ -11,7 +11,7 @@ import org.json.JSONException;
import org.json.JSONObject;
public class SearchController implements View.OnClickListener {
- private LibreOfficeMainActivity mActivity;
+ private final LibreOfficeMainActivity mActivity;
private enum SearchDirection {
UP, DOWN
@@ -69,15 +69,8 @@ public class SearchController implements View.OnClickListener {
ImageButton button = (ImageButton) view;
SearchDirection direction = SearchDirection.DOWN;
- switch(button.getId()) {
- case R.id.button_search_down:
- direction = SearchDirection.DOWN;
- break;
- case R.id.button_search_up:
- direction = SearchDirection.UP;
- break;
- default:
- break;
+ if (button.getId() == R.id.button_search_up) {
+ direction = SearchDirection.UP;
}
String searchText = ((EditText) mActivity.findViewById(R.id.search_string)).getText().toString();
diff --git a/android/source/src/java/org/libreoffice/ThumbnailCreator.java b/android/source/src/java/org/libreoffice/ThumbnailCreator.java
index 52870b67a5b9..c0c097747c69 100644
--- a/android/source/src/java/org/libreoffice/ThumbnailCreator.java
+++ b/android/source/src/java/org/libreoffice/ThumbnailCreator.java
@@ -71,7 +71,7 @@ public class ThumbnailCreator {
class ThumbnailCreationTask{
private final WeakReference<ImageView> imageViewReference;
- private int partNumber;
+ private final int partNumber;
private boolean cancelled = false;
public ThumbnailCreationTask(ImageView imageView, int partNumber) {
diff --git a/android/source/src/java/org/libreoffice/TileProvider.java b/android/source/src/java/org/libreoffice/TileProvider.java
index dabf30b834f7..c979a9883c13 100644
--- a/android/source/src/java/org/libreoffice/TileProvider.java
+++ b/android/source/src/java/org/libreoffice/TileProvider.java
@@ -22,9 +22,24 @@ import org.mozilla.gecko.gfx.IntSize;
public interface TileProvider {
/**
- * Save the current document.
+ * Save the current document under the given path.
+ * @param takeOwnership Whether to take ownership of the new file,
+ * i.e. whether the current document is changed to the
+ * newly saved document (takeOwnership = true),
+ * as compared to just saving a copy of the current document
+ * or exporting to a different file format.
+ * Must be 'false' when using this method for export to e.g. PNG or PDF.
+ * @return Whether saving was successful.
*/
- void saveDocumentAs(String filePath, String format);
+ boolean saveDocumentAs(String filePath, String format, boolean takeOwnership);
+
+ /**
+ * Saves the current document under the given path,
+ * using the default file format.
+ * @param takeOwnership (s. documentation for
+ * 'saveDocumentAs(String filePath, String format, boolean takeOwnership)')
+ */
+ boolean saveDocumentAs(String filePath, boolean takeOwnership);
/**
* Returns the page width in pixels.
@@ -72,6 +87,11 @@ public interface TileProvider {
void close();
/**
+ * Returns true if the current open document is a drawing.
+ */
+ boolean isDrawing();
+
+ /**
* Returns true if the current open document is a text document.
*/
boolean isTextDocument();
diff --git a/android/source/src/java/org/libreoffice/ToolbarController.java b/android/source/src/java/org/libreoffice/ToolbarController.java
index d21396cf4615..603d2258167e 100644
--- a/android/source/src/java/org/libreoffice/ToolbarController.java
+++ b/android/source/src/java/org/libreoffice/ToolbarController.java
@@ -11,7 +11,7 @@ package org.libreoffice;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
-import android.support.v7.widget.Toolbar;
+import androidx.appcompat.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
@@ -45,12 +45,12 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
clipboardManager = (ClipboardManager)mContext.getSystemService(Context.CLIPBOARD_SERVICE);
}
- public void disableMenuItem(final int menuItemId, final boolean disabled) {
+ private void enableMenuItem(final int menuItemId, final boolean enabled) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
MenuItem menuItem = mMainMenu.findItem(menuItemId);
if (menuItem != null) {
- menuItem.setEnabled(!disabled);
+ menuItem.setEnabled(enabled);
} else {
Log.e(LOGTAG, "MenuItem not found.");
}
@@ -72,6 +72,8 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
void switchToEditMode() {
if (!LOKitShell.isEditingEnabled())
return;
+
+ setEditModeOn(true);
// Ensure the change is done on UI thread
LOKitShell.getMainHandler().post(new Runnable() {
@Override
@@ -89,7 +91,6 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
}
mToolbarTop.setNavigationIcon(R.drawable.ic_check);
mToolbarTop.setLogo(null);
- setEditModeOn(true);
}
});
}
@@ -145,7 +146,7 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
@Override
public void run() {
mMainMenu.setGroupVisible(R.id.group_edit_actions, false);
- mToolbarTop.setNavigationIcon(R.drawable.lo_icon);
+ mToolbarTop.setNavigationIcon(R.mipmap.ic_launcher);
mToolbarTop.setLogo(null);
setEditModeOn(false);
mContext.hideBottomToolbar();
@@ -161,94 +162,91 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
@Override
public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_keyboard:
- mContext.showSoftKeyboard();
- break;
- case R.id.action_format:
- mContext.showFormattingToolbar();
- break;
- case R.id.action_about:
- mContext.showAbout();
- return true;
- case R.id.action_save:
- if (mContext.isNewDocument) {
- mContext.saveAs();
- } else {
- mContext.getTileProvider().saveDocument();
- }
- return true;
- case R.id.action_parts:
- mContext.openDrawer();
- return true;
- case R.id.action_exportToPDF:
- mContext.getTileProvider().exportToPDF(false);
- return true;
- case R.id.action_print:
- mContext.getTileProvider().exportToPDF(true);
- return true;
- case R.id.action_settings:
- mContext.showSettings();
- return true;
- case R.id.action_search:
- mContext.showSearchToolbar();
- return true;
- case R.id.action_undo:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Undo"));
- return true;
- case R.id.action_redo:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Redo"));
- return true;
- case R.id.action_presentation:
- mContext.preparePresentation();
- return true;
- case R.id.action_add_slide:
- mContext.addPart();
- return true;
- case R.id.action_add_worksheet:
- mContext.addPart();
- return true;
- case R.id.action_rename_worksheet:
- case R.id.action_rename_slide:
- mContext.renamePart();
- return true;
- case R.id.action_delete_worksheet:
- mContext.deletePart();
- return true;
- case R.id.action_delete_slide:
- mContext.deletePart();
- return true;
- case R.id.action_back:
- hideClipboardActions();
- return true;
- case R.id.action_copy:
- LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Copy"));
- clipData = ClipData.newPlainText("clipboard data", clipboardText);
- clipboardManager.setPrimaryClip(clipData);
- Toast.makeText(mContext, mContext.getResources().getString(R.string.action_text_copied), Toast.LENGTH_SHORT).show();
- return true;
- case R.id.action_paste:
- clipData = clipboardManager.getPrimaryClip();
- ClipData.Item clipItem = clipData.getItemAt(0);
- mContext.setDocumentChanged(true);
- return mContext.getTileProvider().paste("text/plain;charset=utf-16", clipItem.getText().toString());
- case R.id.action_cut:
- clipData = ClipData.newPlainText("clipboard data", clipboardText);
- clipboardManager.setPrimaryClip(clipData);
- LOKitShell.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
- mContext.setDocumentChanged(true);
- return true;
- case R.id.action_UNO_commands:
- mContext.showUNOCommandsToolbar();
- return true;
+ final int itemId = item.getItemId();
+ if (itemId == R.id.action_keyboard) {
+ mContext.showSoftKeyboard();
+ } else if (itemId == R.id.action_format) {
+ mContext.showFormattingToolbar();
+ } else if (itemId == R.id.action_about) {
+ mContext.showAbout();
+ return true;
+ } else if (itemId == R.id.action_save) {
+ mContext.getTileProvider().saveDocument();
+ return true;
+ } else if (itemId == R.id.action_save_as) {
+ mContext.saveDocumentAs();
+ return true;
+ } else if (itemId == R.id.action_parts) {
+ mContext.openDrawer();
+ return true;
+ } else if (itemId == R.id.action_exportToPDF) {
+ mContext.exportToPDF();
+ return true;
+ } else if (itemId == R.id.action_print) {
+ mContext.getTileProvider().printDocument();
+ return true;
+ } else if (itemId == R.id.action_settings) {
+ mContext.showSettings();
+ return true;
+ } else if (itemId == R.id.action_search) {
+ mContext.showSearchToolbar();
+ return true;
+ } else if (itemId == R.id.action_undo) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Undo"));
+ return true;
+ } else if (itemId == R.id.action_redo) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Redo"));
+ return true;
+ } else if (itemId == R.id.action_presentation) {
+ mContext.preparePresentation();
+ return true;
+ } else if (itemId == R.id.action_add_slide || itemId == R.id.action_add_worksheet) {
+ mContext.addPart();
+ return true;
+ } else if (itemId == R.id.action_rename_worksheet || itemId == R.id.action_rename_slide) {
+ mContext.renamePart();
+ return true;
+ } else if (itemId == R.id.action_delete_worksheet || itemId == R.id.action_delete_slide) {
+ mContext.deletePart();
+ return true;
+ } else if (itemId == R.id.action_back) {
+ hideClipboardActions();
+ return true;
+ } else if (itemId == R.id.action_copy) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Copy"));
+ clipData = ClipData.newPlainText("clipboard data", clipboardText);
+ clipboardManager.setPrimaryClip(clipData);
+ Toast.makeText(mContext, mContext.getResources().getString(R.string.action_text_copied), Toast.LENGTH_SHORT).show();
+ return true;
+ } else if (itemId == R.id.action_paste) {
+ clipData = clipboardManager.getPrimaryClip();
+ ClipData.Item clipItem = clipData.getItemAt(0);
+ mContext.setDocumentChanged(true);
+ return mContext.getTileProvider().paste("text/plain;charset=utf-16", clipItem.getText().toString());
+ } else if (itemId == R.id.action_cut) {
+ clipData = ClipData.newPlainText("clipboard data", clipboardText);
+ clipboardManager.setPrimaryClip(clipData);
+ LOKitShell.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
+ mContext.setDocumentChanged(true);
+ return true;
+ } else if (itemId == R.id.action_UNO_commands) {
+ mContext.showUNOCommandsToolbar();
+ return true;
}
return false;
}
void setupToolbars() {
- if (mContext.usesTemporaryFile()) {
- disableMenuItem(R.id.action_save, true);
- Toast.makeText(mContext, mContext.getString(R.string.temp_file_saving_disabled), Toast.LENGTH_LONG).show();
+ if (LibreOfficeMainActivity.isExperimentalMode()) {
+ boolean enableSaveEntry = !LibreOfficeMainActivity.isReadOnlyMode() && mContext.hasLocationForSave();
+ enableMenuItem(R.id.action_save, enableSaveEntry);
+ if (LibreOfficeMainActivity.isReadOnlyMode()) {
+ // show message in case experimental mode is enabled (i.e. editing is supported in general),
+ // but current document is readonly
+ Toast.makeText(mContext, mContext.getString(R.string.readonly_file), Toast.LENGTH_LONG).show();
+ }
+ } else {
+ hideItem(R.id.action_save);
}
mMainMenu.findItem(R.id.action_parts).setVisible(mContext.isDrawerEnabled());
}
diff --git a/android/source/src/java/org/libreoffice/UNOCommandsController.java b/android/source/src/java/org/libreoffice/UNOCommandsController.java
index 9453b3bd07b7..cba67732cce1 100644
--- a/android/source/src/java/org/libreoffice/UNOCommandsController.java
+++ b/android/source/src/java/org/libreoffice/UNOCommandsController.java
@@ -8,7 +8,7 @@
package org.libreoffice;
import android.content.DialogInterface;
-import android.support.v7.app.AlertDialog;
+import androidx.appcompat.app.AlertDialog;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.EditText;
@@ -21,7 +21,7 @@ import org.json.JSONObject;
import static org.libreoffice.SearchController.addProperty;
class UNOCommandsController implements View.OnClickListener {
- private LibreOfficeMainActivity mActivity;
+ private final LibreOfficeMainActivity mActivity;
private JSONObject mRootJSON = new JSONObject();
@@ -72,7 +72,7 @@ class UNOCommandsController implements View.OnClickListener {
})
.setIcon(android.R.drawable.ic_dialog_info)
.show();
- TextView textView = (TextView) dialog.findViewById(android.R.id.message);
+ TextView textView = dialog.findViewById(android.R.id.message);
if (textView != null) {
textView.setScroller(new Scroller(mActivity));
textView.setVerticalScrollBarEnabled(true);
@@ -82,4 +82,4 @@ class UNOCommandsController implements View.OnClickListener {
e.printStackTrace();
}
}
-} \ No newline at end of file
+}
diff --git a/android/source/src/java/org/libreoffice/canvas/BitmapHandle.java b/android/source/src/java/org/libreoffice/canvas/BitmapHandle.java
index e46173db518f..51f6f7cf8611 100644
--- a/android/source/src/java/org/libreoffice/canvas/BitmapHandle.java
+++ b/android/source/src/java/org/libreoffice/canvas/BitmapHandle.java
@@ -5,7 +5,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
-import android.support.v4.content.ContextCompat;
+import androidx.core.content.ContextCompat;
/**
* Bitmap handle canvas element is used to show a handle on the screen.
diff --git a/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java b/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
index c1f8e74e7ba2..a285234bc8b0 100644
--- a/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
+++ b/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
@@ -4,29 +4,40 @@ import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextPaint;
public class CalcHeaderCell extends CommonCanvasElement {
- private TextPaint mTextPaint = new TextPaint();
- private Paint mBgPaint = new Paint();
- private RectF mBounds;
- private String mText;
+ private final TextPaint mTextPaint = new TextPaint();
+
+ private final Paint mFramePaint = new Paint();
+ private final Paint mBgPaint = new Paint();
+ private final RectF mBounds;
+ private final Rect mTextBounds = new Rect();
+ private final String mText;
public CalcHeaderCell(float left, float top, float width, float height, String text, boolean selected) {
mBounds = new RectF(left, top, left + width, top + height);
+
+ mFramePaint.setStyle(Style.STROKE);
+ mFramePaint.setColor(Color.BLACK);
+
+ mBgPaint.setStyle(Style.FILL);
+ mBgPaint.setColor(Color.GRAY);
+ // draw background more intensely when cell is selected
if (selected) {
- // if the cell is selected, display filled
- mBgPaint.setStyle(Style.FILL_AND_STROKE);
+ mBgPaint.setAlpha(100);
} else {
- // if not, display only the frame
- mBgPaint.setStyle(Style.STROKE);
+ mBgPaint.setAlpha(25);
}
- mBgPaint.setColor(Color.GRAY);
- mBgPaint.setAlpha(100); // hard coded for now
- mTextPaint.setColor(Color.GRAY);
+
+ mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextSize(24f); // hard coded for now
+ mTextPaint.setTextAlign(Paint.Align.CENTER);
mText = text;
+
+ mTextPaint.getTextBounds(mText, 0, mText.length(), mTextBounds);
}
/**
@@ -49,6 +60,7 @@ public class CalcHeaderCell extends CommonCanvasElement {
@Override
public void onDraw(Canvas canvas) {
canvas.drawRect(mBounds, mBgPaint);
- canvas.drawText(mText, mBounds.left, mBounds.bottom, mTextPaint);
+ canvas.drawRect(mBounds, mFramePaint);
+ canvas.drawText(mText, mBounds.centerX(), mBounds.centerY() - mTextBounds.centerY(), mTextPaint);
}
-} \ No newline at end of file
+}
diff --git a/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java b/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
index 40c9ddcd8cea..8b99c292cbc5 100644
--- a/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
+++ b/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
@@ -4,7 +4,7 @@ import android.content.Context;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
-import android.support.design.widget.Snackbar;
+import com.google.android.material.snackbar.Snackbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Gravity;
diff --git a/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java b/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
index a8b2d2048409..98af7a9554e7 100644
--- a/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
+++ b/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
@@ -4,7 +4,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
-import android.support.v4.view.GestureDetectorCompat;
+import androidx.core.view.GestureDetectorCompat;
import android.util.AttributeSet;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
@@ -101,12 +101,8 @@ public class CalcHeadersView extends View {
bottom = -origin.y + zoom*mDimens.get(i);
if (top <= getHeight() && bottom >= 0) {
inRangeOfVisibleHeaders = true;
- if (mCellCursorRect != null && bottom > mCellCursorRect.top - origin.y && top < mCellCursorRect.bottom - origin.y) {
- // if cell is within current selected portion
- new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i), true).onDraw(canvas);
- } else {
- new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i), false).onDraw(canvas);
- }
+ boolean isSelected = mCellCursorRect != null && bottom > mCellCursorRect.top - origin.y && top < mCellCursorRect.bottom - origin.y;
+ new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i), isSelected).onDraw(canvas);
} else {
if (inRangeOfVisibleHeaders) {
break;
@@ -116,12 +112,8 @@ public class CalcHeadersView extends View {
left = -origin.x + zoom*mDimens.get(i-1);
right = -origin.x + zoom*mDimens.get(i);
if (left <= getWidth() && right >= 0) {
- if (mCellCursorRect != null && right > mCellCursorRect.left - origin.x && left < mCellCursorRect.right - origin.x) {
- // if cell is within current selected portion
- new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i), true).onDraw(canvas);
- } else {
- new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i), false).onDraw(canvas);
- }
+ boolean isSelected = mCellCursorRect != null && right > mCellCursorRect.left - origin.x && left < mCellCursorRect.right - origin.x;
+ new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i), isSelected).onDraw(canvas);
} else {
if (inRangeOfVisibleHeaders) {
break;
diff --git a/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java b/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java
deleted file mode 100644
index acf5aebcd6c6..000000000000
--- a/android/source/src/java/org/libreoffice/storage/DocumentProviderFactory.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.libreoffice.storage.external.ExtsdDocumentsProvider;
-import org.libreoffice.storage.external.OTGDocumentsProvider;
-import org.libreoffice.storage.local.LocalDocumentsDirectoryProvider;
-import org.libreoffice.storage.local.LocalDocumentsProvider;
-import org.libreoffice.storage.owncloud.OwnCloudProvider;
-
-import android.content.Context;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-
-/**
- * Keeps the instances of the available IDocumentProviders in the system.
- * Instances are maintained in a sorted list and providers have to be
- * accessed from their position.
- *
- * The factory follows the Singleton pattern, there is only one instance of it
- * in the application and it must be retrieved with
- * DocumentProviderFactory.getInstance().
- */
-public final class DocumentProviderFactory {
- public static int EXTSD_PROVIDER_INDEX = 2;
- public static int OTG_PROVIDER_INDEX = 3;
-
- /**
- * Private factory instance for the Singleton pattern.
- */
- private static DocumentProviderFactory instance = null;
-
- private IDocumentProvider[] providers;
-
- private String[] providerNames;
-
- private DocumentProviderFactory() {
- // private to prevent external instances of the factory
- }
-
- /**
- * Initializes the factory with some context. If this method is called for
- * twice or more times those calls will have no effect.
- *
- * @param context
- * Application context for the factory.
- */
- public static void initialize(Context context) {
- if (instance == null) {
- // initialize instance
- instance = new DocumentProviderFactory();
-
- // initialize document providers list
- instance.providers = new IDocumentProvider[5];
- instance.providers[0] = new LocalDocumentsDirectoryProvider(0);
- instance.providers[1] = new LocalDocumentsProvider(1);
- instance.providers[OTG_PROVIDER_INDEX] = new OTGDocumentsProvider(OTG_PROVIDER_INDEX, context);
- instance.providers[4] = new OwnCloudProvider(4, context);
-
- instance.providers[EXTSD_PROVIDER_INDEX] = new ExtsdDocumentsProvider(EXTSD_PROVIDER_INDEX, context);
-
- // initialize document provider names list
- instance.providerNames = new String[instance.providers.length];
- for (int i = 0; i < instance.providers.length; i++) {
- instance.providerNames[i] = context.getString(instance
- .getProvider(i).getNameResource());
- }
- }
- }
-
- /**
- * Retrieve the unique instance of the factory.
- *
- * @return the unique factory object or null if it is not yet initialized.
- */
- public static DocumentProviderFactory getInstance() {
- return instance;
- }
-
- /**
- * Retrieve the provider associated to a certain id.
- *
- * @param id
- * @return document provider with that id.
- */
- public IDocumentProvider getProvider(int id) {
- // as for now, id == position in providers array
- return providers[id];
- }
-
- /**
- * Returns a sorted list of the names of the providers. Order is meaningful
- * to retrieve the actual provider object with getProvider().
- *
- * @return Array with the names of the available providers.
- */
- public String[] getNames() {
- return providerNames;
- }
-
- /**
- * Returns the default provider.
- *
- * @return default provider.
- */
- public IDocumentProvider getDefaultProvider() {
- return providers[0];
- }
-
- public Set<OnSharedPreferenceChangeListener> getChangeListeners() {
- Set<OnSharedPreferenceChangeListener> listeners =
- new HashSet<OnSharedPreferenceChangeListener>();
- for (IDocumentProvider provider : providers) {
- if (provider instanceof OnSharedPreferenceChangeListener)
- listeners.add((OnSharedPreferenceChangeListener) provider);
- }
- return listeners;
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/DocumentProviderSettingsActivity.java b/android/source/src/java/org/libreoffice/storage/DocumentProviderSettingsActivity.java
deleted file mode 100644
index b842e79fafd6..000000000000
--- a/android/source/src/java/org/libreoffice/storage/DocumentProviderSettingsActivity.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage;
-
-import java.util.Set;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.external.BrowserSelectorActivity;
-
-import android.content.Intent;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
-import android.preference.PreferenceManager;
-import android.preference.PreferenceScreen;
-import android.support.v7.app.AppCompatActivity;
-
-public class DocumentProviderSettingsActivity extends AppCompatActivity {
-
- public static final String KEY_PREF_OWNCLOUD_SERVER = "pref_server_url";
- public static final String KEY_PREF_OWNCLOUD_USER_NAME = "pref_user_name";
- public static final String KEY_PREF_OWNCLOUD_PASSWORD = "pref_password";
- public static final String KEY_PREF_EXTERNAL_SD_PATH_URI = "pref_extsd_path_uri";
- public static final String KEY_PREF_OTG_PATH_URI = "pref_otg_path_uri";
-
- private Set<OnSharedPreferenceChangeListener> listeners;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Display the fragment as the main content.
- getFragmentManager().beginTransaction()
- .replace(android.R.id.content, new SettingsFragment()).commit();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- listeners = DocumentProviderFactory.getInstance().getChangeListeners();
- for (OnSharedPreferenceChangeListener listener : listeners) {
- PreferenceManager.getDefaultSharedPreferences(this)
- .registerOnSharedPreferenceChangeListener(listener);
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- for (OnSharedPreferenceChangeListener listener : listeners) {
- PreferenceManager.getDefaultSharedPreferences(this)
- .unregisterOnSharedPreferenceChangeListener(listener);
- }
- }
-
- public static class SettingsFragment extends PreferenceFragment {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // Load the preferences from an XML resource
- addPreferencesFromResource(R.xml.documentprovider_preferences);
-
- PreferenceScreen extSDPreference =
- (PreferenceScreen)findPreference(KEY_PREF_EXTERNAL_SD_PATH_URI);
- PreferenceScreen otgPreference =
- (PreferenceScreen)findPreference(KEY_PREF_OTG_PATH_URI);
-
- extSDPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startBrowserSelectorActivity(KEY_PREF_EXTERNAL_SD_PATH_URI,
- BrowserSelectorActivity.MODE_EXT_SD);
- return true;
- }
- });
- otgPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- startBrowserSelectorActivity(KEY_PREF_OTG_PATH_URI,
- BrowserSelectorActivity.MODE_OTG);
- return true;
- }
- });
-
- }
-
- private void startBrowserSelectorActivity(String prefKey, String mode) {
- Intent i = new Intent(getActivity(), BrowserSelectorActivity.class);
- i.putExtra(BrowserSelectorActivity.PREFERENCE_KEY_EXTRA, prefKey);
- i.putExtra(BrowserSelectorActivity.MODE_EXTRA, mode);
- startActivity(i);
- }
-
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java b/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java
deleted file mode 100644
index 044d7ddb422b..000000000000
--- a/android/source/src/java/org/libreoffice/storage/IDocumentProvider.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage;
-
-import android.content.Context;
-
-import java.net.URI;
-
-/**
- * Represents a Document Provider, an object able to provide documents from a
- * certain source (e.g. local documents, DropBox, Google Docs).
- */
-public interface IDocumentProvider {
-
- /**
- * Provides the content root element for the Document Provider.
- *
- * @return Content root element.
- * @throws RuntimeException in case of error.
- * @param context
- */
- IFile getRootDirectory(Context context);
-
- /**
- * Transforms some URI into the IFile object that represents that content.
- *
- *
- * @param context
- * @param uri
- * URI pointing to some content object that has been previously
- * retrieved with IFile.getUri().
- * @return IFile object pointing to the content represented by uri.
- * @throws RuntimeException in case of error.
- */
- IFile createFromUri(Context context, URI uri);
-
- /**
- * Get internationalized name for this provider. This name is intended to be
- * shown in the UI.
- *
- * @return string resource pointing to the provider name.
- */
- int getNameResource();
-
- /**
- * Provides the unique ID for a document provider instance in a program.
- *
- * This ID should be set when the instance is built. It could be used to
- * tell two instances of the same document provider apart, e. g. two
- * instances of OwnCloudProvider pointing to different servers.
- *
- * @return Unique ID for a document provider instance.
- */
- int getId();
-
- /**
- * Checks if the Document Provider is available or not.
- *
- * @return A boolean value based on provider availability.
- * @param context
- */
- boolean checkProviderAvailability(Context context);
-}
diff --git a/android/source/src/java/org/libreoffice/storage/IFile.java b/android/source/src/java/org/libreoffice/storage/IFile.java
deleted file mode 100644
index c9cfa7f1198d..000000000000
--- a/android/source/src/java/org/libreoffice/storage/IFile.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage;
-
-import android.content.Context;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.net.URI;
-import java.util.Date;
-import java.util.List;
-
-/**
- * An abstraction of the File class, intended to be implemented by different
- * Document Providers.
- *
- * It represents a file or a directory in the context of a certain Document
- * Provider. It wraps the file-related operations and provides access to the
- * final document as a local File, downloading it if necessary.
- */
-public interface IFile {
-
- /**
- * Provides a URI that represents this IFile object.
- *
- * @return URI that represents this IFile object in the context of the
- * Document Provider that created it. The URI can be transformed
- * back into an IFile object with IDocumentProvider.createFromUri().
- */
- URI getUri();
-
- /**
- * Returns the name of the file or directory represented by this file.
- *
- * @return This file's name.
- */
- String getName();
-
- /**
- * Indicates if this file represents a directory in the context of the
- * Document Provider which originated it.
- *
- * @return true if this file is a directory, false otherwise.
- */
- boolean isDirectory();
-
- /**
- * Returns the file size in bytes.
- *
- * @return file size in bytes, 0 if the file does not exist.
- */
- long getSize();
-
- /**
- * Returns the time when this file was last modified, measured in
- * milliseconds since January 1st, 1970, midnight.
- *
- * @return time when this file was last modified, or 0 if the file does not
- * exist.
- */
- Date getLastModified();
-
- /**
- * Returns a list containing the files in the directory represented by this
- * file.
- *
- * @return list of files contained by this directory, or an empty list if
- * this is not a directory.
- * @throws RuntimeException in case of error.
- */
- List<IFile> listFiles();
-
- /**
- * Gets the list of files contained in the directory represented by this
- * file, and filters it through some FilenameFilter.
- *
- * @param filter
- * the filter to match names against.
- * @return filtered list of files contained by this directory, or an empty
- * list if this is not a directory.
- * @throws RuntimeException in case of error.
- */
- List<IFile> listFiles(FileFilter filter);
-
- /**
- * Returns the pparent of this file.
- *
- * @return this file's parent or null if it does not have it.
- * @param context
- */
- IFile getParent(Context context);
-
- /**
- * Returns the document wrapped by this IFile as a local file. The result
- * for a directory is not defined.
- *
- * @return local file containing the document wrapped by this object.
- * @throws RuntimeException in case of error.
- */
- File getDocument();
-
- /**
- * Replaces the wrapped document with a new version of it.
- *
- * @param file
- * A local file pointing to the new version of the document.
- */
- void saveDocument(File file);
-}
diff --git a/android/source/src/java/org/libreoffice/storage/IOUtils.java b/android/source/src/java/org/libreoffice/storage/IOUtils.java
deleted file mode 100644
index f345f5cbed3b..000000000000
--- a/android/source/src/java/org/libreoffice/storage/IOUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.libreoffice.storage;
-
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * File IO related methods.
- */
-public class IOUtils {
- private static final int BUFFER_SIZE = 1024 * 8;
- private static final String LOGTAG = IOUtils.class.getSimpleName();
-
- public static File getFileFromURIString(String URIpath) throws IllegalArgumentException{
- try{
- return new File(new URI(URIpath));
- } catch (URISyntaxException e) {
- //should not happen as all URIs are system generated
- Log.wtf(LOGTAG, e.getReason());
- return null;
- }
- }
-
- public static boolean isInvalidFile(File f) {
- return f == null || !f.exists() || f.getTotalSpace() == 0
- || !f.canRead() || !f.canWrite();
- }
-
- public static int copy(InputStream input, OutputStream output) throws Exception {
- byte[] buffer = new byte[BUFFER_SIZE];
-
- BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
- BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
-
- int count = 0, n = 0;
- try {
- while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
- out.write(buffer, 0, n);
- count += n;
- }
- out.flush();
- } finally {
- if (out != null) out.close();
- if (in != null) in.close();
- }
-
- return count;
- }
-
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/BrowserSelectorActivity.java b/android/source/src/java/org/libreoffice/storage/external/BrowserSelectorActivity.java
deleted file mode 100644
index 07b64623b701..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/BrowserSelectorActivity.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.annotation.TargetApi;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.UriPermission;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.support.v7.app.AppCompatActivity;
-import android.util.Log;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.DocumentProviderFactory;
-
-import java.util.Set;
-
-/**
- * Activity to select which directory browser to use.
- * Android 5+ will use the DocumentTree intent to locate a browser.
- * Android 4+ & OTG will use the internal directory browser.
- */
-public class BrowserSelectorActivity extends AppCompatActivity {
- public static final String PREFERENCE_KEY_EXTRA = "org.libreoffice.pref_key_extra";
- public static final String MODE_EXTRA = "org.libreoffice.mode_extra";
- public static final String MODE_OTG = "OTG";
- public static final String MODE_EXT_SD = "EXT_SD";
-
- private static final String LOGTAG = BrowserSelectorActivity.class.getSimpleName();
- private static final int REQUEST_DOCUMENT_TREE = 1;
- private static final int REQUEST_INTERNAL_BROWSER = 2;
- private Set<SharedPreferences.OnSharedPreferenceChangeListener> listeners;
- private String preferenceKey;
- private SharedPreferences preferences;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- preferenceKey = getIntent().getStringExtra(PREFERENCE_KEY_EXTRA);
- preferences = PreferenceManager.getDefaultSharedPreferences(this);
- String mode = getIntent().getStringExtra(MODE_EXTRA);
-
- if(mode.equals(MODE_EXT_SD)) {
- findSDCard();
- } else if (mode.equals(MODE_OTG)) {
- findOTGDevice();
- }
- }
-
- private void findOTGDevice() {
- useInternalBrowser(DocumentProviderFactory.OTG_PROVIDER_INDEX);
- }
-
- private void findSDCard() {
- if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- useDocumentTreeBrowser();
- } else {
- useInternalBrowser(DocumentProviderFactory.EXTSD_PROVIDER_INDEX);
- }
- }
-
- private void useInternalBrowser(int providerIndex) {
- IExternalDocumentProvider provider =
- (IExternalDocumentProvider) DocumentProviderFactory.getInstance()
- .getProvider(providerIndex);
- String previousDirectoryPath = preferences.getString(preferenceKey, provider.guessRootURI(this));
- Intent i = new Intent(this, DirectoryBrowserActivity.class);
- i.putExtra(DirectoryBrowserActivity.DIRECTORY_PATH_EXTRA, previousDirectoryPath);
- startActivityForResult(i, REQUEST_INTERNAL_BROWSER);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void useDocumentTreeBrowser() {
- Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
- startActivityForResult(i, REQUEST_DOCUMENT_TREE);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- //listeners are registered here as onActivityResult is called before onResume
- super.onActivityResult(requestCode, resultCode, data);
-
- registerListeners();
- if(resultCode == RESULT_OK) {
- switch(requestCode) {
- case REQUEST_DOCUMENT_TREE:
- Uri treeUri = data.getData();
- preferences.edit()
- .putString(preferenceKey, treeUri.toString())
- .apply();
-
- updatePersistedUriPermission(treeUri);
- getContentResolver().takePersistableUriPermission(treeUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION |
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- break;
-
- case REQUEST_INTERNAL_BROWSER:
- Uri fileUri = data.getData();
- preferences.edit()
- .putString(preferenceKey, fileUri.toString())
- .apply();
- break;
- default:
- }
- }
- unregisterListeners();
- Log.d(LOGTAG, "Preference saved: " +
- preferences.getString(preferenceKey, getString(R.string.directory_not_saved)));
- finish();
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void updatePersistedUriPermission(Uri treeUri) {
- freePreviousUriPermissions();
-
- //TODO: Use non-emulator Android 5+ device to check if needed
- /*this.grantUriPermission(this.getPackageName(),
- treeUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION |
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION); */
-
- getContentResolver().takePersistableUriPermission(treeUri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION |
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- private void freePreviousUriPermissions() {
- ContentResolver cr = getContentResolver();
- for (UriPermission uriPermission : cr.getPersistedUriPermissions()) {
- cr.releasePersistableUriPermission(uriPermission.getUri(), 0);
- }
- }
-
- private void registerListeners() {
- listeners = DocumentProviderFactory.getInstance().getChangeListeners();
- for (SharedPreferences.OnSharedPreferenceChangeListener listener : listeners) {
- PreferenceManager.getDefaultSharedPreferences(this)
- .registerOnSharedPreferenceChangeListener(listener);
- }
- }
-
- private void unregisterListeners() {
- for (SharedPreferences.OnSharedPreferenceChangeListener listener : listeners) {
- PreferenceManager.getDefaultSharedPreferences(this)
- .unregisterOnSharedPreferenceChangeListener(listener);
- }
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserActivity.java b/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserActivity.java
deleted file mode 100644
index 1cf9f52fa7c0..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserActivity.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.libreoffice.storage.external;
-
-
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
-
-import org.libreoffice.R;
-
-/**
- * Container for DirectoryBrowserFragment
- */
-public class DirectoryBrowserActivity extends AppCompatActivity {
- public static final String DIRECTORY_PATH_EXTRA = "org.libreoffice.directory_path_extra";
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Intent data = getIntent();
- String initialPath = data.getStringExtra(DIRECTORY_PATH_EXTRA);
-
- setContentView(R.layout.activity_directory_browser);
- FragmentManager fm = getFragmentManager();
- Fragment fragment = DirectoryBrowserFragment.newInstance(initialPath);
- fm.beginTransaction()
- .add(R.id.fragment_container, fragment)
- .commit();
- }
-
- @Override
- public void onBackPressed() {
- FragmentManager fm = getFragmentManager();
- if(fm.getBackStackEntryCount() > 0) {
- fm.popBackStack();
- } else {
- super.onBackPressed();
- }
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserFragment.java b/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserFragment.java
deleted file mode 100644
index 18165650a617..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/DirectoryBrowserFragment.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.support.annotation.Nullable;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.IOUtils;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Comparator;
-
-/**
- * A simple directory browser.
- */
-public class DirectoryBrowserFragment extends Fragment {
- private static final String LOGTAG = DirectoryBrowserFragment.class.getSimpleName();
- private static final String INITIAL_PATH_URI_KEY = "initial_path";
- private File currentDirectory;
- private FileArrayAdapter directoryAdapter;
-
- public static DirectoryBrowserFragment newInstance(String initialPathURI) {
- Bundle args = new Bundle();
- args.putString(INITIAL_PATH_URI_KEY, initialPathURI);
- DirectoryBrowserFragment fragment = new DirectoryBrowserFragment();
- fragment.setArguments(args);
- Log.d(LOGTAG, "Saved path: " + initialPathURI);
-
- return fragment;
- }
-
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- String initialPathURI = getArguments().getString(INITIAL_PATH_URI_KEY);
- setupCurrentDirectory(initialPathURI);
- }
-
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v = inflater.inflate(R.layout.fragment_directory_browser, container, false);
-
- final EditText directoryHeader = v.findViewById(R.id.directory_header);
- Button directorySearchButton = v.findViewById(R.id.directory_search_button);
- Button positiveButton = v.findViewById(R.id.confirm_button);
- Button negativeButton = v.findViewById(R.id.cancel_button);
- ImageView upImage = v.findViewById(R.id.up_image);
- ListView directoryListView = v.findViewById(R.id.directory_list);
-
- directoryHeader.setText(currentDirectory.getPath());
- directorySearchButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String currentPath = currentDirectory.getAbsolutePath();
- String enteredPath = directoryHeader.getText().toString();
- File testDirectory = new File(enteredPath);
- if(enteredPath.equals(currentPath)) ;
- else if (isInvalidFileDirectory(testDirectory)) {
- Toast.makeText(getActivity(), R.string.bad_directory, Toast.LENGTH_SHORT)
- .show();
- }
- else {
- changeDirectory(testDirectory);
- }
- }
- });
-
- positiveButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent data = new Intent();
- data.setData(Uri.fromFile(currentDirectory));
- getActivity().setResult(Activity.RESULT_OK, data);
- getActivity().finish();
- }
- });
-
- negativeButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().setResult(Activity.RESULT_CANCELED, null);
- getActivity().finish();
- }
- });
-
- upImage.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- changeDirectory(currentDirectory.getParentFile());
- }
- });
-
- directoryAdapter = new FileArrayAdapter(getActivity(), new ArrayList<File>());
- directoryAdapter.populateFileList(currentDirectory);
- directoryListView.setAdapter(directoryAdapter);
- directoryListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- changeDirectory(directoryAdapter.getItem(position));
- }
- });
-
- return v;
- }
-
- private void changeDirectory(File destination) {
- if(destination == null) {
- Toast.makeText(getActivity(), R.string.unable_to_go_further, Toast.LENGTH_SHORT)
- .show();
- } else {
- Fragment fragment = DirectoryBrowserFragment.newInstance(destination.toURI().toString());
- getActivity().getFragmentManager().beginTransaction()
- .replace(R.id.fragment_container, fragment)
- .addToBackStack(null)
- .commit();
- }
- }
-
- private void setupCurrentDirectory(String initialPathURI) {
- File initialDirectory = null;
- if(initialPathURI != null && !initialPathURI.isEmpty()) {
- initialDirectory = IOUtils.getFileFromURIString(initialPathURI);
- }
-
- if(isInvalidFileDirectory(initialDirectory)) {
- initialDirectory = Environment.getExternalStorageDirectory();
- }
- currentDirectory = initialDirectory;
- }
-
- private boolean isInvalidFileDirectory(File f) {
- return f == null || !f.exists() || !f.isDirectory() ||!f.canRead();
- }
-
- private class FileArrayAdapter extends ArrayAdapter<File> {
- private Comparator<File> caseInsensitiveNaturalOrderComparator;
-
- public FileArrayAdapter(Context context, ArrayList<File> files) {
- super(context, 0, files);
- caseInsensitiveNaturalOrderComparator = new AlphabeticalFileComparator();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = getActivity().getLayoutInflater()
- .inflate(android.R.layout.simple_list_item_1, null);
- }
-
- File f = this.getItem(position);
- TextView tv = convertView.findViewById(android.R.id.text1);
- tv.setText(f.getName());
-
- return convertView;
- }
-
- public void sortAlphabetically() {
- this.sort(caseInsensitiveNaturalOrderComparator);
- }
-
- public void populateFileList(File directory) {
- for(File f : directory.listFiles()){
- if(f.isDirectory()){
- directoryAdapter.add(f);
- }
- }
- directoryAdapter.sortAlphabetically();
- }
- }
-
- private class AlphabeticalFileComparator implements Comparator<File> {
- @Override
- public int compare(File lhs, File rhs) {
- String lhsName = lhs.getName();
- String rhsName = rhs.getName();
-
- return lhsName.compareToIgnoreCase(rhsName);
- }
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/ExternalFile.java b/android/source/src/java/org/libreoffice/storage/external/ExternalFile.java
deleted file mode 100644
index aff33e4413ef..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/ExternalFile.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.content.Context;
-import android.support.v4.provider.DocumentFile;
-import android.util.Log;
-
-import org.libreoffice.storage.IFile;
-import org.libreoffice.storage.IOUtils;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Implementation of IFile for the external file system, for Android 4.4+
- *
- * Uses the DocumentFile class.
- *
- * The DocumentFile class obfuscates the path of the files it wraps,
- * preventing usage of LOK's documentLoad method. A copy of the DocumentFile's contents
- * will be created in the cache when files are opened, allowing use of documentLoad.
- */
-public class ExternalFile implements IFile{
- private final static String LOGTAG = "ExternalFile";
-
- private ExtsdDocumentsProvider provider;
- private DocumentFile docFile;
- private File duplicateFile;
- private Context context;
-
- public ExternalFile(ExtsdDocumentsProvider provider, DocumentFile docFile, Context context) {
- this.provider = provider;
- this.context = context;
- this.docFile = docFile;
- }
-
- @Override
- public URI getUri() {
- try{
- return new URI(docFile.toString());
- } catch (URISyntaxException e) {
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- return null;
- }
- }
-
- @Override
- public String getName() {
- return docFile.getName();
- }
-
- @Override
- public boolean isDirectory() {
- return docFile.isDirectory();
- }
-
- @Override
- public long getSize() {
- return docFile.length();
- }
-
- @Override
- public Date getLastModified() {
- return new Date(docFile.lastModified());
- }
-
- @Override
- public List<IFile> listFiles() {
- List<IFile> children = new ArrayList<IFile>();
- for (DocumentFile child : docFile.listFiles()) {
- children.add(new ExternalFile(provider, child, context));
- }
- return children;
- }
-
- @Override
- public List<IFile> listFiles(FileFilter filter) {
- File file;
- try{
- List<IFile> children = new ArrayList<IFile>();
- for (DocumentFile child : docFile.listFiles()) {
- file = new File(new URI(child.getUri().toString()));
- if(filter.accept(file))
- children.add(new ExternalFile(provider, child, context));
- }
- return children;
-
- }catch (Exception e){
- e.printStackTrace();
- }
- /* if something goes wrong */
- return listFiles();
-
- }
-
- @Override
- public IFile getParent(Context context) {
- // this is the root node
- if(docFile.getParentFile() == null) return null;
-
- return new ExternalFile(provider, docFile.getParentFile(), this.context);
- }
-
- @Override
- public File getDocument() {
- if(isDirectory()) {
- return null;
- } else {
- duplicateFile = duplicateInCache();
- return duplicateFile;
- }
- }
-
- private File duplicateInCache() {
- try{
- InputStream istream = context.getContentResolver().
- openInputStream(docFile.getUri());
-
- File storageFolder = provider.getCacheDir();
- File fileCopy = new File(storageFolder, docFile.getName());
- OutputStream ostream = new FileOutputStream(fileCopy);
-
- IOUtils.copy(istream, ostream);
- return fileCopy;
- } catch (Exception e) {
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- return null;
- }
- }
-
- @Override
- public void saveDocument(File file) {
- try{
- OutputStream ostream = context.getContentResolver().
- openOutputStream(docFile.getUri());
- InputStream istream = new FileInputStream(file);
-
- IOUtils.copy(istream, ostream);
-
- } catch (Exception e) {
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- }
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object)
- return true;
- if (!(object instanceof ExternalFile))
- return false;
- ExternalFile file = (ExternalFile) object;
- return file.getUri().equals(getUri());
- }
-
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/ExtsdDocumentsProvider.java b/android/source/src/java/org/libreoffice/storage/external/ExtsdDocumentsProvider.java
deleted file mode 100644
index e45929374bbd..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/ExtsdDocumentsProvider.java
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Environment;
-import android.preference.PreferenceManager;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.provider.DocumentFile;
-import android.util.Log;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.DocumentProviderSettingsActivity;
-import org.libreoffice.storage.IFile;
-
-import java.io.File;
-import java.net.URI;
-
-/**
- * Implementation of IDocumentProvider for the external file system, for android 4.4+
- *
- * The DocumentFile class is required when accessing files in external storage
- * for Android 4.4+. The ExternalFile class is used to handle this.
- *
- * Android 4.4 & 5+ use different types of root directory paths,
- * 5 using a DirectoryTree Uri and 4.4 using a normal File path.
- * As such, different methods are required to obtain the rootDirectory IFile.
- * 4.4 has to guess the location of the rootDirectory as well.
- */
-public class ExtsdDocumentsProvider implements IExternalDocumentProvider,
- OnSharedPreferenceChangeListener{
- private static final String LOGTAG = ExtsdDocumentsProvider.class.getSimpleName();
-
- private int id;
- private File cacheDir;
- private String rootPathURI;
-
- public ExtsdDocumentsProvider(int id, Context context) {
- this.id = id;
- setupRootPathUri(context);
- setupCache(context);
- }
-
- private void setupRootPathUri(Context context) {
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
- rootPathURI = preferences.getString(
- DocumentProviderSettingsActivity.KEY_PREF_EXTERNAL_SD_PATH_URI, guessRootURI(context));
- }
-
- public String guessRootURI(Context context) {
- // TODO: unfortunately the getExternalFilesDirs function relies on devices to actually
- // follow guidelines re external storage. Of course device manufacturers don't and as such
- // you cannot rely on it returning the actual paths (neither the compat, nor the native variant)
- File[] possibleRemovables = ContextCompat.getExternalFilesDirs(context,null);
- // the primary dir that is already covered by the "LocalDocumentsProvider"
- // might be emulated/part of internal memory or actual SD card
- // TODO: change to not confuse android's "external storage" with "expandable storage"
- String primaryExternal = Environment.getExternalStorageDirectory().getAbsolutePath();
-
- for (File option: possibleRemovables) {
- // Returned paths may be null if a storage device is unavailable.
- if (null == option) {
- Log.w(LOGTAG,"path was a null option :-/"); continue; }
- String optionPath = option.getAbsolutePath();
- if(optionPath.contains(primaryExternal)) {
- Log.v(LOGTAG, "did get file path - but is same as primary storage ("+ primaryExternal +")");
- continue;
- }
-
- return option.toURI().toString();
- }
-
- // TODO: do some manual probing of possible directories (/storage/sdcard1 and similar)
- Log.i(LOGTAG, "no secondary storage reported");
- return null;
- }
-
- private void setupCache(Context context) {
- // TODO: probably we should do smarter cache management
- cacheDir = new File(context.getExternalCacheDir(), "externalFiles");
- if (cacheDir.exists()) {
- deleteRecursive(cacheDir);
- }
- cacheDir.mkdirs();
- }
-
- private static void deleteRecursive(File file) {
- if (file.isDirectory()) {
- for (File child : file.listFiles())
- deleteRecursive(child);
- }
- file.delete();
- }
-
- public File getCacheDir() {
- return cacheDir;
- }
-
- @Override
- public IFile getRootDirectory(Context context) {
- if(android.os.Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
- return android4RootDirectory(context);
- } else {
- return android5RootDirectory(context);
- }
- }
-
- private ExternalFile android4RootDirectory(Context context) {
- try{
- File f = new File(new URI(rootPathURI));
- return new ExternalFile(this, DocumentFile.fromFile(f), context);
- } catch (Exception e) {
- //invalid rootPathURI
- throw buildRuntimeExceptionForInvalidFileURI(context);
- }
- }
-
- private ExternalFile android5RootDirectory(Context context) {
- try {
- return new ExternalFile(this,
- DocumentFile.fromTreeUri(context, Uri.parse(rootPathURI)),
- context);
- } catch (Exception e) {
- //invalid rootPathURI
- throw buildRuntimeExceptionForInvalidFileURI(context);
- }
- }
-
- private RuntimeException buildRuntimeExceptionForInvalidFileURI(Context context) {
- // ToDo: discarding the original exception / catch-all handling is bad style
- return new RuntimeException(context.getString(R.string.ext_document_provider_error));
- }
-
- @Override
- public IFile createFromUri(Context context, URI javaURI) {
- //TODO: refactor when new DocumentFile API exist
- //uri must be of a DocumentFile file, not directory.
- Uri androidUri = Uri.parse(javaURI.toString());
- return new ExternalFile(this,
- DocumentFile.fromSingleUri(context, androidUri),
- context);
- }
-
- @Override
- public int getNameResource() {
- return R.string.external_sd_file_system;
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- @Override
- public boolean checkProviderAvailability(Context context) {
- // too many devices (or I am just unlucky) don't report the mounted state properly, and other
- // devices also consider dedicated part of internal storage to be "mounted" so cannot use
- // getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && isExternalStorageRemovable()
- // but they refer to the primary external storage anyway, so what currently is covered by the
- // "LocalDocumentsProvider"
- return rootPathURI!=null && ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
- if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_EXTERNAL_SD_PATH_URI)) {
- rootPathURI = preferences.getString(key, "");
- }
- }
-
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/IExternalDocumentProvider.java b/android/source/src/java/org/libreoffice/storage/external/IExternalDocumentProvider.java
deleted file mode 100644
index a439417b60cd..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/IExternalDocumentProvider.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.content.Context;
-
-import org.libreoffice.storage.IDocumentProvider;
-
-
-/**
- * Interface for external document providers.
- */
-public interface IExternalDocumentProvider extends IDocumentProvider {
-
- /**
- * Used to obtain the default directory to display when
- * browsing using the internal DirectoryBrowser.
- *
- * @return a guess of the root file's URI.
- * @param context
- */
- String guessRootURI(Context context);
-
-}
diff --git a/android/source/src/java/org/libreoffice/storage/external/OTGDocumentsProvider.java b/android/source/src/java/org/libreoffice/storage/external/OTGDocumentsProvider.java
deleted file mode 100644
index 4341bc3541e6..000000000000
--- a/android/source/src/java/org/libreoffice/storage/external/OTGDocumentsProvider.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.libreoffice.storage.external;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.DocumentProviderSettingsActivity;
-import org.libreoffice.storage.IFile;
-import org.libreoffice.storage.IOUtils;
-import org.libreoffice.storage.local.LocalFile;
-
-import java.io.File;
-import java.net.URI;
-
-/**
- * TODO: OTG currently uses LocalFile. Change to an IFile that handles abrupt OTG unmounting
- */
-public class OTGDocumentsProvider implements IExternalDocumentProvider,
- SharedPreferences.OnSharedPreferenceChangeListener {
-
- private static final String LOGTAG = OTGDocumentsProvider.class.getSimpleName();
-
- private String rootPathURI;
- private int id;
-
- public OTGDocumentsProvider(int id, Context context) {
- this.id = id;
- setupRootPath(context);
- }
-
- private void setupRootPath(Context context) {
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
- rootPathURI = preferences.getString(
- DocumentProviderSettingsActivity.KEY_PREF_OTG_PATH_URI, "");
- }
-
- @Override
- public IFile createFromUri(Context context, URI uri) {
- return new LocalFile(uri);
- }
-
- @Override
- public int getNameResource() {
- return R.string.otg_file_system;
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- @Override
- public IFile getRootDirectory(Context context) {
- // TODO: handle this with more fine-grained exceptions
- if(rootPathURI.equals("")) {
- Log.e(LOGTAG, "rootPathURI is empty");
- throw new RuntimeException(context.getString(R.string.ext_document_provider_error));
- }
-
- File f = IOUtils.getFileFromURIString(rootPathURI);
- if(IOUtils.isInvalidFile(f)) {
- Log.e(LOGTAG, "rootPathURI is invalid - missing device?");
- throw new RuntimeException(context.getString(R.string.otg_missing_error));
- }
-
- return new LocalFile(f);
- }
-
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OTG_PATH_URI)) {
- rootPathURI = sharedPreferences.getString(key, "");
- }
- }
-
- @Override
- public String guessRootURI(Context context) {
- return "";
- }
-
- @Override
- public boolean checkProviderAvailability(Context context) {
- // check if system supports USB Host
- return rootPathURI.length()>0 && context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_HOST);
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java
deleted file mode 100644
index 15522e93a45e..000000000000
--- a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsDirectoryProvider.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage.local;
-
-import java.io.File;
-
-import org.libreoffice.storage.IFile;
-import org.libreoffice.R;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Environment;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
-
-/**
- * A convenience IDocumentProvider to browse the /sdcard/Documents directory.
- *
- * Extends LocalDocumentsProvider to overwrite getRootDirectory and set it to
- * /sdcard/Documents. Most documents will probably be stored there so there is
- * no need for the user to browse the filesystem from the root every time.
- */
-public class LocalDocumentsDirectoryProvider extends LocalDocumentsProvider {
-
- public LocalDocumentsDirectoryProvider(int id) {
- super(id);
- }
-
- private static File getDocumentsDir() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- // DIRECTORY_DOCUMENTS is 19 or later only
- return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
- } else {
- return new File(Environment.getExternalStorageDirectory() + "/Documents");
- }
- }
-
- @Override
- public IFile getRootDirectory(Context context) {
- File documentsDirectory = getDocumentsDir();
- if (!documentsDirectory.exists()) {
- if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
- if(!documentsDirectory.mkdirs()) {
- // fallback to the toplevel dir - might be due to the dir not mounted/used as USB-Mass-Storage or similar
- // TODO: handle unavailability of the storage/failure of the mkdir properly
- Log.e("LocalDocumentsProvider", "not sure how we ended up here - if we have read permissions to use it in the first place, we also should have the write-permissions..");
- documentsDirectory = Environment.getExternalStorageDirectory();
- }
- }
- }
- return new LocalFile(documentsDirectory);
- }
-
- @Override
- public int getNameResource() {
- return R.string.local_documents;
- }
-
- @Override
- public boolean checkProviderAvailability(Context context) {
- File documentsDirectory = getDocumentsDir();
- return documentsDirectory.exists() && ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java b/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java
deleted file mode 100644
index 1a10fad424db..000000000000
--- a/android/source/src/java/org/libreoffice/storage/local/LocalDocumentsProvider.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage.local;
-
-import java.net.URI;
-
-import org.libreoffice.storage.IDocumentProvider;
-import org.libreoffice.storage.IFile;
-
-import org.libreoffice.R;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Environment;
-import android.support.v4.content.ContextCompat;
-
-/**
- * Implementation of IDocumentProvider for the local file system.
- */
-public class LocalDocumentsProvider implements IDocumentProvider {
-
- private int id;
-
- public LocalDocumentsProvider(int id) {
- this.id = id;
- }
-
- @Override
- public IFile getRootDirectory(Context context) {
- return new LocalFile(Environment.getExternalStorageDirectory());
- }
-
- @Override
- public IFile createFromUri(Context context, URI uri) {
- return new LocalFile(uri);
- }
-
- @Override
- public int getNameResource() {
- return R.string.local_file_system;
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- @Override
- public boolean checkProviderAvailability(Context context) {
- return ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/local/LocalFile.java b/android/source/src/java/org/libreoffice/storage/local/LocalFile.java
deleted file mode 100644
index 4ff5bbf119f4..000000000000
--- a/android/source/src/java/org/libreoffice/storage/local/LocalFile.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-package org.libreoffice.storage.local;
-
-import android.content.Context;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.libreoffice.storage.IFile;
-
-/**
- * Implementation of IFile for the local file system.
- */
-public class LocalFile implements IFile {
-
- private File file;
-
- public LocalFile(File file) {
- this.file = file;
- }
-
- public LocalFile(URI uri) {
- this.file = new File(uri);
- }
-
- public URI getUri() {
- return file.toURI();
- }
-
- public String getName() {
- return file.getName();
- }
-
- @Override
- public boolean isDirectory() {
- return file.isDirectory();
- }
-
- @Override
- public long getSize() {
- return file.length();
- }
-
- @Override
- public Date getLastModified() {
- return new Date(file.lastModified());
- }
-
- @Override
- public List<IFile> listFiles() {
- List<IFile> children = new ArrayList<IFile>();
- for (File child : file.listFiles()) {
- children.add(new LocalFile(child));
- }
- return children;
- }
-
- @Override
- public List<IFile> listFiles(FileFilter filter) {
- List<IFile> children = new ArrayList<IFile>();
- for (File child : file.listFiles(filter)) {
- children.add(new LocalFile(child));
- }
- return children;
- }
-
- @Override
- public IFile getParent(Context context) {
- return new LocalFile(file.getParentFile());
- }
-
- @Override
- public File getDocument() {
- return file;
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object)
- return true;
- if (!(object instanceof LocalFile))
- return false;
- LocalFile file = (LocalFile) object;
- return file.getUri().equals(getUri());
- }
-
- @Override
- public void saveDocument(File file) {
- // do nothing; file is local
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java
deleted file mode 100644
index fa74a54b08e2..000000000000
--- a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudFile.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package org.libreoffice.storage.owncloud;
-
-import android.content.Context;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-import org.libreoffice.storage.IFile;
-
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation;
-import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
-import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
-import com.owncloud.android.lib.resources.files.RemoteFile;
-import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
-
-/**
- * Implementation of IFile for ownCloud servers.
- */
-public class OwnCloudFile implements IFile {
-
- private OwnCloudProvider provider;
- private RemoteFile file;
-
- private String name;
- private String parentPath;
-
- protected OwnCloudFile(OwnCloudProvider provider, RemoteFile file) {
- this.provider = provider;
- this.file = file;
-
- // get name and parent from path
- File localFile = new File(file.getRemotePath());
- this.name = localFile.getName();
- this.parentPath = localFile.getParent();
- }
-
- @Override
- public URI getUri(){
-
- try{
- return URI.create(URLEncoder.encode(file.getRemotePath(),"UTF-8"));
- }catch(UnsupportedEncodingException e){
- e.printStackTrace();
- }
-
- return null;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean isDirectory() {
- return file.getMimeType().equals("DIR");
- }
-
- @Override
- public long getSize() {
- return file.getLength();
- }
-
- @Override
- public Date getLastModified() {
- return new Date(file.getModifiedTimestamp());
- }
-
- @Override
- public List<IFile> listFiles() {
- List<IFile> children = new ArrayList<IFile>();
- if (isDirectory()) {
- ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(
- file.getRemotePath());
- RemoteOperationResult result = refreshOperation.execute(provider
- .getClient());
- if (!result.isSuccess()) {
- throw provider.buildRuntimeExceptionForResultCode(result.getCode());
- }
- for (Object obj : result.getData()) {
- RemoteFile child = (RemoteFile) obj;
- if (!child.getRemotePath().equals(file.getRemotePath()))
- children.add(new OwnCloudFile(provider, child));
- }
- }
- return children;
- }
-
- @Override
- public List<IFile> listFiles(FileFilter filter) {
- List<IFile> children = new ArrayList<IFile>();
- if (isDirectory()) {
- ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(
- file.getRemotePath());
- RemoteOperationResult result = refreshOperation.execute(provider
- .getClient());
- if (!result.isSuccess()) {
- throw provider.buildRuntimeExceptionForResultCode(result.getCode());
- }
-
- for (Object obj : result.getData()) {
- RemoteFile child = (RemoteFile) obj;
- if (!child.getRemotePath().equals(file.getRemotePath())){
- OwnCloudFile ownCloudFile = new OwnCloudFile(provider, child);
- if(!ownCloudFile.isDirectory()){
- File f = new File(provider.getCacheDir().getAbsolutePath(),
- ownCloudFile.getName());
- if(filter.accept(f))
- children.add(ownCloudFile);
- f.delete();
- }else{
- children.add(ownCloudFile);
- }
- }
- }
- }
- return children;
- }
-
- @Override
- public IFile getParent(Context context) {
- if (parentPath == null)
- // this is the root node
- return null;
-
- return provider.createFromUri(context, URI.create(parentPath));
- }
-
- @Override
- public File getDocument() {
- if (isDirectory()) {
- return null;
- }
- File downFolder = provider.getCacheDir();
- DownloadRemoteFileOperation operation = new DownloadRemoteFileOperation(
- file.getRemotePath(), downFolder.getAbsolutePath());
- RemoteOperationResult result = operation.execute(provider.getClient());
- if (!result.isSuccess()) {
- throw provider.buildRuntimeExceptionForResultCode(result.getCode());
- }
- return new File(downFolder.getAbsolutePath() + file.getRemotePath());
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object)
- return true;
- if (!(object instanceof OwnCloudFile))
- return false;
- OwnCloudFile file = (OwnCloudFile) object;
- return file.getUri().equals(getUri());
- }
-
- @Override
- public void saveDocument(File newFile) {
- UploadRemoteFileOperation uploadOperation;
- if (newFile.length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE) {
- uploadOperation = new ChunkedUploadRemoteFileOperation(
- newFile.getPath(), file.getRemotePath(), file.getMimeType());
- } else {
- uploadOperation = new UploadRemoteFileOperation(newFile.getPath(),
- file.getRemotePath(), file.getMimeType());
- }
-
- RemoteOperationResult result = uploadOperation.execute(provider
- .getClient());
- if (!result.isSuccess()) {
- throw provider.buildRuntimeExceptionForResultCode(result.getCode());
- }
- }
-}
diff --git a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java b/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java
deleted file mode 100644
index 0852ab617660..000000000000
--- a/android/source/src/java/org/libreoffice/storage/owncloud/OwnCloudProvider.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package org.libreoffice.storage.owncloud;
-
-import java.io.File;
-import java.net.URI;
-
-import org.libreoffice.R;
-import org.libreoffice.storage.DocumentProviderSettingsActivity;
-import org.libreoffice.storage.IDocumentProvider;
-import org.libreoffice.storage.IFile;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.net.Uri;
-import android.preference.PreferenceManager;
-
-import com.owncloud.android.lib.common.OwnCloudClient;
-import com.owncloud.android.lib.common.OwnCloudClientFactory;
-import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult;
-import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
-import com.owncloud.android.lib.resources.files.FileUtils;
-import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
-import com.owncloud.android.lib.resources.files.RemoteFile;
-
-
-/**
- * Implementation of IDocumentProvider for ownCloud servers.
- */
-public class OwnCloudProvider implements IDocumentProvider,
- OnSharedPreferenceChangeListener {
-
- private int id;
-
- private Context context;
- private OwnCloudClient client;
- private File cacheDir;
-
- private String serverUrl;
- private String userName;
- private String password;
- private RemoteOperationResult result;
-
- public OwnCloudProvider(int id, Context context) {
- this.id = id;
- this.context = context;
-
- // read preferences
- SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
- serverUrl = preferences.getString(
- DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_SERVER, "");
- userName = preferences.getString(
- DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_USER_NAME, "");
- password = preferences.getString(
- DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_PASSWORD, "");
-
- setupClient();
-
- // make sure cache directory exists, and clear it
- // TODO: probably we should do smarter cache management
- cacheDir = new File(context.getCacheDir(), "ownCloud");
- if (cacheDir.exists()) {
- deleteRecursive(cacheDir);
- }
- cacheDir.mkdirs();
- }
-
- private void setupClient() {
- Uri serverUri = Uri.parse(serverUrl);
- client = OwnCloudClientFactory.createOwnCloudClient(serverUri, context,
- true);
- client.setCredentials(OwnCloudCredentialsFactory.newBasicCredentials(
- userName, password));
- }
-
- @Override
- public IFile getRootDirectory(Context context) {
- return createFromUri(context, URI.create(FileUtils.PATH_SEPARATOR));
- }
-
- @Override
- public IFile createFromUri(Context context, URI uri) {
- if(serverUrl != "" || userName != "" || password != ""){
- ReadRemoteFileOperation refreshOperation = new ReadRemoteFileOperation(
- uri.getPath());
- this.result = refreshOperation.execute(client);
- if (!result.isSuccess()) {
- throw buildRuntimeExceptionForResultCode(result.getCode());
- }
- if (result.getData().size() > 0) {
- return new OwnCloudFile(this, (RemoteFile) result.getData().get(0));
- }
- } else {
- throw buildRuntimeExceptionForResultCode(ResultCode.WRONG_CONNECTION);
- }
-
- return null;
- }
-
- @Override
- public int getNameResource() {
- return R.string.owncloud;
- }
-
- /**
- * Used by OwnCloudFiles to get a configured client to run their own
- * operations.
- *
- * @return configured OwnCloudClient.
- */
- protected OwnCloudClient getClient() {
- return client;
- }
-
- /**
- * Used by OwnCloudFiles to get the cache directory they should download
- * files to.
- *
- * @return cache directory.
- */
- protected File getCacheDir() {
- return cacheDir;
- }
-
- /**
- * Build the proper RuntimeException for some error result.
- *
- * @param code Result code got from some RemoteOperationResult.
- * @return exception with the proper internationalized error message.
- */
- protected RuntimeException buildRuntimeExceptionForResultCode(ResultCode code) {
- int errorMessage;
- switch (code) {
- case WRONG_CONNECTION: // SocketException
- case FILE_NOT_FOUND: // HTTP 404
- errorMessage = R.string.owncloud_wrong_connection;
- break;
- case UNAUTHORIZED: // wrong user/pass
- errorMessage = R.string.owncloud_unauthorized;
- break;
- default:
- errorMessage = R.string.owncloud_unspecified_error;
- break;
- }
- return new RuntimeException(context.getString(errorMessage));
- }
-
- /**
- * Deletes files and recursively deletes directories.
- *
- * @param file
- * File or directory to be deleted.
- */
- private static void deleteRecursive(File file) {
- if (file.isDirectory()) {
- for (File child : file.listFiles())
- deleteRecursive(child);
- }
- file.delete();
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences preferences,
- String key) {
- boolean changed = false;
- if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_SERVER)) {
- serverUrl = preferences.getString(key, "");
- changed = true;
- }
- else if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_USER_NAME)) {
- userName = preferences.getString(key, "");
- changed = true;
- }
- else if (key.equals(DocumentProviderSettingsActivity.KEY_PREF_OWNCLOUD_PASSWORD)) {
- password = preferences.getString(key, "");
- changed = true;
- }
-
- if (changed)
- setupClient();
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- @Override
- public boolean checkProviderAvailability(Context context) {
- return client != null;
- }
-}
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 7a58486004cd..7fc8c3c84eb1 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -8,25 +8,18 @@
*/
package org.libreoffice.ui;
-import org.libreoffice.storage.IFile;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.text.Collator;
import java.util.Map;
-import java.util.Collections;
-import java.util.List;
import java.util.HashMap;
-import java.util.Comparator;
+
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.OpenableColumns;
import android.util.Log;
-import android.webkit.MimeTypeMap;
public class FileUtilities {
- private static String LOGTAG = FileUtilities.class.getSimpleName();
-
- static final int ALL = -1;
+ private static final String LOGTAG = FileUtilities.class.getSimpleName();
// These have to be in sync with the file_view_modes resource.
static final int DOC = 0;
@@ -36,26 +29,16 @@ public class FileUtilities {
static final int UNKNOWN = 10;
- static final int SORT_AZ = 0;
- static final int SORT_ZA = 1;
- /** Oldest Files First*/
- static final int SORT_OLDEST = 2;
- /** Newest Files First*/
- static final int SORT_NEWEST = 3;
- /** Largest Files First */
- static final int SORT_LARGEST = 4;
- /** Smallest Files First */
- static final int SORT_SMALLEST = 5;
-
- public static final String DEFAULT_WRITER_EXTENSION = ".odt";
- public static final String DEFAULT_IMPRESS_EXTENSION = ".odp";
- public static final String DEFAULT_SPREADSHEET_EXTENSION = ".ods";
- public static final String DEFAULT_DRAWING_EXTENSION = ".odg";
+ public static final String MIMETYPE_OPENDOCUMENT_TEXT = "application/vnd.oasis.opendocument.text";
+ public static final String MIMETYPE_OPENDOCUMENT_SPREADSHEET = "application/vnd.oasis.opendocument.spreadsheet";
+ public static final String MIMETYPE_OPENDOCUMENT_PRESENTATION = "application/vnd.oasis.opendocument.presentation";
+ public static final String MIMETYPE_OPENDOCUMENT_GRAPHICS = "application/vnd.oasis.opendocument.graphics";
+ public static final String MIMETYPE_PDF = "application/pdf";
private static final Map<String, Integer> mExtnMap = new HashMap<String, Integer>();
- private static final Map<String, String> extensionToMimeTypeMap = new HashMap<String, String>();
static {
// Please keep this in sync with AndroidManifest.xml
+ // and 'SUPPORTED_MIME_TYPES' in LibreOfficeUIActivity.java
// ODF
mExtnMap.put(".odt", DOC);
@@ -80,7 +63,7 @@ public class FileUtilities {
mExtnMap.put(".vsdx", DRAWING);
mExtnMap.put(".pub", DRAWING);
mExtnMap.put(".ppt", IMPRESS);
- // mExtnMap.put(".pps", IMPRESS);
+ mExtnMap.put(".pps", IMPRESS);
mExtnMap.put(".xls", CALC);
// MS templates
@@ -91,7 +74,7 @@ public class FileUtilities {
// OOXML
mExtnMap.put(".docx", DOC);
mExtnMap.put(".pptx", IMPRESS);
- // mExtnMap.put(".ppsx", IMPRESS);
+ mExtnMap.put(".ppsx", IMPRESS);
mExtnMap.put(".xlsx", CALC);
// OOXML templates
@@ -109,22 +92,6 @@ public class FileUtilities {
mExtnMap.put(".svm", DRAWING);
mExtnMap.put(".wmf", DRAWING);
mExtnMap.put(".svg", DRAWING);
-
- // Some basic MIME types
- // Android's MimeTypeMap lacks some types that we need
- extensionToMimeTypeMap.put("odb", "application/vnd.oasis.opendocument.database");
- extensionToMimeTypeMap.put("odf", "application/vnd.oasis.opendocument.formula");
- extensionToMimeTypeMap.put("odg", "application/vnd.oasis.opendocument.graphics");
- extensionToMimeTypeMap.put("otg", "application/vnd.oasis.opendocument.graphics-template");
- extensionToMimeTypeMap.put("odi", "application/vnd.oasis.opendocument.image");
- extensionToMimeTypeMap.put("odp", "application/vnd.oasis.opendocument.presentation");
- extensionToMimeTypeMap.put("otp", "application/vnd.oasis.opendocument.presentation-template");
- extensionToMimeTypeMap.put("ods", "application/vnd.oasis.opendocument.spreadsheet");
- extensionToMimeTypeMap.put("ots", "application/vnd.oasis.opendocument.spreadsheet-template");
- extensionToMimeTypeMap.put("odt", "application/vnd.oasis.opendocument.text");
- extensionToMimeTypeMap.put("odm", "application/vnd.oasis.opendocument.text-master");
- extensionToMimeTypeMap.put("ott", "application/vnd.oasis.opendocument.text-template");
- extensionToMimeTypeMap.put("oth", "application/vnd.oasis.opendocument.text-web");
}
public static String getExtension(String filename) {
@@ -149,129 +116,42 @@ public class FileUtilities {
return type;
}
- static String getMimeType(String filename) {
- String extension = MimeTypeMap.getFileExtensionFromUrl(filename);
- String mime = extensionToMimeTypeMap.get(extension);
- if (mime == null) {
- //fallback to Android's MimeTypeMap
- mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
- extension);
- }
- return mime;
+ /**
+ * Returns whether the passed MIME type is one for a document template.
+ */
+ public static boolean isTemplateMimeType(final String mimeType) {
+ // this works for ODF and OOXML template MIME types
+ return mimeType != null && mimeType.endsWith("template");
}
- // Filter by mode, and/or in future by filename/wildcard
- private static boolean doAccept(String filename, int byMode, String byFilename) {
- Log.d(LOGTAG, "doAccept : " + filename + " mode " + byMode + " byFilename " + byFilename);
- if (filename == null)
- return false;
-
- // check extension
- if (byMode != ALL) {
- if (mExtnMap.get (getExtension (filename)) != byMode)
- return false;
- }
- if (!byFilename.equals("")) {
- // FIXME return false on a non-match
- }
- return true;
+ public static String stripExtensionFromFileName(final String fileName)
+ {
+ return fileName.split("\\.[A-Za-z0-9]*$")[0];
}
- static FileFilter getFileFilter(final int mode) {
- return new FileFilter() {
- public boolean accept(File pathname) {
- if (pathname.isDirectory())
- return true;
- if (lookupExtension(pathname.getName()) == UNKNOWN)
- return false;
- return doAccept(pathname.getName(), mode, "");
+ /**
+ * Tries to retrieve the display (which should be the document name)
+ * for the given URI using the given resolver.
+ */
+ public static String retrieveDisplayNameForDocumentUri(ContentResolver resolver, Uri docUri) {
+ String displayName = "";
+ // try to retrieve original file name
+ Cursor cursor = null;
+ try {
+ String[] columns = {OpenableColumns.DISPLAY_NAME};
+ cursor = resolver.query(docUri, columns, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ displayName = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
}
- };
- }
-
- static FilenameFilter getFilenameFilter(final int mode) {
- return new FilenameFilter() {
- public boolean accept(File dir, String filename) {
- if (new File(dir , filename).isDirectory())
- return true;
- return doAccept(filename, mode, "");
+ } catch (SecurityException e) {
+ // thrown e.g. when Uri has become invalid, e.g. corresponding file has been deleted
+ Log.i(LOGTAG, "SecurityException when trying to receive display name for Uri " + docUri);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
}
- };
- }
-
- static void sortFiles(List<IFile> files, int sortMode) {
- if (files == null)
- return;
- // Compare filenames in the default locale
- final Collator mCollator = Collator.getInstance();
- switch (sortMode) {
- case SORT_AZ:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return mCollator.compare(lhs.getName(), rhs.getName());
- }
- });
- break;
- case SORT_ZA:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return mCollator.compare(rhs.getName(), lhs.getName());
- }
- });
- break;
- case SORT_OLDEST:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return lhs.getLastModified().compareTo(rhs.getLastModified());
- }
- });
- break;
- case SORT_NEWEST:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return rhs.getLastModified().compareTo(lhs.getLastModified());
- }
- });
- break;
- case SORT_LARGEST:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return Long.valueOf(rhs.getSize()).compareTo(lhs.getSize());
- }
- });
- break;
- case SORT_SMALLEST:
- Collections.sort(files , new Comparator<IFile>() {
- public int compare(IFile lhs, IFile rhs) {
- return Long.valueOf(lhs.getSize()).compareTo(rhs.getSize());
- }
- });
- break;
- default:
- Log.e(LOGTAG, "uncatched sortMode: " + sortMode);
}
- }
-
- static boolean isHidden(File file) {
- return file.getName().startsWith(".");
- }
-
- static boolean isThumbnail(File file) {
- return isHidden(file) && file.getName().endsWith(".png");
- }
-
- static boolean hasThumbnail(File file) {
- String filename = file.getName();
- if (lookupExtension(filename) == DOC) // only do this for docs for now
- {
- // Will need another method to check if Thumb is up-to-date - or extend this one?
- return new File(file.getParent(), getThumbnailName(file)).isFile();
- }
- return true;
- }
-
- static String getThumbnailName(File file) {
- return "." + file.getName().split("[.]")[0] + ".png" ;
+ return displayName;
}
}
diff --git a/android/source/src/java/org/libreoffice/ui/FolderIconView.java b/android/source/src/java/org/libreoffice/ui/FolderIconView.java
deleted file mode 100644
index cde6cd27af4c..000000000000
--- a/android/source/src/java/org/libreoffice/ui/FolderIconView.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-package org.libreoffice.ui;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
-import android.graphics.Color;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-
-import java.io.File;
-import java.util.Stack;
-
-public class FolderIconView extends View{
- private String LOGTAG = "FolderIconView";
-
- private Paint mPaintBlack;
- private Paint mPaintGray;
- private Paint mPaintShadow;
-
- private File dir;
-
- public FolderIconView(Context context) {
- super(context);
- initialisePaints();
- }
- public FolderIconView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initialisePaints();
- }
- public FolderIconView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initialisePaints();
- }
-
- private void initialisePaints() {
- mPaintBlack = new Paint();
- mPaintBlack.setColor(Color.DKGRAY);//Can also use parseColor(String "#aarrggbb")
- mPaintBlack.setAntiAlias(true);
-
- mPaintGray = new Paint();
- mPaintGray.setColor(Color.GRAY);//Can also use parseColor(String "#aarrggbb")
- mPaintGray.setAntiAlias(true);
-
- mPaintShadow = new Paint();
- mPaintShadow.setColor(Color.parseColor("#88888888"));
- mPaintShadow.setAntiAlias(true);
- }
-
- public void setDir(File dir) {
- this.dir = dir;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- Log.d(LOGTAG, "onDraw");
- //float width = (float)canvas.getWidth();
- //float height = (float)canvas.getHeight();
- float width = (float) this.getWidth();
- float height = (float) this.getHeight();
- float centerX = width*0.5f;// centered on horz axis
- float centerY = height*0.5f;
- float outerRadius = 0.8f*0.5f*width;
- float innerRadius = 0.7f*0.5f*width;
- float thumbHeight = outerRadius*1.25f;
- float thumbWidth = thumbHeight*(float)(1/Math.sqrt(2));
- float DZx = 0.2f*outerRadius;
- float DZy = 0.2f*outerRadius;
- //Bitmap blankPage = BitmapFactory.decodeResource(getResources(), R.drawable.page);
- Log.i(LOGTAG, Float.toString(width) + "x" + Float.toString(height));
- canvas.drawCircle(centerX, centerY, outerRadius, mPaintGray);
- canvas.drawCircle(centerX, centerY, innerRadius, mPaintBlack);
- //Either get thumbs from directory or use generic page images
- //For now just get the first 4 thumbs -> add some checks later
- if (dir == null)
- return;//TODO
- File[] contents = dir.listFiles();//TODO consider filtering thumbs to match grid.
- if (contents == null)
- // dir is not a directory,
- // or user does not have permissions to read it
- return;
- Stack<Bitmap> thumbs = new Stack<Bitmap>();
- BitmapFactory factory = new BitmapFactory();
- for (File file : contents) {
- if (!FileUtilities.isThumbnail(file))
- continue;
- thumbs.push(BitmapFactory.decodeFile(file.getAbsolutePath()));//TODO switch to push for semantics
- if (thumbs.size() > 3)
- break;
- }
- /*while(thumbs.size() < 4) {// padd out with blanks?
- thumbs.push(blankPage);
- }*/
- Log.i(LOGTAG, Integer.toString(thumbs.size()));
- //should handle empty folders better
- // options:
- // don't show?
- // show generic LO icons for writer etc
- // Show a generic blank page icon
- if (thumbs.isEmpty())
- return;
- /*float left = centerX ;//+ 0.25f*outerRadius;
- float top = centerY - 0.5f*outerRadius;
- float right = left + thumbs.get(0).getWidth()*0.4f;
- float bottom = top + thumbs.get(0).getHeight()*0.4f;
- RectF dest = new RectF(left, top, right, bottom);
- RectF shadowBox = new RectF(dest);
- shadowBox.inset(-1, -1);
- int size = thumbs.size();
- for (int i = 1; i <= size; i++) {
- canvas.drawRect(shadowBox, mPaintShadow);
- canvas.drawBitmap(thumbs.pop(), null, dest, null);
- dest.offset(-outerRadius*0.2f, outerRadius*0.1f);
- shadowBox.offset(-outerRadius*0.2f, outerRadius*0.1f);
- }*/
- float left;
- float top;
- float right;
- float bottom;
- RectF dest;
- RectF shadowBox;
- int size;
- switch(thumbs.size()) {
- case 0:
- break;
- case 1:
- left = centerX - 0.5f*thumbWidth;
- top = centerY - 0.5f*thumbHeight;
- right = left + thumbWidth;
- bottom = top + thumbHeight;
- dest = new RectF(left, top, right, bottom);
- shadowBox = new RectF(dest);
- shadowBox.inset(-1, -1);
- canvas.drawRect(shadowBox, mPaintShadow);
- canvas.drawBitmap(thumbs.pop(), null, dest, null);
- break;
- case 2:
- left = centerX - 0.5f*thumbWidth + 0.5f*DZx;
- top = centerY - 0.5f*thumbHeight - 0.5f*DZy;
- right = left + thumbWidth;
- bottom = top + thumbHeight;
- dest = new RectF(left, top, right, bottom);
- shadowBox = new RectF(dest);
- shadowBox.inset(-1, -1);
- size = thumbs.size();
- for (int i = 1; i <= size; i++) {
- canvas.drawRect(shadowBox, mPaintShadow);
- canvas.drawBitmap(thumbs.pop(), null, dest, null);
- dest.offset(-DZx, DZy);
- shadowBox.offset(-DZx, DZy);
- }
- break;
- case 3:
- left = centerX - 0.5f*thumbWidth + DZx;
- top = centerY - 0.5f*thumbHeight - DZy;
- right = left + thumbWidth;
- bottom = top + thumbHeight;
- dest = new RectF(left, top, right, bottom);
- shadowBox = new RectF(dest);
- shadowBox.inset(-1, -1);
- size = thumbs.size();
- for (int i = 1; i <= size; i++) {
- canvas.drawRect(shadowBox, mPaintShadow);
- canvas.drawBitmap(thumbs.pop(), null, dest, null);
- dest.offset(-DZx, DZy);
- shadowBox.offset(-DZx, DZy);
- }
- break;
- case 4:
- left = centerX - 0.5f*thumbWidth + 1.5f*DZx;
- top = centerY - 0.5f*thumbHeight - 1.5f*DZy;
- right = left + thumbWidth;
- bottom = top + thumbHeight;
- dest = new RectF(left, top, right, bottom);
- shadowBox = new RectF(dest);
- shadowBox.inset(-1, -1);
- size = thumbs.size();
- for (int i = 1; i <= size; i++) {
- canvas.drawRect(shadowBox, mPaintShadow);
- canvas.drawBitmap(thumbs.pop(), null, dest, null);
- dest.offset(-DZx, DZy);
- shadowBox.offset(-DZx, DZy);
- }
- break;
- default:
- break;
- }
- }
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
index a9d797c4bf28..bc5203d9c6eb 100644
--- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
+++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
@@ -10,134 +10,119 @@
package org.libreoffice.ui;
import android.Manifest;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.BroadcastReceiver;
+import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.drawable.Icon;
-import android.hardware.usb.UsbManager;
import android.net.Uri;
-import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
-import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.NavigationView;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBarDrawerToggle;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.Toolbar;
-import android.text.InputType;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+import androidx.core.view.ViewCompat;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.appcompat.widget.Toolbar;
+import android.text.TextUtils;
import android.util.Log;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.OvershootInterpolator;
-import android.widget.EditText;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import android.widget.Toast;
import org.libreoffice.AboutDialogFragment;
-import org.libreoffice.LOKitShell;
+import org.libreoffice.BuildConfig;
import org.libreoffice.LibreOfficeMainActivity;
import org.libreoffice.LocaleHelper;
import org.libreoffice.R;
import org.libreoffice.SettingsActivity;
import org.libreoffice.SettingsListenerModel;
-import org.libreoffice.storage.DocumentProviderFactory;
-import org.libreoffice.storage.DocumentProviderSettingsActivity;
-import org.libreoffice.storage.IDocumentProvider;
-import org.libreoffice.storage.IFile;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FilenameFilter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Date;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
public class LibreOfficeUIActivity extends AppCompatActivity implements SettingsListenerModel.OnSettingsPreferenceChangedListener, View.OnClickListener{
- private String LOGTAG = LibreOfficeUIActivity.class.getSimpleName();
- private SharedPreferences prefs;
- private int filterMode = FileUtilities.ALL;
- private int viewMode;
- private int sortMode;
- private boolean showHiddenFiles;
- private String displayLanguage;
-
- // dynamic permissions IDs
- private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
+ public enum DocumentType {
+ WRITER,
+ CALC,
+ IMPRESS,
+ DRAW,
+ INVALID
+ }
- FileFilter fileFilter;
- FilenameFilter filenameFilter;
- private List<IFile> filePaths = new ArrayList<IFile>();
- private DocumentProviderFactory documentProviderFactory;
- private IDocumentProvider documentProvider;
- private IFile homeDirectory;
- private IFile currentDirectory;
- private int currentlySelectedFile;
+ private static final String LOGTAG = LibreOfficeUIActivity.class.getSimpleName();
- private static final String CURRENT_DIRECTORY_KEY = "CURRENT_DIRECTORY";
- private static final String DOC_PROVIDER_KEY = "CURRENT_DOCUMENT_PROVIDER";
- private static final String FILTER_MODE_KEY = "FILTER_MODE";
- public static final String EXPLORER_VIEW_TYPE_KEY = "EXPLORER_VIEW_TYPE";
public static final String EXPLORER_PREFS_KEY = "EXPLORER_PREFS";
- public static final String SORT_MODE_KEY = "SORT_MODE";
- private static final String RECENT_DOCUMENTS_KEY = "RECENT_DOCUMENTS";
- private static final String ENABLE_SHOW_HIDDEN_FILES_KEY = "ENABLE_SHOW_HIDDEN_FILES";
+ private static final String RECENT_DOCUMENTS_KEY = "RECENT_DOCUMENT_URIS";
+ // delimiter used for storing multiple URIs in a string
+ private static final String RECENT_DOCUMENTS_DELIMITER = " ";
private static final String DISPLAY_LANGUAGE = "DISPLAY_LANGUAGE";
- public static final String NEW_FILE_PATH_KEY = "NEW_FILE_PATH_KEY";
public static final String NEW_DOC_TYPE_KEY = "NEW_DOC_TYPE_KEY";
public static final String NEW_WRITER_STRING_KEY = "private:factory/swriter";
public static final String NEW_IMPRESS_STRING_KEY = "private:factory/simpress";
public static final String NEW_CALC_STRING_KEY = "private:factory/scalc";
public static final String NEW_DRAW_STRING_KEY = "private:factory/sdraw";
- public static final int GRID_VIEW = 0;
- public static final int LIST_VIEW = 1;
+ // keep this in sync with 'AndroidManifext.xml'
+ private static final String[] SUPPORTED_MIME_TYPES = {
+ "application/vnd.oasis.opendocument.text",
+ "application/vnd.oasis.opendocument.graphics",
+ "application/vnd.oasis.opendocument.presentation",
+ "application/vnd.oasis.opendocument.spreadsheet",
+ "application/vnd.oasis.opendocument.text-flat-xml",
+ "application/vnd.oasis.opendocument.graphics-flat-xml",
+ "application/vnd.oasis.opendocument.presentation-flat-xml",
+ "application/vnd.oasis.opendocument.spreadsheet-flat-xml",
+ "application/vnd.oasis.opendocument.text-template",
+ "application/vnd.oasis.opendocument.spreadsheet-template",
+ "application/vnd.oasis.opendocument.graphics-template",
+ "application/vnd.oasis.opendocument.presentation-template",
+ "application/rtf",
+ "text/rtf",
+ "application/msword",
+ "application/vnd.ms-powerpoint",
+ "application/vnd.ms-excel",
+ "application/vnd.visio",
+ "application/vnd.visio.xml",
+ "application/x-mspublisher",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
+ "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.template",
+ "application/vnd.openxmlformats-officedocument.presentationml.template",
+ "text/csv",
+ "text/comma-separated-values",
+ "application/vnd.ms-works",
+ "application/vnd.apple.keynote",
+ "application/x-abiword",
+ "application/x-pagemaker",
+ "image/x-emf",
+ "image/x-svm",
+ "image/x-wmf",
+ "image/svg+xml",
+ };
- private DrawerLayout drawerLayout;
- private NavigationView navigationDrawer;
- private ActionBar actionBar;
- private ActionBarDrawerToggle drawerToggle;
- private RecyclerView fileRecyclerView;
- private RecyclerView recentRecyclerView;
+ private static final int REQUEST_CODE_OPEN_FILECHOOSER = 12345;
- private boolean canQuit = false;
+ private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
private Animation fabOpenAnimation;
private Animation fabCloseAnimation;
@@ -156,45 +141,49 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // initialize document provider factory
- DocumentProviderFactory.initialize(this);
- documentProviderFactory = DocumentProviderFactory.getInstance();
-
- PreferenceManager.setDefaultValues(this, R.xml.documentprovider_preferences, false);
readPreferences();
SettingsListenerModel.getInstance().setListener(this);
- // Registering the USB detect broadcast receiver
- IntentFilter filter = new IntentFilter();
- filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
- filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
- registerReceiver(mUSBReceiver, filter);
- // init UI and populate with contents from the provider
-
+ // init UI
createUI();
fabOpenAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_open);
fabCloseAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_close);
}
@Override
+ protected void onStart() {
+ super.onStart();
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ Log.i(LOGTAG, "no permission to read external storage - asking for permission");
+ ActivityCompat.requestPermissions(this,
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ PERMISSION_WRITE_EXTERNAL_STORAGE);
+ }
+ }
+
+ @Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocaleHelper.onAttach(newBase));
}
public void createUI() {
-
setContentView(R.layout.activity_document_browser);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- actionBar = getSupportActionBar();
+ ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setIcon(R.mipmap.ic_launcher);
}
editFAB = findViewById(R.id.editFAB);
editFAB.setOnClickListener(this);
+ // allow creating new docs only when experimental editing is enabled
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ final boolean bEditingEnabled = BuildConfig.ALLOW_EDITING && preferences.getBoolean(LibreOfficeMainActivity.ENABLE_EXPERIMENTAL_PREFS_KEY, false);
+ editFAB.setVisibility(bEditingEnabled ? View.VISIBLE : View.INVISIBLE);
+
impressFAB = findViewById(R.id.newImpressFAB);
impressFAB.setOnClickListener(this);
writerFAB = findViewById(R.id.newWriterFAB);
@@ -207,110 +196,27 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
impressLayout = findViewById(R.id.impressLayout);
calcLayout = findViewById(R.id.calcLayout);
drawLayout = findViewById(R.id.drawLayout);
+ TextView openFileView = findViewById(R.id.open_file_button);
+ openFileView.setOnClickListener(this);
- recentRecyclerView = findViewById(R.id.list_recent);
- Set<String> recentFileStrings = prefs.getStringSet(RECENT_DOCUMENTS_KEY, new HashSet<String>());
+ RecyclerView recentRecyclerView = findViewById(R.id.list_recent);
- final ArrayList<IFile> recentFiles = new ArrayList<IFile>();
+ SharedPreferences prefs = getSharedPreferences(EXPLORER_PREFS_KEY, MODE_PRIVATE);
+ String recentPref = prefs.getString(RECENT_DOCUMENTS_KEY, "");
+ String[] recentFileStrings = recentPref.split(RECENT_DOCUMENTS_DELIMITER);
+
+ final List<RecentFile> recentFiles = new ArrayList<>();
for (String recentFileString : recentFileStrings) {
- try {
- if(documentProvider != null)
- recentFiles.add(documentProvider.createFromUri(this, new URI(recentFileString)));
- } catch (URISyntaxException e) {
- e.printStackTrace();
- } catch (RuntimeException e){
- e.printStackTrace();
+ Uri uri = Uri.parse(recentFileString);
+ String filename = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), uri);
+ if (!filename.isEmpty()) {
+ recentFiles.add(new RecentFile(uri, filename));
}
}
recentRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
recentRecyclerView.setAdapter(new RecentFilesAdapter(this, recentFiles));
-
- fileRecyclerView = findViewById(R.id.file_recycler_view);
- //This should be tested because it possibly disables view recycling
- fileRecyclerView.setNestedScrollingEnabled(false);
- openDirectory(currentDirectory);
- registerForContextMenu(fileRecyclerView);
-
- //Setting up navigation drawer
- drawerLayout = findViewById(R.id.drawer_layout);
- navigationDrawer = findViewById(R.id.navigation_drawer);
-
- final ArrayList<CharSequence> providerNames = new ArrayList<CharSequence>(
- Arrays.asList(documentProviderFactory.getNames())
- );
-
- // Loop through the document providers menu items and check if they are available or not
- for (int index = 0; index < providerNames.size(); index++) {
- MenuItem item = navigationDrawer.getMenu().getItem(index);
- item.setEnabled(documentProviderFactory.getProvider(index).checkProviderAvailability(this));
- }
-
- navigationDrawer.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
- @Override
- public boolean onNavigationItemSelected(@NonNull MenuItem item) {
-
- switch (item.getItemId()) {
- case R.id.menu_storage_preferences: {
- startActivity(new Intent(LibreOfficeUIActivity.this, DocumentProviderSettingsActivity.class));
- return true;
- }
-
- case R.id.menu_provider_documents: {
- switchToDocumentProvider(documentProviderFactory.getProvider(0));
- return true;
- }
-
- case R.id.menu_provider_filesystem: {
- switchToDocumentProvider(documentProviderFactory.getProvider(1));
- return true;
- }
-
- case R.id.menu_provider_extsd: {
- switchToDocumentProvider(documentProviderFactory.getProvider(2));
- return true;
- }
-
- case R.id.menu_provider_otg: {
- switchToDocumentProvider(documentProviderFactory.getProvider(3));
- return true;
- }
-
- case R.id.menu_provider_owncloud: {
- switchToDocumentProvider(documentProviderFactory.getProvider(4));
- return true;
- }
-
- default:
- return false;
- }
-
-
- }
- });
- drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
- R.string.document_locations, R.string.close_document_locations) {
-
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- supportInvalidateOptionsMenu();
- navigationDrawer.requestFocus(); // Make keypad navigation easier
- if (isFabMenuOpen) {
- collapseFabMenu(); //Collapse FAB Menu when drawer is opened
- }
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- supportInvalidateOptionsMenu();
- }
- };
- drawerToggle.setDrawerIndicatorEnabled(true);
- drawerLayout.addDrawerListener(drawerToggle);
- drawerToggle.syncState();
}
private void expandFabMenu() {
@@ -340,658 +246,126 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
}
@Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
-
- drawerToggle.syncState();
- }
-
- private void refreshView() {
- // enable home icon as "up" if required
- if (currentDirectory != null && homeDirectory != null && !currentDirectory.equals(homeDirectory)) {
- drawerToggle.setDrawerIndicatorEnabled(false);
- } else {
- drawerToggle.setDrawerIndicatorEnabled(true);
- }
-
- FileUtilities.sortFiles(filePaths, sortMode);
- // refresh view
- fileRecyclerView.setLayoutManager(isViewModeList() ? new LinearLayoutManager(this) : new GridLayoutManager(this, 3));
- fileRecyclerView.setAdapter(new ExplorerItemAdapter(this, filePaths));
- // close drawer if it was open
- drawerLayout.closeDrawer(navigationDrawer);
+ public void onBackPressed() {
if (isFabMenuOpen) {
collapseFabMenu();
+ } else {
+ super.onBackPressed();
}
}
@Override
- public void onBackPressed() {
- if (drawerLayout.isDrawerOpen(navigationDrawer)) {
- drawerLayout.closeDrawer(navigationDrawer);
- if (isFabMenuOpen) {
- collapseFabMenu();
- }
- } else if (currentDirectory != null && homeDirectory != null && !currentDirectory.equals(homeDirectory)) {
- // navigate upwards in directory hierarchy
- openParentDirectory();
- } else if (isFabMenuOpen) {
- collapseFabMenu();
- } else {
- // only exit if warning has been shown
- if (canQuit) {
- super.onBackPressed();
- return;
- }
-
- // show warning about leaving the app and set a timer
- Toast.makeText(this, R.string.back_again_to_quit,
- Toast.LENGTH_SHORT).show();
- canQuit = true;
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- canQuit = false;
- }
- }, 3000);
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == REQUEST_CODE_OPEN_FILECHOOSER && resultCode == RESULT_OK) {
+ final Uri fileUri = data.getData();
+ openDocument(fileUri);
}
}
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v,
- ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.context_menu, menu);
- }
+ private void showSystemFilePickerAndOpenFile() {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.setType("*/*");
+ intent.putExtra(Intent.EXTRA_MIME_TYPES, SUPPORTED_MIME_TYPES);
- @Override
- public boolean onContextItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.context_menu_open:
- open(currentlySelectedFile);
- return true;
- case R.id.context_menu_share:
- share(currentlySelectedFile);
- return true;
- default:
- return super.onContextItemSelected(item);
+ try {
+ startActivityForResult(intent, REQUEST_CODE_OPEN_FILECHOOSER);
+ } catch (ActivityNotFoundException e) {
+ Log.w(LOGTAG, "No activity available that can handle the intent to open a document.");
}
}
- private boolean isViewModeList(){
- return viewMode == LIST_VIEW;
- }
-
- private void switchToDocumentProvider(IDocumentProvider provider) {
+ public void openDocument(final Uri documentUri) {
+ // "forward" to LibreOfficeMainActivity to open the file
+ Intent intent = new Intent(Intent.ACTION_VIEW, documentUri);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- new AsyncTask<IDocumentProvider, Void, Void>() {
- @Override
- protected Void doInBackground(IDocumentProvider... provider) {
- // switch document provider:
- // these operations may imply network access and must be run in
- // a different thread
- try {
- homeDirectory = provider[0].getRootDirectory(LibreOfficeUIActivity.this);
- List<IFile> paths = homeDirectory.listFiles(FileUtilities
- .getFileFilter(filterMode));
- filePaths = new ArrayList<IFile>();
- for(IFile file: paths) {
- if(showHiddenFiles){
- filePaths.add(file);
- } else {
- if(!file.getName().startsWith(".")){
- filePaths.add(file);
- }
- }
- }
- }
- catch (final RuntimeException e) {
- final Activity activity = LibreOfficeUIActivity.this;
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(activity, e.getMessage(),
- Toast.LENGTH_SHORT).show();
- }
- });
- startActivity(new Intent(activity, DocumentProviderSettingsActivity.class));
- Log.e(LOGTAG, "failed to switch document provider "+ e.getMessage(), e.getCause());
- return null;
- }
- //no exception
- documentProvider = provider[0];
- currentDirectory = homeDirectory;
- return null;
- }
+ addDocumentToRecents(documentUri);
- @Override
- protected void onPostExecute(Void result) {
- refreshView();
- }
- }.execute(provider);
+ String packageName = getApplicationContext().getPackageName();
+ ComponentName componentName = new ComponentName(packageName,
+ LibreOfficeMainActivity.class.getName());
+ intent.setComponent(componentName);
+ startActivity(intent);
}
- public void openDirectory(IFile dir) {
- if (dir == null)
- return;
-
- //show recent files if in home directory
- if (dir.equals(homeDirectory)) {
- recentRecyclerView.setVisibility(View.VISIBLE);
- findViewById(R.id.header_browser).setVisibility((View.VISIBLE));
- findViewById(R.id.header_recents).setVisibility((View.VISIBLE));
- actionBar.setTitle(R.string.app_name);
- findViewById(R.id.text_directory_path).setVisibility(View.GONE);
+ private void loadNewDocument(DocumentType docType) {
+ final String newDocumentType;
+ if (docType == DocumentType.WRITER) {
+ newDocumentType = NEW_WRITER_STRING_KEY;
+ } else if (docType == DocumentType.CALC) {
+ newDocumentType = NEW_CALC_STRING_KEY;
+ } else if (docType == DocumentType.IMPRESS) {
+ newDocumentType = NEW_IMPRESS_STRING_KEY;
+ } else if (docType == DocumentType.DRAW) {
+ newDocumentType = NEW_DRAW_STRING_KEY;
} else {
- recentRecyclerView.setVisibility(View.GONE);
- findViewById(R.id.header_browser).setVisibility((View.GONE));
- findViewById(R.id.header_recents).setVisibility((View.GONE));
- actionBar.setTitle(dir.getName());
- findViewById(R.id.text_directory_path).setVisibility(View.VISIBLE);
- ((TextView)findViewById(R.id.text_directory_path)).setText(getString(R.string.current_dir,
- dir.getUri().getPath()));
+ Log.w(LOGTAG, "invalid document type passed to loadNewDocument method. Ignoring request");
+ return;
}
- new AsyncTask<IFile, Void, Void>() {
- @Override
- protected Void doInBackground(IFile... dir) {
- // get list of files:
- // this operation may imply network access and must be run in
- // a different thread
- currentDirectory = dir[0];
- try {
- List<IFile> paths = currentDirectory.listFiles(FileUtilities
- .getFileFilter(filterMode));
- filePaths = new ArrayList<IFile>();
- for(IFile file: paths) {
- if(showHiddenFiles){
- filePaths.add(file);
- } else {
- if(!file.getName().startsWith(".")){
- filePaths.add(file);
- }
- }
- }
- }
- catch (final RuntimeException e) {
- final Activity activity = LibreOfficeUIActivity.this;
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(activity, e.getMessage(),
- Toast.LENGTH_SHORT).show();
- }
- });
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Void result) {
- refreshView();
- }
- }.execute(dir);
- }
-
- public void open(final IFile document) {
- addDocumentToRecents(document);
- new AsyncTask<IFile, Void, File>() {
- @Override
- protected File doInBackground(IFile... document) {
- // this operation may imply network access and must be run in
- // a different thread
- try {
- return document[0].getDocument();
- }
- catch (final RuntimeException e) {
- final Activity activity = LibreOfficeUIActivity.this;
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(activity, e.getMessage(),
- Toast.LENGTH_SHORT).show();
- }
- });
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(File file) {
- if (file != null) {
- Intent i = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
- String packageName = getApplicationContext().getPackageName();
- ComponentName componentName = new ComponentName(packageName,
- LibreOfficeMainActivity.class.getName());
- i.setComponent(componentName);
-
- // these extras allow to rebuild the IFile object in LOMainActivity
- i.putExtra("org.libreoffice.document_provider_id",
- documentProvider.getId());
- i.putExtra("org.libreoffice.document_uri",
- document.getUri());
-
- startActivity(i);
- }
- }
- }.execute(document);
- }
-
- // Opens an Input dialog to get the name of new file
- private void createNewFileInputDialog(final String defaultFileName, final String newDocumentType) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.create_new_document_title);
- final EditText input = new EditText(this);
- input.setInputType(InputType.TYPE_CLASS_TEXT);
- input.setText(defaultFileName);
- builder.setView(input);
-
- builder.setPositiveButton(R.string.action_create, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final String newFilePath = currentDirectory.getUri().getPath() + input.getText().toString();
- loadNewDocument(newDocumentType, newFilePath);
- }
- });
-
- builder.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
-
- builder.show();
- }
-
- private void loadNewDocument(String newDocumentType, String newFilePath) {
Intent intent = new Intent(LibreOfficeUIActivity.this, LibreOfficeMainActivity.class);
intent.putExtra(NEW_DOC_TYPE_KEY, newDocumentType);
- intent.putExtra(NEW_FILE_PATH_KEY, newFilePath);
startActivity(intent);
}
- private void open(int position) {
- IFile file = filePaths.get(position);
- if (!file.isDirectory()) {
- open(file);
- } else {
- openDirectory(file);
- }
- }
-
- private void openParentDirectory() {
- new AsyncTask<Void, Void, IFile>() {
- @Override
- protected IFile doInBackground(Void... dir) {
- // this operation may imply network access and must be run in
- // a different thread
- return currentDirectory.getParent(LibreOfficeUIActivity.this);
- }
-
- @Override
- protected void onPostExecute(IFile result) {
- openDirectory(result);
- }
- }.execute();
- }
-
- private void share(int position) {
-
- new AsyncTask<IFile, Void, File>() {
- @Override
- protected File doInBackground(IFile... document) {
- // this operation may imply network access and must be run in
- // a different thread
- try {
- return document[0].getDocument();
- } catch (final RuntimeException e) {
- final Activity activity = LibreOfficeUIActivity.this;
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(activity, e.getMessage(),
- Toast.LENGTH_SHORT).show();
- }
- });
- Log.e(LOGTAG, e.getMessage(), e.getCause());
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(File file) {
- if (file != null) {
- Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
- Uri uri = Uri.fromFile(file);
- sharingIntent.setType(FileUtilities.getMimeType(file.getName()));
- sharingIntent.putExtra(android.content.Intent.EXTRA_STREAM, uri);
- sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
- file.getName());
- startActivity(Intent.createChooser(sharingIntent,
- getString(R.string.share_via)));
- }
- }
- }.execute(filePaths.get(position));
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.view_menu, menu);
- switch (sortMode) {
- case FileUtilities.SORT_SMALLEST: {
- menu.findItem(R.id.menu_sort_size_asc).setChecked(true);
- }
- break;
-
- case FileUtilities.SORT_LARGEST: {
- menu.findItem(R.id.menu_sort_size_desc).setChecked(true);
- }
- break;
-
- case FileUtilities.SORT_AZ: {
- menu.findItem(R.id.menu_sort_az).setChecked(true);
- }
- break;
-
- case FileUtilities.SORT_ZA: {
- menu.findItem(R.id.menu_sort_za).setChecked(true);
- }
- break;
-
- case FileUtilities.SORT_NEWEST: {
- menu.findItem(R.id.menu_sort_modified_newest).setChecked(true);
- }
- break;
-
- case FileUtilities.SORT_OLDEST: {
- menu.findItem(R.id.menu_sort_modified_oldest).setChecked(true);
- }
- break;
- }
-
- switch (filterMode) {
- case FileUtilities.ALL:
- menu.findItem(R.id.menu_filter_everything).setChecked(true);
- break;
-
- case FileUtilities.DOC:
- menu.findItem(R.id.menu_filter_documents).setChecked(true);
- break;
-
- case FileUtilities.CALC:
- menu.findItem(R.id.menu_filter_presentations).setChecked(true);
- break;
-
- case FileUtilities.IMPRESS:
- menu.findItem(R.id.menu_filter_presentations).setChecked(true);
- break;
-
- case FileUtilities.DRAWING:
- menu.findItem(R.id.menu_filter_drawings).setChecked(true);
- break;
- }
-
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- // Will close the drawer if the home button is pressed
- if (drawerToggle.onOptionsItemSelected(item)) {
+ final int itemId = item.getItemId();
+ if (itemId == R.id.action_about) {
+ AboutDialogFragment aboutDialogFragment = new AboutDialogFragment();
+ aboutDialogFragment.show(getSupportFragmentManager(), "AboutDialogFragment");
return true;
}
-
- switch (item.getItemId()) {
- case android.R.id.home:
- if (!currentDirectory.equals(homeDirectory)){
- openParentDirectory();
- }
- break;
-
- case R.id.menu_filter_everything:
- item.setChecked(true);
- filterMode = FileUtilities.ALL;
- openDirectory(currentDirectory);
- break;
-
- case R.id.menu_filter_documents:
- item.setChecked(true);
- filterMode = FileUtilities.DOC;
- openDirectory(currentDirectory);
- break;
-
- case R.id.menu_filter_spreadsheets:
- item.setChecked(true);
- filterMode = FileUtilities.CALC;
- openDirectory(currentDirectory);
- break;
-
- case R.id.menu_filter_presentations:
- item.setChecked(true);
- filterMode = FileUtilities.IMPRESS;
- openDirectory(currentDirectory);
- break;
-
- case R.id.menu_filter_drawings:
- item.setChecked(true);
- filterMode = FileUtilities.DRAWING;
- openDirectory(currentDirectory);
- break;
-
- case R.id.menu_sort_size_asc: {
- sortMode = FileUtilities.SORT_SMALLEST;
- this.onResume();
- }
- break;
-
- case R.id.menu_sort_size_desc: {
- sortMode = FileUtilities.SORT_LARGEST;
- this.onResume();
- }
- break;
-
- case R.id.menu_sort_az: {
- sortMode = FileUtilities.SORT_AZ;
- this.onResume();
- }
- break;
-
- case R.id.menu_sort_za: {
- sortMode = FileUtilities.SORT_ZA;
- this.onResume();
- }
- break;
-
- case R.id.menu_sort_modified_newest: {
- sortMode = FileUtilities.SORT_NEWEST;
- this.onResume();
- }
- break;
-
- case R.id.menu_sort_modified_oldest: {
- sortMode = FileUtilities.SORT_OLDEST;
- this.onResume();
- }
- break;
-
- case R.id.action_about: {
- AboutDialogFragment aboutDialogFragment = new AboutDialogFragment();
- aboutDialogFragment.show(getSupportFragmentManager(), "AboutDialogFragment");
- }
- return true;
- case R.id.action_settings:
- startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
+ if (itemId == R.id.action_settings) {
+ startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
+ return true;
}
- return true;
+
+ return super.onOptionsItemSelected(item);
}
public void readPreferences(){
- prefs = getSharedPreferences(EXPLORER_PREFS_KEY, MODE_PRIVATE);
- sortMode = prefs.getInt(SORT_MODE_KEY, FileUtilities.SORT_AZ);
SharedPreferences defaultPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
- viewMode = Integer.valueOf(defaultPrefs.getString(EXPLORER_VIEW_TYPE_KEY, ""+ GRID_VIEW));
- filterMode = Integer.valueOf(defaultPrefs.getString(FILTER_MODE_KEY , "-1"));
- showHiddenFiles = defaultPrefs.getBoolean(ENABLE_SHOW_HIDDEN_FILES_KEY, false);
- displayLanguage = defaultPrefs.getString(DISPLAY_LANGUAGE, LocaleHelper.SYSTEM_DEFAULT_LANGUAGE);
-
- Intent i = this.getIntent();
- if (i.hasExtra(CURRENT_DIRECTORY_KEY)) {
- try {
- currentDirectory = documentProvider.createFromUri(this, new URI(
- i.getStringExtra(CURRENT_DIRECTORY_KEY)));
- } catch (URISyntaxException e) {
- currentDirectory = documentProvider.getRootDirectory(this);
- }
- Log.d(LOGTAG, CURRENT_DIRECTORY_KEY);
- }
-
- if (i.hasExtra(FILTER_MODE_KEY)) {
- filterMode = i.getIntExtra( FILTER_MODE_KEY, FileUtilities.ALL);
- Log.d(LOGTAG, FILTER_MODE_KEY);
- }
-
- if (i.hasExtra(EXPLORER_VIEW_TYPE_KEY)) {
- viewMode = i.getIntExtra( EXPLORER_VIEW_TYPE_KEY, GRID_VIEW);
- Log.d(LOGTAG, EXPLORER_VIEW_TYPE_KEY);
- }
-
+ final String displayLanguage = defaultPrefs.getString(DISPLAY_LANGUAGE, LocaleHelper.SYSTEM_DEFAULT_LANGUAGE);
LocaleHelper.setLocale(this, displayLanguage);
}
@Override
public void settingsPreferenceChanged(SharedPreferences sharedPreferences, String key) {
readPreferences();
- refreshView();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- // TODO Auto-generated method stub
- super.onSaveInstanceState(outState);
-
- if(currentDirectory != null) {
- outState.putString(CURRENT_DIRECTORY_KEY, currentDirectory.getUri().toString());
- Log.d(LOGTAG, currentDirectory.toString() + Integer.toString(filterMode) + Integer.toString(viewMode));
- }
- outState.putInt(FILTER_MODE_KEY, filterMode);
- outState.putInt(EXPLORER_VIEW_TYPE_KEY , viewMode);
- if(documentProvider != null)
- outState.putInt(DOC_PROVIDER_KEY, documentProvider.getId());
-
- outState.putBoolean(ENABLE_SHOW_HIDDEN_FILES_KEY , showHiddenFiles);
-
- //prefs.edit().putInt(EXPLORER_VIEW_TYPE, viewType).commit();
- Log.d(LOGTAG, "savedInstanceState");
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onRestoreInstanceState(savedInstanceState);
- if (savedInstanceState.isEmpty()){
- return;
- }
- if (documentProvider == null) {
- Log.d(LOGTAG, "onRestoreInstanceState - documentProvider is null");
- documentProvider = DocumentProviderFactory.getInstance()
- .getProvider(savedInstanceState.getInt(DOC_PROVIDER_KEY));
- }
- try {
- currentDirectory = documentProvider.createFromUri(this, new URI(
- savedInstanceState.getString(CURRENT_DIRECTORY_KEY)));
- } catch (URISyntaxException e) {
- currentDirectory = documentProvider.getRootDirectory(this);
- }
- filterMode = savedInstanceState.getInt(FILTER_MODE_KEY, FileUtilities.ALL);
- viewMode = savedInstanceState.getInt(EXPLORER_VIEW_TYPE_KEY, GRID_VIEW);
- showHiddenFiles = savedInstanceState.getBoolean(ENABLE_SHOW_HIDDEN_FILES_KEY, false);
- //openDirectory(currentDirectory);
- Log.d(LOGTAG, "onRestoreInstanceState");
- Log.d(LOGTAG, currentDirectory.toString() + Integer.toString(filterMode) + Integer.toString(viewMode));
- }
-
- private final BroadcastReceiver mUSBReceiver = new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
- Toast.makeText(context, R.string.usb_connected_configure, Toast.LENGTH_SHORT).show();
- startActivity(new Intent(context, DocumentProviderSettingsActivity.class));
- Log.d(LOGTAG, "USB device attached");
- } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
- Log.d(LOGTAG, "USB device detached");
- }
- }
- };
- @Override
- protected void onPause() {
- super.onPause();
- Log.d(LOGTAG, "onPause");
}
@Override
protected void onResume() {
super.onResume();
Log.d(LOGTAG, "onResume");
- Log.d(LOGTAG, "sortMode="+ sortMode + " filterMode=" + filterMode);
createUI();
}
- @Override
- protected void onStart() {
- super.onStart();
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
- Log.i(LOGTAG, "no permission to read external storage - asking for permission");
- ActivityCompat.requestPermissions(this,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
- PERMISSION_WRITE_EXTERNAL_STORAGE);
- } else {
- switchToDocumentProvider(documentProviderFactory.getDefaultProvider());
- setEditFABVisibility(View.VISIBLE);
- }
- Log.d(LOGTAG, "onStart");
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- Log.d(LOGTAG, "onStop");
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unregisterReceiver(mUSBReceiver);
- Log.d(LOGTAG, "onDestroy");
- }
-
- private int dpToPx(int dp){
- final float scale = getApplicationContext().getResources().getDisplayMetrics().density;
- return (int) (dp * scale + 0.5f);
- }
+ private void addDocumentToRecents(Uri fileUri) {
+ SharedPreferences prefs = getSharedPreferences(EXPLORER_PREFS_KEY, MODE_PRIVATE);
- private void addDocumentToRecents(IFile iFile) {
- String newRecent = iFile.getUri().toString();
- Set<String> recentsSet = prefs.getStringSet(RECENT_DOCUMENTS_KEY, new HashSet<String>());
+ // preserve permissions across device reboots,
+ // s. https://developer.android.com/training/data-storage/shared/documents-files#persist-permissions
+ getContentResolver().takePersistableUriPermission(fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
- //create array to work with
- ArrayList<String> recentsArrayList = new ArrayList<String>(recentsSet);
+ String newRecent = fileUri.toString();
+ List<String> recentsList = new ArrayList<>(Arrays.asList(prefs.getString(RECENT_DOCUMENTS_KEY, "").split(RECENT_DOCUMENTS_DELIMITER)));
- //remove string if present, so that it doesn't appear multiple times
- recentsSet.remove(newRecent);
-
- //put the new value in the first place
- recentsArrayList.add(0, newRecent);
+ // remove string if present, so that it doesn't appear multiple times
+ recentsList.remove(newRecent);
+ // put the new value in the first place
+ recentsList.add(0, newRecent);
/*
* 4 because the number of recommended items in App Shortcuts is 4, and also
@@ -999,15 +373,13 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
*/
final int RECENTS_SIZE = 4;
- while (recentsArrayList.size() > RECENTS_SIZE) {
- recentsArrayList.remove(RECENTS_SIZE);
+ while (recentsList.size() > RECENTS_SIZE) {
+ recentsList.remove(RECENTS_SIZE);
}
- //switch to Set, so that it could be inserted into prefs
- recentsSet = new HashSet<String>(recentsArrayList);
-
- prefs.edit().putStringSet(RECENT_DOCUMENTS_KEY, recentsSet).apply();
-
+ // serialize to String that can be set for pref
+ String value = TextUtils.join(RECENT_DOCUMENTS_DELIMITER, recentsList);
+ prefs.edit().putString(RECENT_DOCUMENTS_KEY, value).apply();
//update app shortcuts (7.0 and above)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
@@ -1016,12 +388,17 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
//Remove all shortcuts, and apply new ones.
shortcutManager.removeAllDynamicShortcuts();
- ArrayList<ShortcutInfo> shortcuts = new ArrayList<ShortcutInfo>();
- for (String pathString : recentsArrayList) {
+ ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+ for (String recentDoc : recentsList) {
+ Uri docUri = Uri.parse(recentDoc);
+ String filename = FileUtilities.retrieveDisplayNameForDocumentUri(getContentResolver(), docUri);
+ if (filename.isEmpty()) {
+ continue;
+ }
//find the appropriate drawable
int drawable = 0;
- switch (FileUtilities.getType(pathString)) {
+ switch (FileUtilities.getType(filename)) {
case FileUtilities.DOC:
drawable = R.drawable.writer;
break;
@@ -1036,12 +413,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
break;
}
- File file = new File(pathString);
-
- //for some reason, getName uses %20 instead of space
- String filename = file.getName().replace("%20", " ");
-
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.fromFile(file));
+ Intent intent = new Intent(Intent.ACTION_VIEW, docUri);
String packageName = this.getApplicationContext().getPackageName();
ComponentName componentName = new ComponentName(packageName, LibreOfficeMainActivity.class.getName());
intent.setComponent(componentName);
@@ -1062,161 +434,22 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
@Override
public void onClick(View v) {
int id = v.getId();
- switch (id){
- case R.id.editFAB:
- if (isFabMenuOpen) {
- collapseFabMenu();
- } else {
- expandFabMenu();
- }
- break;
- case R.id.newWriterFAB:
- createNewFileInputDialog(getString(R.string.default_document_name) + FileUtilities.DEFAULT_WRITER_EXTENSION, NEW_WRITER_STRING_KEY);
- break;
- case R.id.newImpressFAB:
- createNewFileInputDialog(getString(R.string.default_document_name) + FileUtilities.DEFAULT_IMPRESS_EXTENSION, NEW_IMPRESS_STRING_KEY);
- break;
- case R.id.newCalcFAB:
- createNewFileInputDialog(getString(R.string.default_document_name) + FileUtilities.DEFAULT_SPREADSHEET_EXTENSION, NEW_CALC_STRING_KEY);
- break;
- case R.id.newDrawFAB:
- createNewFileInputDialog(getString(R.string.default_document_name) + FileUtilities.DEFAULT_DRAWING_EXTENSION, NEW_DRAW_STRING_KEY);
- break;
- }
- }
-
-
- class ExplorerItemAdapter extends RecyclerView.Adapter<ExplorerItemAdapter.ViewHolder> {
-
- private Activity mActivity;
- private List<IFile> filePaths;
- private final long KB = 1024;
- private final long MB = 1048576;
-
- ExplorerItemAdapter(Activity activity, List<IFile> filePaths) {
- this.mActivity = activity;
- this.filePaths = filePaths;
- }
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View item = LayoutInflater.from(parent.getContext())
- .inflate(isViewModeList() ? R.layout.file_list_item : R.layout.file_explorer_grid_item, parent, false);
- return new ViewHolder(item);
- }
-
- @Override
- public void onBindViewHolder(final ViewHolder holder, final int position) {
- final IFile file = filePaths.get(position);
-
- holder.itemView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- open(holder.getAdapterPosition());
- }
- });
- holder.itemView.setOnLongClickListener(new OnLongClickListener() {
-
- @Override
- public boolean onLongClick(View view) {
- //to be picked out by floating context menu (workaround-ish)
- currentlySelectedFile = holder.getAdapterPosition();
- //must return false so the click is not consumed
- return false;
- }
- });
-
- holder.filenameView.setText(file.getName());
- switch (FileUtilities.getType(file.getName())) {
- case FileUtilities.DOC:
- holder.iconView.setImageResource(R.drawable.writer);
- break;
- case FileUtilities.CALC:
- holder.iconView.setImageResource(R.drawable.calc);
- break;
- case FileUtilities.DRAWING:
- holder.iconView.setImageResource(R.drawable.draw);
- break;
- case FileUtilities.IMPRESS:
- holder.iconView.setImageResource(R.drawable.impress);
- break;
- }
-
- if (file.isDirectory()) {
- //Eventually have thumbnails of each sub file on a black circle
- //For now just a folder icon
- holder.iconView.setImageResource(R.drawable.ic_folder_black_24dp);
- holder.iconView.setColorFilter(ContextCompat.getColor(mActivity, R.color.text_color_secondary));
- }
-
- // Date and Size field only exist when we are displaying items in a list.
- if(isViewModeList()) {
- if (!file.isDirectory()) {
- String size;
- long length = filePaths.get(position).getSize();
- if (length < KB) {
- size = Long.toString(length) + "B";
- } else if (length < MB) {
- size = Long.toString(length / KB) + "KB";
- } else {
- size = Long.toString(length / MB) + "MB";
- }
- holder.fileSizeView.setText(size);
- }
- SimpleDateFormat df = new SimpleDateFormat("dd MMM yyyy hh:ss");
- Date date = file.getLastModified();
- //TODO format date
- holder.fileDateView.setText(df.format(date));
- }
- }
-
- @Override
- public int getItemCount() {
- return filePaths.size();
- }
-
- class ViewHolder extends RecyclerView.ViewHolder {
-
- View itemView;
- TextView filenameView, fileSizeView, fileDateView;
- ImageView iconView;
-
- ViewHolder(View itemView) {
- super(itemView);
- this.itemView = itemView;
- filenameView = itemView.findViewById(R.id.file_item_name);
- iconView = itemView.findViewById(R.id.file_item_icon);
- // Check if view mode is List, only then initialise Size and Date field
- if (isViewModeList()) {
- fileSizeView = itemView.findViewById(R.id.file_item_size);
- fileDateView = itemView.findViewById(R.id.file_item_date);
- }
- }
- }
- }
-
- private void setEditFABVisibility(final int visibility){
- LOKitShell.getMainHandler().post(new Runnable() {
- @Override
- public void run() {
- editFAB.setVisibility(visibility);
- }
- });
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- switch(requestCode){
- case PERMISSION_WRITE_EXTERNAL_STORAGE:
- if(permissions.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
- switchToDocumentProvider(documentProviderFactory.getDefaultProvider());
- setEditFABVisibility(View.VISIBLE);
- } else {
- setEditFABVisibility(View.INVISIBLE);
- }
- break;
- default:
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (id == R.id.editFAB) {
+ if (isFabMenuOpen) {
+ collapseFabMenu();
+ } else {
+ expandFabMenu();
+ }
+ } else if (id == R.id.open_file_button) {
+ showSystemFilePickerAndOpenFile();
+ } else if (id == R.id.newWriterFAB) {
+ loadNewDocument(DocumentType.WRITER);
+ } else if (id == R.id.newImpressFAB) {
+ loadNewDocument(DocumentType.IMPRESS);
+ } else if (id == R.id.newCalcFAB) {
+ loadNewDocument(DocumentType.CALC);
+ } else if (id == R.id.newDrawFAB) {
+ loadNewDocument(DocumentType.DRAW);
}
}
}
diff --git a/android/source/src/java/org/libreoffice/ui/PageView.java b/android/source/src/java/org/libreoffice/ui/PageView.java
index 1d32a7de7e80..4c3f69562250 100644
--- a/android/source/src/java/org/libreoffice/ui/PageView.java
+++ b/android/source/src/java/org/libreoffice/ui/PageView.java
@@ -17,29 +17,29 @@ import android.view.View;
public class PageView extends View{
private Bitmap bmp;
private Paint mPaintBlack;
- private String tag = "PageView";
+ private static final String LOGTAG = "PageView";
public PageView(Context context ) {
super(context);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.dummy_page);
- intialise();
+ initialise();
}
public PageView(Context context, AttributeSet attrs) {
super(context, attrs);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.dummy_page);
- Log.d( tag , bmp.toString());
- intialise();
+ Log.d(LOGTAG, bmp.toString());
+ initialise();
}
public PageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.dummy_page);//load a "page"
- intialise();
+ initialise();
}
- private void intialise(){
+ private void initialise(){
mPaintBlack = new Paint();
mPaintBlack.setARGB(255, 0, 0, 0);
- Log.d(tag, " Doing some set-up");
+ Log.d(LOGTAG, " Doing some set-up");
}
public void setBitmap(Bitmap bmp){
@@ -49,8 +49,8 @@ public class PageView extends View{
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- Log.d(tag, "Draw");
- Log.d(tag, Integer.toString(bmp.getHeight()));
+ Log.d(LOGTAG, "Draw");
+ Log.d(LOGTAG, Integer.toString(bmp.getHeight()));
if( bmp != null ){
int horizontalMargin = (int) (canvas.getWidth()*0.1);
//int verticalMargin = (int) (canvas.getHeight()*0.1);
diff --git a/android/source/src/java/org/libreoffice/ui/RecentFile.java b/android/source/src/java/org/libreoffice/ui/RecentFile.java
new file mode 100644
index 000000000000..fdcc688aa140
--- /dev/null
+++ b/android/source/src/java/org/libreoffice/ui/RecentFile.java
@@ -0,0 +1,25 @@
+package org.libreoffice.ui;
+
+import android.net.Uri;
+
+/**
+ * An entry for a recently used file in the RecentFilesAdapter.
+ */
+public class RecentFile {
+
+ private final Uri uri;
+ private final String displayName;
+
+ public RecentFile(Uri docUri, String name) {
+ uri = docUri;
+ displayName = name;
+ }
+
+ public Uri getUri() {
+ return uri;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+}
diff --git a/android/source/src/java/org/libreoffice/ui/RecentFilesAdapter.java b/android/source/src/java/org/libreoffice/ui/RecentFilesAdapter.java
index fc16d06a48d7..ef00b9fb6cfd 100644
--- a/android/source/src/java/org/libreoffice/ui/RecentFilesAdapter.java
+++ b/android/source/src/java/org/libreoffice/ui/RecentFilesAdapter.java
@@ -9,8 +9,8 @@
package org.libreoffice.ui;
-import android.support.v4.content.ContextCompat;
-import android.support.v7.widget.RecyclerView;
+import androidx.core.content.ContextCompat;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -18,16 +18,15 @@ import android.widget.ImageView;
import android.widget.TextView;
import org.libreoffice.R;
-import org.libreoffice.storage.IFile;
import java.util.List;
class RecentFilesAdapter extends RecyclerView.Adapter<RecentFilesAdapter.ViewHolder> {
- private LibreOfficeUIActivity mActivity;
- private List<IFile> recentFiles;
+ private final LibreOfficeUIActivity mActivity;
+ private final List<RecentFile> recentFiles;
- RecentFilesAdapter(LibreOfficeUIActivity activity, List<IFile> recentFiles) {
+ RecentFilesAdapter(LibreOfficeUIActivity activity, List<RecentFile> recentFiles) {
this.mActivity = activity;
this.recentFiles = recentFiles;
}
@@ -41,17 +40,16 @@ class RecentFilesAdapter extends RecyclerView.Adapter<RecentFilesAdapter.ViewHol
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
- final IFile iFile = recentFiles.get(position);
+ final RecentFile entry = recentFiles.get(position);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- mActivity.open(iFile);
+ mActivity.openDocument(entry.getUri());
}
});
- String filename = iFile.getName();
-
+ final String filename = entry.getDisplayName();
holder.textView.setText(filename);
int compoundDrawableInt = 0;
diff --git a/android/source/src/java/org/mozilla/gecko/ZoomConstraints.java b/android/source/src/java/org/mozilla/gecko/ZoomConstraints.java
index f1672ba3dd76..dbe278827279 100644
--- a/android/source/src/java/org/mozilla/gecko/ZoomConstraints.java
+++ b/android/source/src/java/org/mozilla/gecko/ZoomConstraints.java
@@ -6,28 +6,16 @@
package org.mozilla.gecko;
public final class ZoomConstraints {
- private final boolean mAllowZoom;
- private final boolean mAllowDoubleTapZoom;
private final float mDefaultZoom;
private final float mMinZoom;
private final float mMaxZoom;
- public ZoomConstraints(boolean allowZoom, float defaultZoom, float minZoom, float maxZoom) {
- mAllowZoom = allowZoom;
- mAllowDoubleTapZoom = allowZoom;
+ public ZoomConstraints(float defaultZoom, float minZoom, float maxZoom) {
mDefaultZoom = defaultZoom;
mMinZoom = minZoom;
mMaxZoom = maxZoom;
}
- public final boolean getAllowZoom() {
- return mAllowZoom;
- }
-
- public final boolean getAllowDoubleTapZoom() {
- return mAllowDoubleTapZoom;
- }
-
public final float getDefaultZoom() {
return mDefaultZoom;
}
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/GLController.java b/android/source/src/java/org/mozilla/gecko/gfx/GLController.java
index e296f4760f68..6a43dd6a87db 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/GLController.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/GLController.java
@@ -20,7 +20,6 @@ public class GLController {
private LayerView mView;
private int mGLVersion;
- private boolean mSurfaceValid;
private int mWidth, mHeight;
private EGL10 mEGL;
@@ -29,8 +28,6 @@ public class GLController {
private EGLContext mEGLContext;
private EGLSurface mEGLSurface;
- private GL mGL;
-
private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4;
private static final int[] CONFIG_SPEC = {
@@ -45,7 +42,6 @@ public class GLController {
public GLController(LayerView view) {
mView = view;
mGLVersion = 2;
- mSurfaceValid = false;
}
public void setGLVersion(int version) {
@@ -84,12 +80,11 @@ public class GLController {
getEGLError());
}
- mGL = null;
mEGLContext = null;
}
}
- public GL getGL() { return mEGLContext.getGL(); }
+ public GL10 getGL() { return (GL10) mEGLContext.getGL(); }
public EGLDisplay getEGLDisplay() { return mEGLDisplay; }
public EGLConfig getEGLConfig() { return mEGLConfig; }
public EGLContext getEGLContext() { return mEGLContext; }
@@ -104,38 +99,6 @@ public class GLController {
return mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface);
}
- public boolean checkForLostContext() {
- if (mEGL.eglGetError() != EGL11.EGL_CONTEXT_LOST) {
- return false;
- }
-
- mEGLDisplay = null;
- mEGLConfig = null;
- mEGLContext = null;
- mEGLSurface = null;
- mGL = null;
- return true;
- }
-
- // This function is invoked by JNI
- public synchronized void resumeCompositorIfValid() {
- if (mSurfaceValid) {
- mView.getListener().compositionResumeRequested(mWidth, mHeight);
- }
- }
-
- // Wait until we are allowed to use EGL functions on the Surface backing
- // this window. This function is invoked by JNI
- public synchronized void waitForValidSurface() {
- while (!mSurfaceValid) {
- try {
- wait();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
public synchronized int getWidth() {
return mWidth;
}
@@ -145,14 +108,12 @@ public class GLController {
}
synchronized void surfaceDestroyed() {
- mSurfaceValid = false;
notifyAll();
}
synchronized void surfaceChanged(int newWidth, int newHeight) {
mWidth = newWidth;
mHeight = newHeight;
- mSurfaceValid = true;
notifyAll();
}
@@ -183,11 +144,10 @@ public class GLController {
getEGLError());
}
- mGL = mEGLContext.getGL();
-
if (mView.getRenderer() != null) {
- mView.getRenderer().onSurfaceCreated((GL10)mGL, mEGLConfig);
- mView.getRenderer().onSurfaceChanged((GL10)mGL, mWidth, mHeight);
+ GL10 gl = (GL10) mEGLContext.getGL();
+ mView.getRenderer().onSurfaceCreated(gl, mEGLConfig);
+ mView.getRenderer().onSurfaceChanged(gl, mWidth, mHeight);
}
}
@@ -216,7 +176,8 @@ public class GLController {
}
}
- throw new GLControllerException("No suitable EGL configuration found");
+ // if there's no 565 RGB configuration, select another one that fulfils the specification
+ return configs[0];
}
private void createEGLSurface() {
@@ -232,32 +193,11 @@ public class GLController {
"surface! " + getEGLError());
}
- mGL = mEGLContext.getGL();
-
if (mView.getRenderer() != null) {
- mView.getRenderer().onSurfaceCreated((GL10)mGL, mEGLConfig);
- mView.getRenderer().onSurfaceChanged((GL10)mGL, mView.getWidth(), mView.getHeight());
- }
- }
-
- /**
- * Provides an EGLSurface without assuming ownership of this surface.
- * This class does not keep a reference to the provided EGL surface; the
- * caller assumes ownership of the surface once it is returned.
- */
- private EGLSurface provideEGLSurface() {
- if (mEGL == null) {
- initEGL();
+ GL10 gl = (GL10) mEGLContext.getGL();
+ mView.getRenderer().onSurfaceCreated(gl, mEGLConfig);
+ mView.getRenderer().onSurfaceChanged(gl, mView.getWidth(), mView.getHeight());
}
-
- Object window = mView.getNativeWindow();
- EGLSurface surface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, window, null);
- if (surface == null || surface == EGL10.EGL_NO_SURFACE) {
- throw new GLControllerException("EGL window surface could not be created! " +
- getEGLError());
- }
-
- return surface;
}
private String getEGLError() {
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/source/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 681fb6fd6019..72a96f0bb00f 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -80,7 +80,7 @@ public class GeckoLayerClient implements PanZoomTarget {
mView.setLayerRenderer(mLayerRenderer);
- sendResizeEventIfNecessary();
+ sendResizeEventIfNecessary(false);
mView.requestRender();
}
@@ -124,21 +124,23 @@ public class GeckoLayerClient implements PanZoomTarget {
* to the layer client. That way, the layer client won't be tempted to call this, which might
* result in an infinite loop.
*/
- void setViewportSize(FloatSize size) {
+ void setViewportSize(FloatSize size, boolean forceResizeEvent) {
mViewportMetrics = mViewportMetrics.setViewportSize(size.width, size.height);
- sendResizeEventIfNecessary();
+ sendResizeEventIfNecessary(forceResizeEvent);
}
PanZoomController getPanZoomController() {
return mPanZoomController;
}
- /* Informs Gecko that the screen size has changed. */
- private void sendResizeEventIfNecessary() {
+ /* Informs Gecko that the screen size has changed.
+ * @param force: If true, a resize event will always be sent, otherwise
+ * it is only sent if size has changed. */
+ private void sendResizeEventIfNecessary(boolean force) {
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
IntSize newScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels);
- if (mScreenSize.equals(newScreenSize)) {
+ if (!force && mScreenSize.equals(newScreenSize)) {
return;
}
@@ -233,7 +235,7 @@ public class GeckoLayerClient implements PanZoomTarget {
}
private void geometryChanged() {
- sendResizeEventIfNecessary();
+ sendResizeEventIfNecessary(false);
if (getRedrawHint()) {
adjustViewport(null);
}
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
index db2fcc03c5b3..b20d602a21cb 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
@@ -21,6 +21,7 @@ import org.mozilla.gecko.util.FloatUtils;
import java.util.Timer;
import java.util.TimerTask;
+import java.lang.StrictMath;
/*
* Handles the kinetic scrolling and zooming physics for a layer controller.
@@ -143,16 +144,9 @@ class JavaPanZoomController
/** This function MUST be called on the UI thread */
public boolean onMotionEvent(MotionEvent event) {
- if (Build.VERSION.SDK_INT <= 11) {
- return false;
- }
-
- switch (event.getSource() & InputDevice.SOURCE_CLASS_MASK) {
- case InputDevice.SOURCE_CLASS_POINTER:
- switch (event.getAction() & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_SCROLL: return handlePointerScroll(event);
- }
- break;
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_MASK) == InputDevice.SOURCE_CLASS_POINTER
+ && (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_SCROLL) {
+ return handlePointerScroll(event);
}
return false;
}
@@ -433,7 +427,7 @@ class JavaPanZoomController
private float panDistance(MotionEvent move) {
float dx = mX.panDistance(move.getX(0));
float dy = mY.panDistance(move.getY(0));
- return (float) Math.sqrt(dx * dx + dy * dy);
+ return (float) Math.hypot(dx , dy);
}
private void track(float x, float y, long time) {
@@ -550,7 +544,7 @@ class JavaPanZoomController
private float getVelocity() {
float xvel = mX.getRealVelocity();
float yvel = mY.getRealVelocity();
- return (float) Math.sqrt(xvel * xvel + yvel * yvel);
+ return (float) StrictMath.hypot(xvel, yvel);
}
public PointF getVelocityVector() {
@@ -751,11 +745,6 @@ class JavaPanZoomController
if (constraints.getMaxZoom() > 0)
maxZoomFactor = constraints.getMaxZoom();
- if (!constraints.getAllowZoom()) {
- // If allowZoom is false, clamp to the default zoom level.
- maxZoomFactor = minZoomFactor = constraints.getDefaultZoom();
- }
-
maxZoomFactor = Math.max(maxZoomFactor, minZoomFactor);
if (zoomFactor < minZoomFactor) {
@@ -828,7 +817,7 @@ class JavaPanZoomController
if (mState == PanZoomState.ANIMATED_ZOOM)
return false;
- if (null == mTarget.getZoomConstraints() || !mTarget.getZoomConstraints().getAllowZoom())
+ if (null == mTarget.getZoomConstraints())
return false;
setState(PanZoomState.PINCHING);
@@ -934,10 +923,7 @@ class JavaPanZoomController
@Override
public boolean onDown(MotionEvent motionEvent) {
- if (mTarget.getZoomConstraints() != null)
- mWaitForDoubleTap = mTarget.getZoomConstraints().getAllowDoubleTapZoom();
- else
- mWaitForDoubleTap = false;
+ mWaitForDoubleTap = mTarget.getZoomConstraints() != null;
return false;
}
@@ -991,14 +977,14 @@ class JavaPanZoomController
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
- if (null == mTarget.getZoomConstraints() || !mTarget.getZoomConstraints().getAllowDoubleTapZoom()) {
+ if (null == mTarget.getZoomConstraints()) {
return true;
}
// Double tap zooms in or out depending on the current zoom factor
PointF pointOfTap = getMotionInDocumentCoordinates(motionEvent);
ImmutableViewportMetrics metrics = getMetrics();
float newZoom = metrics.getZoomFactor() >=
- DOUBLE_TAP_THRESHOLD ? mTarget.getZoomConstraints().getMinZoom() : DOUBLE_TAP_THRESHOLD;
+ DOUBLE_TAP_THRESHOLD ? mTarget.getZoomConstraints().getDefaultZoom() : DOUBLE_TAP_THRESHOLD;
// calculate new top_left point from the point of tap
float ratio = newZoom/metrics.getZoomFactor();
float newLeft = pointOfTap.x - 1/ratio * (pointOfTap.x - metrics.getOrigin().x / metrics.getZoomFactor());
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/source/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
index b1aea3616d6c..6ea7dd0edc10 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
@@ -48,13 +48,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
private FloatBuffer mCoordBuffer;
private RenderContext mLastPageContext;
private int mMaxTextureSize;
- private int mBackgroundColor;
private CopyOnWriteArrayList<Layer> mExtraLayers = new CopyOnWriteArrayList<Layer>();
- /* Used by robocop for testing purposes */
- private IntBuffer mPixelBuffer;
-
// Used by GLES 2.0
private int mProgram;
private int mPositionHandle;
@@ -146,6 +142,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mVertScrollLayer.destroy();
}
+ @Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
createDefaultProgram();
activateDefaultProgram();
@@ -184,9 +181,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
GLES20.glEnableVertexAttribArray(mTextureHandle);
GLES20.glUniform1i(mSampleHandle, 0);
-
- // TODO: Move these calls into a separate deactivate() call that is called after the
- // underlay and overlay are rendered.
}
// Deactivates the shader program. This must be done to avoid crashes after returning to the
@@ -220,8 +214,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
/**
* Called whenever a new frame is about to be drawn.
*/
+ @Override
public void onDrawFrame(GL10 gl) {
- Frame frame = createFrame(mView.getLayerClient().getViewportMetrics());
+ Frame frame = new Frame(mView.getLayerClient().getViewportMetrics());
synchronized (mView.getLayerClient()) {
frame.beginDrawing();
frame.drawBackground();
@@ -249,6 +244,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mCoordBuffer);
}
+ @Override
public void onSurfaceChanged(GL10 gl, final int width, final int height) {
GLES20.glViewport(0, 0, width, height);
}
@@ -264,10 +260,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
return shader;
}
- public Frame createFrame(ImmutableViewportMetrics metrics) {
- return new Frame(metrics);
- }
-
class FadeRunnable implements Runnable {
private boolean mStarted;
private long mRunAt;
@@ -305,8 +297,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
}
public class Frame {
- // The timestamp recording the start of this frame.
- private long mFrameStartTime;
// A fixed snapshot of the viewport metrics that this frame is using to render content.
private ImmutableViewportMetrics mFrameMetrics;
// A rendering context for page-positioned layers, and one for screen-positioned layers.
@@ -348,10 +338,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
return pageRect;
}
- /** This function is invoked via JNI; be careful when modifying signature. */
public void beginDrawing() {
- mFrameStartTime = SystemClock.uptimeMillis();
-
TextureReaper.get().reap();
TextureGenerator.get().fill();
@@ -386,58 +373,18 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mUpdated &= layer.update(mPageContext); // called on compositor thread
}
- /** Retrieves the bounds for the layer, rounded in such a way that it
- * can be used as a mask for something that will render underneath it.
- * This will round the bounds inwards, but stretch the mask towards any
- * near page edge, where near is considered to be 'within 2 pixels'.
- * Returns null if the given layer is null.
- */
- private Rect getMaskForLayer(Layer layer) {
- if (layer == null) {
- return null;
- }
-
- RectF bounds = RectUtils.contract(layer.getBounds(mPageContext), 1.0f, 1.0f);
- Rect mask = RectUtils.roundIn(bounds);
-
- // If the mask is within two pixels of any page edge, stretch it over
- // that edge. This is to avoid drawing thin slivers when masking
- // layers.
- if (mask.top <= 2) {
- mask.top = -1;
- }
- if (mask.left <= 2) {
- mask.left = -1;
- }
-
- // Because we're drawing relative to the page-rect, we only need to
- // take into account its width and height (and not its origin)
- int pageRight = mPageRect.width();
- int pageBottom = mPageRect.height();
-
- if (mask.right >= pageRight - 2) {
- mask.right = pageRight + 1;
- }
- if (mask.bottom >= pageBottom - 2) {
- mask.bottom = pageBottom + 1;
- }
-
- return mask;
- }
-
- /** This function is invoked via JNI; be careful when modifying signature. */
public void drawBackground() {
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
/* Update background color. */
- mBackgroundColor = Color.WHITE;
+ final int backgroundColor = Color.WHITE;
/* Clear to the page background colour. The bits set here need to
* match up with those used in gfx/layers/opengl/LayerManagerOGL.cpp.
*/
- GLES20.glClearColor(((mBackgroundColor>>16)&0xFF) / 255.0f,
- ((mBackgroundColor>>8)&0xFF) / 255.0f,
- (mBackgroundColor&0xFF) / 255.0f,
+ GLES20.glClearColor(((backgroundColor >> 16) & 0xFF) / 255.0f,
+ ((backgroundColor >> 8) & 0xFF) / 255.0f,
+ (backgroundColor & 0xFF) / 255.0f,
0.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT |
GLES20.GL_DEPTH_BUFFER_BIT);
@@ -474,7 +421,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
rootLayer.draw(mPageContext);
}
- /** This function is invoked via JNI; be careful when modifying signature. */
public void drawForeground() {
/* Draw any extra layers that were added (likely plugins) */
if (mExtraLayers.size() > 0) {
@@ -498,23 +444,10 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mHorizScrollLayer.draw(mPageContext);
}
- /** This function is invoked via JNI; be careful when modifying signature. */
public void endDrawing() {
// If a layer update requires further work, schedule another redraw
if (!mUpdated)
mView.requestRender();
-
- /* Used by robocop for testing purposes */
- IntBuffer pixelBuffer = mPixelBuffer;
- if (mUpdated && pixelBuffer != null) {
- synchronized (pixelBuffer) {
- pixelBuffer.position(0);
- GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(),
- (int)mScreenContext.viewport.height(), GLES20.GL_RGBA,
- GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
- pixelBuffer.notify();
- }
- }
}
}
}
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/source/src/java/org/mozilla/gecko/gfx/LayerView.java
index 05f2118114c8..29049f92912d 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/LayerView.java
@@ -11,14 +11,12 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
-import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
-import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
@@ -37,8 +35,6 @@ import org.mozilla.gecko.OnSlideSwipeListener;
*
* This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a
* mediator between the LayerRenderer and the LayerController.
- *
- * Note that LayerView is accessed by Robocop via reflection.
*/
public class LayerView extends FrameLayout {
private static String LOGTAG = LayerView.class.getName();
@@ -49,59 +45,22 @@ public class LayerView extends FrameLayout {
private InputConnectionHandler mInputConnectionHandler;
private LayerRenderer mRenderer;
- /* Must be a PAINT_xxx constant */
- private int mPaintState = PAINT_NONE;
- private boolean mFullScreen = false;
-
private SurfaceView mSurfaceView;
- private TextureView mTextureView;
private Listener mListener;
private OnInterceptTouchListener mTouchIntercepter;
- //TODO static because of registerCxxCompositor() function, should be fixed in the future
- private static LibreOfficeMainActivity mContext;
-
- /* Flags used to determine when to show the painted surface. The integer
- * order must correspond to the order in which these states occur. */
- public static final int PAINT_NONE = 0;
- public static final int PAINT_BEFORE_FIRST = 1;
- public static final int PAINT_AFTER_FIRST = 2;
-
- boolean shouldUseTextureView() {
- // we can only use TextureView on ICS or higher
- /*if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
- Log.i(LOGTAG, "Not using TextureView: not on ICS+");
- return false;
- }
-
- try {
- // and then we can only use it if we have a hardware accelerated window
- Method m = View.class.getMethod("isHardwareAccelerated", new Class[0]);
- return (Boolean) m.invoke(this);
- } catch (Exception e) {
- Log.i(LOGTAG, "Not using TextureView: caught exception checking for hw accel: " + e.toString());
- return false;
- }*/
- return false;
- }
+ private LibreOfficeMainActivity mContext;
public LayerView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = (LibreOfficeMainActivity) context;
- if (shouldUseTextureView()) {
- mTextureView = new TextureView(context);
- mTextureView.setSurfaceTextureListener(new SurfaceTextureListener());
+ mSurfaceView = new SurfaceView(context);
+ addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- } else {
- mSurfaceView = new SurfaceView(context);
- addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
-
- SurfaceHolder holder = mSurfaceView.getHolder();
- holder.addCallback(new SurfaceListener());
+ SurfaceHolder holder = mSurfaceView.getHolder();
+ holder.addCallback(new SurfaceListener());
holder.setFormat(PixelFormat.RGB_565);
- }
mGLController = new GLController(this);
}
@@ -183,10 +142,6 @@ public class LayerView extends FrameLayout {
public GeckoLayerClient getLayerClient() { return mLayerClient; }
public PanZoomController getPanZoomController() { return mPanZoomController; }
- public void setViewportSize(IntSize size) {
- mLayerClient.setViewportSize(new FloatSize(size));
- }
-
public ImmutableViewportMetrics getViewportMetrics() {
return mLayerClient.getViewportMetrics();
}
@@ -223,13 +178,6 @@ public class LayerView extends FrameLayout {
return mInputConnectionHandler != null && mInputConnectionHandler.onKeyUp(keyCode, event);
}
- public boolean isIMEEnabled() {
- /*if (mInputConnectionHandler != null) {
- return mInputConnectionHandler.isIMEEnabled();
- }*/
- return false;
- }
-
public void requestRender() {
if (mListener != null) {
mListener.renderRequested();
@@ -256,19 +204,6 @@ public class LayerView extends FrameLayout {
return mRenderer;
}
- /* paintState must be a PAINT_xxx constant. The state will only be changed
- * if paintState represents a state that occurs after the current state. */
- public void setPaintState(int paintState) {
- if (paintState > mPaintState) {
- Log.d(LOGTAG, "LayerView paint state set to " + paintState);
- mPaintState = paintState;
- }
- }
-
- public int getPaintState() {
- return mPaintState;
- }
-
public LayerRenderer getRenderer() {
return mRenderer;
}
@@ -306,7 +241,7 @@ public class LayerView extends FrameLayout {
private void onSizeChanged(int width, int height) {
mGLController.surfaceChanged(width, height);
- mLayerClient.setViewportSize(new FloatSize(width, height));
+ mLayerClient.setViewportSize(new FloatSize(width, height), false);
if (mListener != null) {
mListener.surfaceChanged(width, height);
@@ -324,29 +259,13 @@ public class LayerView extends FrameLayout {
}
public Object getNativeWindow() {
- if (mSurfaceView != null)
- return mSurfaceView.getHolder();
-
- return mTextureView.getSurfaceTexture();
- }
-
- /** This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying signature. */
- public static GLController registerCxxCompositor() {
- try {
- LayerView layerView = mContext.getLayerClient().getView();
- layerView.mListener.compositorCreated();
- return layerView.getGLController();
- } catch (Exception e) {
- Log.e(LOGTAG, "Error registering compositor!", e);
- return null;
- }
+ return mSurfaceView.getHolder();
}
public interface Listener {
void compositorCreated();
void renderRequested();
void compositionPauseRequested();
- void compositionResumeRequested(int width, int height);
void surfaceChanged(int width, int height);
}
@@ -371,30 +290,7 @@ public class LayerView extends FrameLayout {
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
- setViewportSize(new IntSize(right - left, bottom - top));
- }
- }
-
- private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- // We don't do this for surfaceCreated above because it is always followed by a surfaceChanged,
- // but that is not the case here.
- if (mRenderControllerThread != null) {
- mRenderControllerThread.surfaceCreated();
- }
- onSizeChanged(width, height);
- }
-
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- onDestroyed();
- return true; // allow Android to call release() on the SurfaceTexture, we are done drawing to it
- }
-
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- onSizeChanged(width, height);
- }
-
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ mLayerClient.setViewportSize(new FloatSize(right - left, bottom - top), true);
}
}
@@ -438,12 +334,4 @@ public class LayerView extends FrameLayout {
super(e);
}
}
-
- public void setFullScreen(boolean fullScreen) {
- mFullScreen = fullScreen;
- }
-
- public boolean isFullScreen() {
- return mFullScreen;
- }
}
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/PointUtils.java b/android/source/src/java/org/mozilla/gecko/gfx/PointUtils.java
index 4eb07a31f147..4eff380527d2 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/PointUtils.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/PointUtils.java
@@ -11,6 +11,8 @@ import android.graphics.PointF;
import org.json.JSONException;
import org.json.JSONObject;
+import java.lang.StrictMath;
+
public final class PointUtils {
public static PointF add(PointF one, PointF two) {
return new PointF(one.x + two.x, one.y + two.y);
@@ -30,7 +32,7 @@ public final class PointUtils {
/* Computes the magnitude of the given vector. */
public static float distance(PointF point) {
- return (float)Math.sqrt(point.x * point.x + point.y * point.y);
+ return (float)StrictMath.hypot(point.x, point.y);
}
/** Computes the scalar distance between two points. */
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/RenderControllerThread.java b/android/source/src/java/org/mozilla/gecko/gfx/RenderControllerThread.java
index 06f82f158366..5c74d56a004b 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/RenderControllerThread.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/RenderControllerThread.java
@@ -82,11 +82,6 @@ public class RenderControllerThread extends Thread implements LayerView.Listener
}
@Override
- public void compositionResumeRequested(int width, int height) {
-
- }
-
- @Override
public void surfaceChanged(int width, int height) {
this.width = width;
this.height = height;
@@ -115,7 +110,7 @@ public class RenderControllerThread extends Thread implements LayerView.Listener
}
GLSurfaceView.Renderer renderer = getRenderer();
if (renderer != null) {
- renderer.onDrawFrame((GL10) controller.getGL());
+ renderer.onDrawFrame(controller.getGL());
}
controller.swapBuffers();
}
@@ -123,7 +118,7 @@ public class RenderControllerThread extends Thread implements LayerView.Listener
private void doSizeChanged() {
GLSurfaceView.Renderer renderer = getRenderer();
if (renderer != null) {
- renderer.onSurfaceChanged((GL10) controller.getGL(), width, height);
+ renderer.onSurfaceChanged(controller.getGL(), width, height);
}
}
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java b/android/source/src/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java
index 1d901a02a14b..e89015b5ed8c 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java
@@ -34,7 +34,7 @@ import java.util.Stack;
* - It doesn't take pressure into account, which results in smoother scaling.
*/
public class SimpleScaleGestureDetector {
- private static final String LOGTAG = "GeckoSimpleScaleGestureDetector";
+ private static final String LOGTAG = "ScaleGestureDetector";
private SimpleScaleGestureListener mListener;
private long mLastEventTime;
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/SubTile.java b/android/source/src/java/org/mozilla/gecko/gfx/SubTile.java
index 42750df62838..bdad37195d90 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/SubTile.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/SubTile.java
@@ -86,26 +86,24 @@ public class SubTile extends Layer {
protected void finalize() throws Throwable {
try {
destroyImage();
- cleanTexture(false);
+ cleanTexture();
} finally {
super.finalize();
}
}
- private void cleanTexture(boolean immediately) {
+ private void cleanTexture() {
if (mTextureIDs != null) {
TextureReaper.get().add(mTextureIDs);
mTextureIDs = null;
- if (immediately) {
- TextureReaper.get().reap();
- }
+ TextureReaper.get().reap();
}
}
public void destroy() {
try {
destroyImage();
- cleanTexture(false);
+ cleanTexture();
} catch (Exception ex) {
Log.e(LOGTAG, "Error clearing buffers: ", ex);
}
@@ -140,7 +138,7 @@ public class SubTile extends Layer {
if (!textureSize.equals(mSize)) {
mSize = textureSize;
- cleanTexture(true);
+ cleanTexture();
}
}
@@ -253,4 +251,4 @@ public class SubTile extends Layer {
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
-} \ No newline at end of file
+}