Merge commit '70da83381f77e0ee9ada47eafaae395038ff77ad' into tgunn-mncvtdev-to-master-2015-12-04
diff --git a/Android.mk b/Android.mk
index 67d8ab6..1a4e3eb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -5,7 +5,29 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 guava
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+# The design lib requires that the client package use appcompat themes.
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-appcompat
+# Supplies material design components, e.g. Snackbar.
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-design
+LOCAL_STATIC_JAVA_LIBRARIES += android-support-v7-recyclerview
+LOCAL_STATIC_JAVA_LIBRARIES += guava
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+# Not quite sure why it is necessary to explicitly pull in resources from the
+# appcompat lib, but the demo code indicates it's necessary (see
+# development/samples/Support7Demos/Android.mk)
+LOCAL_RESOURCE_DIR += \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/design/res \
+ frameworks/support/v7/recyclerview/res
+
+# Again, required to pull in appcompat resources. See abovementioned demo code.
+LOCAL_AAPT_FLAGS := \
+ --auto-add-overlay \
+ --extra-packages android.support.v7.appcompat \
+ --extra-packages android.support.design \
+ --extra-packages android.support.v7.recyclerview
LOCAL_PACKAGE_NAME := DocumentsUI
LOCAL_CERTIFICATE := platform
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 382b2d0..8cc79a4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -3,6 +3,7 @@
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.REMOVE_TASKS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".DocumentsApplication"
@@ -35,13 +36,43 @@
<action android:name="android.intent.action.OPEN_DOCUMENT_TREE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
+ </activity>
+
+ <activity
+ android:name=".DownloadsActivity"
+ android:theme="@style/DocumentsFullScreenTheme"
+ android:label="@string/downloads_label"
+ android:icon="@drawable/ic_doc_text">
<intent-filter>
<action android:name="android.provider.action.MANAGE_ROOT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.document/root" />
</intent-filter>
+ </activity>
+
+ <activity
+ android:name=".LauncherActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:icon="@drawable/ic_files_app"
+ android:label="@string/files_label"
+ android:enabled="@bool/productivity_device">
<intent-filter>
- <action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" />
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".FilesActivity"
+ android:theme="@style/DocumentsFullScreenTheme"
+ android:icon="@drawable/ic_files_app"
+ android:label="@string/files_label"
+ android:documentLaunchMode="intoExisting">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.provider.action.BROWSE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.document/root" />
</intent-filter>
diff --git a/res/color/item_doc_grid_overlay.xml b/res/color/item_doc_grid_border.xml
similarity index 77%
rename from res/color/item_doc_grid_overlay.xml
rename to res/color/item_doc_grid_border.xml
index 6959c65..e144af8 100644
--- a/res/color/item_doc_grid_overlay.xml
+++ b/res/color/item_doc_grid_border.xml
@@ -16,12 +16,8 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:state_activated="true"
- android:color="?android:attr/colorControlHighlight" />
- <item
- android:state_enabled="false"
- android:color="?android:attr/colorBackground"
- android:alpha="0.5" />
+ android:state_focused="true"
+ android:color="?android:attr/colorAccent"/>
<item
android:color="@android:color/transparent" />
-</selector>
\ No newline at end of file
+</selector>
diff --git a/res/drawable-hdpi/ic_grid_selection_check.png b/res/drawable-hdpi/ic_grid_selection_check.png
deleted file mode 100644
index f3007c2..0000000
--- a/res/drawable-hdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_grid_selection_check.png b/res/drawable-mdpi/ic_grid_selection_check.png
deleted file mode 100644
index 16f2ab9..0000000
--- a/res/drawable-mdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_grid_selection_check.png b/res/drawable-xhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 0885320..0000000
--- a/res/drawable-xhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_grid_selection_check.png b/res/drawable-xxhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 083bbcc..0000000
--- a/res/drawable-xxhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_grid_selection_check.png b/res/drawable-xxxhdpi/ic_grid_selection_check.png
deleted file mode 100644
index 74b1ca5..0000000
--- a/res/drawable-xxxhdpi/ic_grid_selection_check.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/band_select_overlay.xml b/res/drawable/band_select_overlay.xml
new file mode 100644
index 0000000..ba4d526
--- /dev/null
+++ b/res/drawable/band_select_overlay.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ 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
+ ~
+ ~ http://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
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/band_select_background" />
+ <stroke android:width="1dp" android:color="@color/band_select_border" />
+</shape>
diff --git a/res/drawable/ic_files_app.xml b/res/drawable/ic_files_app.xml
new file mode 100644
index 0000000..ff7189e
--- /dev/null
+++ b/res/drawable/ic_files_app.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/icon256"
+ android:tint="?android:attr/colorControlNormal"
+ android:autoMirrored="true" />
diff --git a/res/drawable/ic_root_home.xml b/res/drawable/ic_root_home.xml
new file mode 100644
index 0000000..0a258ac
--- /dev/null
+++ b/res/drawable/ic_root_home.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20 6h-8l-2-2H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V8c0-1.1-.9-2-2-2zm-5 3c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm4
+8h-8v-1c0-1.33 2.67-2 4-2s4 .67 4 2v1z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
diff --git a/res/drawable/icon256.png b/res/drawable/icon256.png
new file mode 100644
index 0000000..631c951
--- /dev/null
+++ b/res/drawable/icon256.png
Binary files differ
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/drawable/item_doc_grid_border.xml
similarity index 78%
rename from res/drawable/item_doc_grid_overlay.xml
rename to res/drawable/item_doc_grid_border.xml
index 3f50fb9..db66094 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/drawable/item_doc_grid_border.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,5 +16,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
+ <stroke
+ android:width="2dp"
+ android:color="@color/item_doc_grid_border"/>
</shape>
diff --git a/res/drawable/item_doc_grid_overlay_icon.xml b/res/drawable/item_doc_grid_overlay_icon.xml
deleted file mode 100644
index d40de1e..0000000
--- a/res/drawable/item_doc_grid_overlay_icon.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="true">
- <item android:state_focused="true" android:state_activated="true" android:drawable="@drawable/ic_grid_selection_check" />
- <item android:state_focused="false" android:state_activated="true" android:drawable="@drawable/ic_grid_selection_check" />
- <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/res/drawable/item_root_background.xml b/res/drawable/item_root_background.xml
deleted file mode 100644
index 93c965f..0000000
--- a/res/drawable/item_root_background.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_focused="true" android:state_activated="true">
- <color android:color="@color/material_grey_300" />
- </item>
- <item android:state_focused="false" android:state_activated="true">
- <color android:color="@color/material_grey_300" />
- </item>
- <item android:drawable="@android:color/transparent" />
-</selector>
diff --git a/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml b/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
new file mode 100644
index 0000000..070b9a1
--- /dev/null
+++ b/res/drawable/progress_indeterminate_horizontal_material_trimmed.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<!-- Variant of progress_indeterminate_horizontal_material in frameworks/base/core/res, which
+ draws the whole height of the progress bar instead having blank space above and below the
+ bar. -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/vector_drawable_progress_indeterminate_horizontal_trimmed" >
+ <target
+ android:name="rect2_grp"
+ android:animation="@*android:anim/progress_indeterminate_horizontal_rect2" />
+ <target
+ android:name="rect1_grp"
+ android:animation="@*android:anim/progress_indeterminate_horizontal_rect1" />
+</animated-vector>
diff --git a/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml b/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
new file mode 100644
index 0000000..39e3a37
--- /dev/null
+++ b/res/drawable/vector_drawable_progress_indeterminate_horizontal_trimmed.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<!-- Variant of vector_drawable_progress_indeterminate_horizontal in frameworks/base/core/res, which
+ draws the whole height of the progress bar instead having blank space above and below the
+ bar. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="10dp"
+ android:width="360dp"
+ android:viewportHeight="10"
+ android:viewportWidth="360" >
+ <group
+ android:name="progress_group"
+ android:translateX="180"
+ android:translateY="5" >
+ <path
+ android:name="background_track"
+ android:pathData="M -180.0,-5.0 l 360.0,0 l 0,10.0 l -360.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated"
+ android:fillAlpha="?android:attr/disabledAlpha"/>
+ <group
+ android:name="rect2_grp"
+ android:translateX="-197.60001"
+ android:scaleX="0.1" >
+ <path
+ android:name="rect2"
+ android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated" />
+ </group>
+ <group
+ android:name="rect1_grp"
+ android:translateX="-522.59998"
+ android:scaleX="0.1" >
+ <path
+ android:name="rect1"
+ android:pathData="M -144.0,-5.0 l 288.0,0 l 0,10.0 l -288.0,0 Z"
+ android:fillColor="?android:attr/colorControlActivated" />
+ </group>
+ </group>
+</vector>
diff --git a/res/layout-sw720dp-land/item_doc_list.xml b/res/layout-sw720dp-land/item_doc_list.xml
index d124320..fe06eaf 100644
--- a/res/layout-sw720dp-land/item_doc_list.xml
+++ b/res/layout-sw720dp-land/item_doc_list.xml
@@ -14,10 +14,17 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.ListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/item_doc_list_background">
+ android:background="@color/item_doc_background"
+ android:orientation="horizontal"
+ android:focusable="true">
+
+ <View
+ android:id="@+id/focus_indicator"
+ android:layout_width="4dp"
+ android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
@@ -121,4 +128,4 @@
</LinearLayout>
-</FrameLayout>
+</com.android.documentsui.ListItem>
diff --git a/res/layout-sw720dp/activity.xml b/res/layout-sw720dp/activity.xml
deleted file mode 100644
index 2a273f4..0000000
--- a/res/layout-sw720dp/activity.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <com.android.documentsui.DocumentsToolBar
- android:id="@+id/toolbar"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/actionBarSize"
- android:background="?android:attr/colorPrimary"
- android:elevation="8dp"
- android:theme="?android:attr/actionBarTheme">
-
- <Spinner
- android:id="@+id/stack"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:overlapAnchor="true" />
-
- </com.android.documentsui.DocumentsToolBar>
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="horizontal"
- android:baselineAligned="false"
- android:divider="?android:attr/dividerVertical"
- android:showDividers="middle">
-
- <FrameLayout
- android:id="@+id/container_roots"
- android:layout_width="256dp"
- android:layout_height="match_parent" />
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="vertical"
- android:elevation="8dp">
-
- <com.android.documentsui.DirectoryContainerView
- android:id="@+id/container_directory"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <FrameLayout
- android:id="@+id/container_save"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="8dp" />
-
- </LinearLayout>
-
- </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout/activity.xml b/res/layout/activity.xml
deleted file mode 100644
index 43fdaf2..0000000
--- a/res/layout/activity.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <com.android.documentsui.DocumentsToolBar
- android:id="@+id/toolbar"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/actionBarSize"
- android:background="?android:attr/colorPrimary"
- android:elevation="8dp"
- android:theme="?android:attr/actionBarTheme">
-
- <Spinner
- android:id="@+id/stack"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="4dp"
- android:overlapAnchor="true" />
-
- </com.android.documentsui.DocumentsToolBar>
-
- <com.android.documentsui.DirectoryContainerView
- android:id="@+id/container_directory"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- <FrameLayout
- android:id="@+id/container_save"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="8dp" />
-
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/drawer_roots"
- android:layout_width="256dp"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:orientation="vertical"
- android:elevation="16dp"
- android:background="@*android:color/white">
-
- <Toolbar
- android:id="@+id/roots_toolbar"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/actionBarSize"
- android:background="?android:attr/colorPrimary"
- android:elevation="8dp"
- android:theme="?android:attr/actionBarTheme" />
-
- <FrameLayout
- android:id="@+id/container_roots"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-
- </LinearLayout>
-
-</android.support.v4.widget.DrawerLayout>
diff --git a/res/layout/directory_cluster.xml b/res/layout/directory_cluster.xml
new file mode 100644
index 0000000..8245e53
--- /dev/null
+++ b/res/layout/directory_cluster.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/container_message_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:elevation="8dp"
+ android:background="@color/material_grey_50"/>
+
+ <com.android.documentsui.DirectoryContainerView
+ android:id="@+id/container_directory"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <FrameLayout
+ android:id="@+id/container_save"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/material_grey_50"
+ android:elevation="8dp" />
+
+</LinearLayout>
diff --git a/res/layout/drawer_layout.xml b/res/layout/drawer_layout.xml
new file mode 100644
index 0000000..0146f14
--- /dev/null
+++ b/res/layout/drawer_layout.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
+ floating action buttons) to operate correctly. -->
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/coordinator_layout">
+
+ <android.support.v4.widget.DrawerLayout
+ android:id="@+id/drawer_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.android.documentsui.DocumentsToolBar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:background="?android:attr/colorPrimary"
+ android:elevation="8dp"
+ android:theme="?actionBarTheme"
+ android:popupTheme="?actionBarPopupTheme">
+
+ <Spinner
+ android:id="@+id/stack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:overlapAnchor="true" />
+
+ </com.android.documentsui.DocumentsToolBar>
+
+ <include layout="@layout/directory_cluster"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/drawer_roots"
+ android:layout_width="256dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="start"
+ android:orientation="vertical"
+ android:elevation="16dp"
+ android:background="@color/window_background">
+
+ <Toolbar
+ android:id="@+id/roots_toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:background="?android:attr/colorPrimary"
+ android:elevation="8dp"
+ android:theme="?actionBarTheme"
+ android:popupTheme="?actionBarPopupTheme" />
+
+ <FrameLayout
+ android:id="@+id/container_roots"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ </android.support.v4.widget.DrawerLayout>
+</android.support.design.widget.CoordinatorLayout>
diff --git a/res/layout/fixed_layout.xml b/res/layout/fixed_layout.xml
new file mode 100644
index 0000000..3135977
--- /dev/null
+++ b/res/layout/fixed_layout.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
+ floating action buttons) to operate correctly. -->
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/coordinator_layout">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.android.documentsui.DocumentsToolBar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:background="?android:attr/colorPrimary"
+ android:elevation="8dp"
+ android:theme="?actionBarTheme"
+ android:popupTheme="?actionBarPopupTheme">
+
+ <Spinner
+ android:id="@+id/stack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:overlapAnchor="true" />
+
+ </com.android.documentsui.DocumentsToolBar>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:baselineAligned="false">
+
+ <FrameLayout
+ android:id="@+id/container_roots"
+ android:layout_width="256dp"
+ android:layout_height="match_parent" />
+
+ <include layout="@layout/directory_cluster"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:elevation="8dp" />
+
+ </LinearLayout>
+
+ </LinearLayout>
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/res/layout/fragment_directory.xml b/res/layout/fragment_directory.xml
index 2c08e72..f9bbccb 100644
--- a/res/layout/fragment_directory.xml
+++ b/res/layout/fragment_directory.xml
@@ -16,35 +16,69 @@
<com.android.documentsui.DirectoryView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:animateLayoutChanges="true">
- <TextView
+ <ProgressBar
+ android:id="@+id/progressbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ style="@style/TrimmedHorizontalProgressBar"
+ android:visibility="gone"/>
+
+ <FrameLayout
+ android:id="@+id/container_message_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:elevation="8dp"
+ android:background="@color/material_grey_50"
+ android:visibility="gone"/>
+
+ <!-- The empty directory view -->
+ <LinearLayout
android:id="@android:id/empty"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:gravity="center"
- android:text="@string/empty"
- android:visibility="gone"
- style="@android:style/TextAppearance.Material.Subhead" />
-
- <ListView
- android:id="@+id/list"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- <GridView
- android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingStart="@dimen/grid_padding_horiz"
- android:paddingEnd="@dimen/grid_padding_horiz"
- android:paddingTop="@dimen/grid_padding_vert"
- android:paddingBottom="@dimen/grid_padding_vert"
- android:horizontalSpacing="@dimen/grid_item_padding"
- android:verticalSpacing="@dimen/grid_item_padding"
- android:clipToPadding="false"
- android:scrollbarStyle="outsideOverlay"
- android:drawSelectorOnTop="true"
- android:visibility="gone" />
+ android:orientation="vertical"
+ android:visibility="gone">
+
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/empty"
+ style="@android:style/TextAppearance.Material.Subhead" />
+
+ <Button
+ android:id="@+id/button_retry"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_retry"
+ style="?android:attr/buttonBarPositiveButtonStyle" />
+
+ </LinearLayout>
+
+ <!-- This FrameLayout works around b/24189541 -->
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/list"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="0dp"
+ android:paddingEnd="0dp"
+ android:paddingTop="0dp"
+ android:paddingBottom="0dp"
+ android:clipToPadding="false"
+ android:scrollbarStyle="outsideOverlay"
+ android:drawSelectorOnTop="true" />
+
+ </FrameLayout>
</com.android.documentsui.DirectoryView>
diff --git a/res/layout/fragment_message_bar.xml b/res/layout/fragment_message_bar.xml
new file mode 100644
index 0000000..47e4e77
--- /dev/null
+++ b/res/layout/fragment_message_bar.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:animateLayoutChanges="true"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:orientation="vertical"
+ android:paddingLeft="@dimen/list_item_padding"
+ android:paddingRight="@dimen/list_item_padding"
+ android:paddingTop="@dimen/list_item_padding">
+
+ <LinearLayout
+ android:id="@+id/container_info"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone">
+
+ <FrameLayout
+ android:layout_height="@dimen/icon_size"
+ android:layout_width="@dimen/icon_size">
+
+ <ImageView
+ android:contentDescription="@null"
+ android:id="@+id/icon_info"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:scaleType="centerInside"/>
+
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/textview_info"
+ android:layout_gravity="center_vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:selectAllOnFocus="true"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/container_error"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone">
+
+ <FrameLayout
+ android:layout_height="@dimen/icon_size"
+ android:layout_width="@dimen/icon_size">
+
+ <ImageView
+ android:contentDescription="@null"
+ android:id="@+id/icon_error"
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:scaleType="centerInside"/>
+
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/textview_error"
+ android:layout_gravity="center_vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:selectAllOnFocus="true"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_gravity="right"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/button_dismiss"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/button_dismiss"
+ style="?android:attr/buttonBarPositiveButtonStyle"/>
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/fragment_roots.xml b/res/layout/fragment_roots.xml
index 2d624d8..f3de3b4 100644
--- a/res/layout/fragment_roots.xml
+++ b/res/layout/fragment_roots.xml
@@ -19,4 +19,5 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
+ android:drawSelectorOnTop="true"
android:divider="@null" />
diff --git a/res/layout/item_doc_grid.xml b/res/layout/item_doc_grid.xml
index d62d050..dcd5cfd 100644
--- a/res/layout/item_doc_grid.xml
+++ b/res/layout/item_doc_grid.xml
@@ -14,129 +14,110 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/grid_item_height"
- android:background="@color/item_doc_grid_background">
+ android:layout_height="wrap_content"
+ android:layout_margin="@dimen/grid_item_margin"
+ android:background="@color/item_doc_background"
+ android:focusable="true">
- <ImageView
- android:id="@+id/icon_thumb"
+ <!-- Main item thumbnail. Comprised of two overlapping images, the
+ visibility of which is controlled by code in
+ DirectoryFragment.java. -->
+
+ <FrameLayout
+ android:id="@+id/thumbnail"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop"
- android:contentDescription="@null" />
+ android:layout_height="wrap_content">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ <com.android.documentsui.GridItemThumbnail
+ android:id="@+id/icon_thumb"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="centerCrop"
+ android:contentDescription="@null" />
- <ImageView
+ <com.android.documentsui.GridItemThumbnail
android:id="@+id/icon_mime"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
+ android:layout_height="wrap_content"
android:scaleType="centerInside"
android:contentDescription="@null" />
- <LinearLayout
- android:layout_width="match_parent"
+ </FrameLayout>
+
+ <!-- Item nameplate. Has a mime-type icon and some text fields (title,
+ size, mod-time, etc). -->
+
+ <RelativeLayout
+ android:id="@+id/nameplate"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/thumbnail"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp">
+
+ <ImageView
+ android:id="@android:id/icon1"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="8dp"
+ android:layout_alignParentStart="true"
+ android:layout_centerVertical="true"
+ android:scaleType="centerInside"
+ android:contentDescription="@null"/>
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@color/item_doc_grid_protect_background"
- android:orientation="vertical"
- android:paddingStart="16dp"
- android:paddingEnd="12dp"
- android:paddingTop="8dp"
- android:paddingBottom="8dp">
+ android:layout_alignParentTop="true"
+ android:layout_toEndOf="@android:id/icon1"
+ android:singleLine="true"
+ android:ellipsize="middle"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Subhead"
+ android:textColor="@*android:color/primary_text_default_material_light" />
- <LinearLayout
- android:id="@+id/line1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:baselineAligned="false">
+ <TextView
+ android:id="@+id/size"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toEndOf="@android:id/icon1"
+ android:layout_below="@android:id/title"
+ android:layout_marginEnd="4dp"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Caption"
+ android:textColor="@*android:color/primary_text_default_material_light" />
- <TextView
- android:id="@android:id/title"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:singleLine="true"
- android:ellipsize="middle"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Subhead"
- android:textColor="@*android:color/primary_text_default_material_dark" />
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_toEndOf="@id/size"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textAlignment="viewStart"
+ android:textAppearance="@android:style/TextAppearance.Material.Caption"
+ android:textColor="@*android:color/primary_text_default_material_light" />
- <ImageView
- android:id="@android:id/icon1"
- android:layout_width="@dimen/root_icon_size"
- android:layout_height="@dimen/root_icon_size"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:contentDescription="@null" />
+ </RelativeLayout>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/line2"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:baselineAligned="false">
-
- <TextView
- android:id="@+id/date"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="0.5"
- android:singleLine="true"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Caption"
- android:textColor="@*android:color/primary_text_default_material_dark" />
-
- <TextView
- android:id="@+id/size"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="0.5"
- android:layout_marginStart="8dp"
- android:singleLine="true"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Caption"
- android:textColor="@*android:color/primary_text_default_material_dark" />
-
- <ImageView
- android:id="@android:id/icon2"
- android:layout_width="@dimen/root_icon_size"
- android:layout_height="@dimen/root_icon_size"
- android:layout_marginStart="8dp"
- android:scaleType="centerInside"
- android:contentDescription="@null"
- android:visibility="gone" />
-
- </LinearLayout>
-
- </LinearLayout>
-
- </LinearLayout>
-
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/item_doc_grid_overlay"
+ <!-- An overlay that draws the item border when it is focused. -->
+ <View
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBottom="@id/nameplate"
+ android:layout_alignTop="@id/thumbnail"
+ android:layout_alignLeft="@id/thumbnail"
+ android:layout_alignRight="@id/thumbnail"
android:contentDescription="@null"
+ android:background="@drawable/item_doc_grid_border"
android:duplicateParentState="true" />
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@drawable/item_doc_grid_overlay_icon"
- android:scaleType="center"
- android:contentDescription="@null"
- android:duplicateParentState="true" />
-
-</FrameLayout>
+</RelativeLayout>
diff --git a/res/layout/item_doc_list.xml b/res/layout/item_doc_list.xml
index c576669..e068423 100644
--- a/res/layout/item_doc_list.xml
+++ b/res/layout/item_doc_list.xml
@@ -14,10 +14,17 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.ListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/item_doc_list_background">
+ android:background="@color/item_doc_background"
+ android:orientation="horizontal"
+ android:focusable="true">
+
+ <View
+ android:id="@+id/focus_indicator"
+ android:layout_width="4dp"
+ android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
@@ -131,4 +138,4 @@
</LinearLayout>
-</FrameLayout>
+</com.android.documentsui.ListItem>
diff --git a/res/layout/item_loading_grid.xml b/res/layout/item_loading_grid.xml
deleted file mode 100644
index 005a111..0000000
--- a/res/layout/item_loading_grid.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/grid_height"
- android:orientation="horizontal">
-
- <ProgressBar
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- style="?android:attr/progressBarStyle" />
-
-</FrameLayout>
diff --git a/res/layout/item_loading_list.xml b/res/layout/item_loading_list.xml
deleted file mode 100644
index 6f214ed..0000000
--- a/res/layout/item_loading_list.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/list_item_height">
-
- <ProgressBar
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- style="?android:attr/progressBarStyle" />
-
-</FrameLayout>
diff --git a/res/layout/item_message_grid.xml b/res/layout/item_message_grid.xml
deleted file mode 100644
index 385563d..0000000
--- a/res/layout/item_message_grid.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="@dimen/grid_height"
- android:paddingStart="?android:attr/listPreferredItemPaddingStart"
- android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
- android:paddingTop="8dp"
- android:paddingBottom="8dp">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:gravity="center">
-
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:contentDescription="@null" />
-
- <TextView
- android:id="@android:id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:maxLines="4"
- android:ellipsize="end"
- android:paddingTop="8dp"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorPrimary" />
-
- </LinearLayout>
-
-</FrameLayout>
diff --git a/res/layout/item_message_list.xml b/res/layout/item_message_list.xml
deleted file mode 100644
index 44c8baf..0000000
--- a/res/layout/item_message_list.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
- 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
-
- http://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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/list_item_height"
- android:paddingStart="@dimen/list_item_padding"
- android:paddingEnd="@dimen/list_item_padding"
- android:paddingTop="8dp"
- android:paddingBottom="8dp"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:baselineAligned="false">
-
- <FrameLayout
- android:layout_width="@dimen/icon_size"
- android:layout_height="@dimen/icon_size"
- android:layout_marginEnd="16dp">
-
- <ImageView
- android:id="@android:id/icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:scaleType="centerInside"
- android:contentDescription="@null" />
-
- </FrameLayout>
-
- <TextView
- android:id="@android:id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:maxLines="2"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:textAppearance="@android:style/TextAppearance.Material.Body1"
- android:textColor="?android:attr/textColorPrimary" />
-
-</LinearLayout>
diff --git a/res/layout/item_root.xml b/res/layout/item_root.xml
index bd83923..ff80d07 100644
--- a/res/layout/item_root.xml
+++ b/res/layout/item_root.xml
@@ -22,13 +22,13 @@
android:paddingEnd="@dimen/list_item_padding"
android:gravity="center_vertical"
android:orientation="horizontal"
- android:baselineAligned="false"
- android:background="@drawable/item_root_background">
+ android:baselineAligned="false">
<FrameLayout
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
- android:layout_marginEnd="16dp"
+ android:layout_marginStart="@dimen/root_icon_margin"
+ android:layout_marginEnd="@dimen/root_icon_margin"
android:duplicateParentState="true">
<ImageView
diff --git a/res/layout/single_pane_layout.xml b/res/layout/single_pane_layout.xml
new file mode 100644
index 0000000..c5a5745
--- /dev/null
+++ b/res/layout/single_pane_layout.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ 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
+
+ http://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.
+-->
+
+<!-- CoordinatorLayout is necessary for various components (e.g. Snackbars, and
+ floating action buttons) to operate correctly. -->
+<android.support.design.widget.CoordinatorLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/coordinator_layout">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.android.documentsui.DocumentsToolBar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:background="?android:attr/colorPrimary"
+ android:elevation="8dp"
+ android:theme="?actionBarTheme"
+ android:popupTheme="?actionBarPopupTheme">
+
+ <Spinner
+ android:id="@+id/stack"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="4dp"
+ android:overlapAnchor="true" />
+
+ </com.android.documentsui.DocumentsToolBar>
+
+ <include layout="@layout/directory_cluster"/>
+
+ </LinearLayout>
+
+</android.support.design.widget.CoordinatorLayout>
diff --git a/res/menu/activity.xml b/res/menu/activity.xml
index 5b944ab..7e0649b 100644
--- a/res/menu/activity.xml
+++ b/res/menu/activity.xml
@@ -16,11 +16,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
- android:id="@+id/menu_create_dir"
- android:title="@string/menu_create_dir"
- android:icon="@drawable/ic_menu_new_folder"
- android:showAsAction="always" />
- <item
android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/ic_menu_search"
@@ -55,11 +50,33 @@
android:icon="@drawable/ic_menu_view_list"
android:showAsAction="never" />
<item
- android:id="@+id/menu_advanced"
- android:showAsAction="never" />
+ android:id="@+id/menu_new_window"
+ android:title="@string/menu_new_window"
+ android:alphabeticShortcut="n"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_create_dir"
+ android:title="@string/menu_create_dir"
+ android:icon="@drawable/ic_menu_new_folder"
+ android:alphabeticShortcut="e"
+ android:showAsAction="always"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_paste_from_clipboard"
+ android:title="@string/menu_paste_from_clipboard"
+ android:alphabeticShortcut="v"
+ android:showAsAction="never"
+ android:visible="false" />
+ <!-- Copy action is defined in mode_directory.xml -->
<item
android:id="@+id/menu_file_size"
- android:showAsAction="never" />
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_advanced"
+ android:showAsAction="never"
+ android:visible="false" />
<item
android:id="@+id/menu_settings"
android:title="@string/menu_settings"
diff --git a/res/menu/mode_directory.xml b/res/menu/mode_directory.xml
index 4b89823..4ff396f 100644
--- a/res/menu/mode_directory.xml
+++ b/res/menu/mode_directory.xml
@@ -30,11 +30,22 @@
android:title="@string/menu_delete"
android:showAsAction="always" />
<item
+ android:id="@+id/menu_copy_to_clipboard"
+ android:title="@string/menu_copy_to_clipboard"
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
android:id="@+id/menu_select_all"
android:title="@string/menu_select_all"
android:showAsAction="never" />
<item
- android:id="@+id/menu_copy"
+ android:id="@+id/menu_copy_to"
android:title="@string/menu_copy"
- android:showAsAction="never" />
+ android:showAsAction="never"
+ android:visible="false" />
+ <item
+ android:id="@+id/menu_move_to"
+ android:title="@string/menu_move"
+ android:showAsAction="never"
+ android:visible="false" />
</menu>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-af/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-af/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-af/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 3f7571a..3daecc7 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
- <string name="title_open" msgid="4353228937663917801">"Maak oop vanaf"</string>
+ <string name="files_label" msgid="6051402950202690279">"Lêers"</string>
+ <string name="title_open" msgid="4353228937663917801">"Maak oop vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Stoor na"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Skep vouer"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nuwe vouer"</string>
<string name="menu_grid" msgid="6878021334497835259">"Roosteraansig"</string>
<string name="menu_list" msgid="7279285939892417279">"Lysaansig"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sorteer volgens"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Stoor"</string>
<string name="menu_share" msgid="3075149983979628146">"Deel"</string>
<string name="menu_delete" msgid="8138799623850614177">"Vee uit"</string>
- <string name="menu_select" msgid="8711270657353563424">"Kies \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Kies almal"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Kies alles"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopieer na …"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Skuif na …"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nuwe venster"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopieer"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Plak"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Wys interne berging"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Wys SD-kaart"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Versteek interne berging"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Versteek SD-kaart"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Wys lêergrootte"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Versteek lêergrootte"</string>
+ <string name="button_select" msgid="527196987259139214">"Kies"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopieer"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> gekies"</string>
+ <string name="button_move" msgid="2202666023104202232">"Skuif"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Maak toe"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Probeer weer"</string>
<string name="sort_name" msgid="9183560467917256779">"Volgens naam"</string>
<string name="sort_date" msgid="586080032956151448">"Volgens datum gewysig"</string>
<string name="sort_size" msgid="3350681319735474741">"Volgens grootte"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Kan sommige dokumente nie uitvee nie"</string>
<string name="share_via" msgid="8966594246261344259">"Deel via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopieer tans lêers"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Skuif tans lêers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> oor"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopieer tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers.</item>
<item quantity="one">Kopieer tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Skuif tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers.</item>
+ <item quantity="one">Skuif tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Vee tans <xliff:g id="COUNT_1">%1$d</xliff:g> lêers uit.</item>
+ <item quantity="one">Vee tans <xliff:g id="COUNT_0">%1$d</xliff:g> lêer uit.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Ontdoen"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Maak tans gereed vir kopieer …"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Berei tans voor vir skuif …"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie kopieer nie</item>
<item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie kopieer nie</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Kon <xliff:g id="COUNT_1">%1$d</xliff:g> lêers nie skuif nie</item>
+ <item quantity="one">Kon <xliff:g id="COUNT_0">%1$d</xliff:g> lêer nie skuif nie</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Raak om besonderhede te bekyk"</string>
<string name="retry" msgid="7564024179122207376">"Herprobeer"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Hierdie lêers is nie gekopieer nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Hierdie lêers is nie geskuif nie: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Het <xliff:g id="COUNT_1">%1$d</xliff:g> lêers na die knipbord gekopieer.</item>
+ <item quantity="one">Het <xliff:g id="COUNT_0">%1$d</xliff:g> lêer na die knipbord gekopieer.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan nie die geselekteerde lêers in hierdie ligging plak nie."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-am/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-am/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-am/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index f4da9eb..43db786 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ሰነዶች"</string>
+ <string name="files_label" msgid="6051402950202690279">"ፋይሎች"</string>
<string name="title_open" msgid="4353228937663917801">"ክፈት ከ"</string>
<string name="title_save" msgid="2433679664882857999">"አስቀምጥ ወደ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"አቃፊ ፍጠር"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"አዲስ አቃፊ"</string>
<string name="menu_grid" msgid="6878021334497835259">"የፍርግርግ እይታ"</string>
<string name="menu_list" msgid="7279285939892417279">"የዝርዝር እይታ"</string>
<string name="menu_sort" msgid="7677740407158414452">"ደርድር በ"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"አስቀምጥ"</string>
<string name="menu_share" msgid="3075149983979628146">"አጋራ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ሰርዝ"</string>
- <string name="menu_select" msgid="8711270657353563424">"«<xliff:g id="DIRECTORY">^1</xliff:g>»ን ይምረጡ"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ሁሉንም ምረጥ"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ሁሉንም ምረጥ"</string>
<string name="menu_copy" msgid="3612326052677229148">"ቅዳ ወደ…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ይውሰዱ ወደ..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"አዲሰ መስኮት"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ቅዳ"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ለጥፍ"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ውስጣዊ ማከማቻ አሳይ"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ካርድ አሳይ"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ውስጣዊ ማከማቻ ደብቅ"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD ካርድ ደብቅ"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"የፋይል መጠን አሳይ"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"የፋይል መጠን ደብቅ"</string>
+ <string name="button_select" msgid="527196987259139214">"ምረጥ"</string>
<string name="button_copy" msgid="8706475544635021302">"ቅዳ"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ተመርጠዋል"</string>
+ <string name="button_move" msgid="2202666023104202232">"አንቀሳቀስ"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"አሰናብት"</string>
+ <string name="button_retry" msgid="4392027584153752797">"እንደገና ይሞክሩ"</string>
<string name="sort_name" msgid="9183560467917256779">"በስም"</string>
<string name="sort_date" msgid="586080032956151448">"በተለወጠበት ቀን"</string>
<string name="sort_size" msgid="3350681319735474741">"በመጠን"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"አንዳንድ ሰነዶችን መሰረዝ አልተቻለም"</string>
<string name="share_via" msgid="8966594246261344259">"በሚከተለው በኩል ያጋሩ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ፋይሎች በመገልበጥ ላይ"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ፋይሎችን በመውሰድ ላይ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ቀርቷል"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች በመቅዳት ላይ።</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች በመቅዳት ላይ።</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመውሰድ ላይ።</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመውሰድ ላይ።</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመሰረዝ ላይ።</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን በመሰረዝ ላይ።</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"ቀልብስ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"ቅጂ በማዘጋጀት ላይ…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ለመውሰድ በማዘጋጀት ላይ…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መቅዳት አልተቻለም</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መውሰድ አልተቻለም</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎችን መውሰድ አልተቻለም</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"ዝርዝሮችን ለመመልከት ይንኩ።"</string>
<string name="retry" msgid="7564024179122207376">"እንደገና ይሞክሩ"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"እነዚህ ፋይሎች አልተቀዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"እነዚህ ፋይሎች አልተወሰዱም፦ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ወደ ቅንጥብ ሰሌዳ ቀድቷል።</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ወደ ቅንጥብ ሰሌዳ ቀድተዋል።</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"የተመረጡትን ፋይሎች ወደዚህ አካባቢ መለጠፍ አይቻልም።"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ar/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ar/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ar/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 987e0a1..88c42d0 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"مستندات"</string>
+ <string name="files_label" msgid="6051402950202690279">"الملفات"</string>
<string name="title_open" msgid="4353228937663917801">"فتح من"</string>
<string name="title_save" msgid="2433679664882857999">"حفظ في"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"إنشاء مجلد"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"مجلد جديد"</string>
<string name="menu_grid" msgid="6878021334497835259">"عرض الشبكة"</string>
<string name="menu_list" msgid="7279285939892417279">"عرض القائمة"</string>
<string name="menu_sort" msgid="7677740407158414452">"ترتيب بحسب"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"حفظ"</string>
<string name="menu_share" msgid="3075149983979628146">"مشاركة"</string>
<string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
- <string name="menu_select" msgid="8711270657353563424">"تحديد \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"تحديد الكل"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"تحديد الكل"</string>
<string name="menu_copy" msgid="3612326052677229148">"نسخ إلى…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"نقل إلى..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"نافذة جديدة"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"نسخ"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"لصق"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"إظهار وحدة التخزين الداخلية"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"إظهار بطاقة SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"إخفاء وحدة التخزين الداخلية"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"إخفاء بطاقة SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"إظهار حجم الملف"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"إخفاء حجم الملف"</string>
+ <string name="button_select" msgid="527196987259139214">"تحديد"</string>
<string name="button_copy" msgid="8706475544635021302">"نسخ"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"تم تحديد <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"نقل"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"إزالة"</string>
+ <string name="button_retry" msgid="4392027584153752797">"إعادة المحاولة"</string>
<string name="sort_name" msgid="9183560467917256779">"بحسب الاسم"</string>
<string name="sort_date" msgid="586080032956151448">"بحسب تاريخ التعديل"</string>
<string name="sort_size" msgid="3350681319735474741">"بحسب الحجم"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"تعذر حذف بعض المستندات"</string>
<string name="share_via" msgid="8966594246261344259">"مشاركة عبر"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"جارٍ نسخ الملفات"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"نقل الملفات"</string>
<string name="copy_remaining" msgid="6283790937387975095">"المدة المتبقية: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="zero">جارٍ نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
@@ -68,7 +76,25 @@
<item quantity="other">جارٍ نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات.</item>
<item quantity="one">جارٍ نسخ ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>).</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="zero">لا ملفات <xliff:g id="COUNT_1">%1$d</xliff:g> يجري نقلها.</item>
+ <item quantity="two">جارٍ نقل ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>).</item>
+ <item quantity="few">جارٍ نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
+ <item quantity="many">جارٍ نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا.</item>
+ <item quantity="other">جارٍ نقل <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات.</item>
+ <item quantity="one">جارٍ نقل <xliff:g id="COUNT_0">%1$d</xliff:g> ملف واحد.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="zero">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف.</item>
+ <item quantity="two">جارٍ حذف ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>).</item>
+ <item quantity="few">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات.</item>
+ <item quantity="many">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا.</item>
+ <item quantity="other">جارٍ حذف <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات.</item>
+ <item quantity="one">جارٍ حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"تراجع"</string>
<string name="copy_preparing" msgid="3896202461003039386">"جارٍ التحضير للنسخ ..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"جارٍ التحضير للنقل…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="zero">لم يتعذر نسخ أية ملفات (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
<item quantity="two">تعذر نسخ ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
@@ -77,7 +103,25 @@
<item quantity="other"> تعذر نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات</item>
<item quantity="one"> تعذر نسخ <xliff:g id="COUNT_0">%1$d</xliff:g> ملف</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="zero">ليست هناك ملفات يتعذر نقلها (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="two">تعذر نقل ملفين (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="few">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات</item>
+ <item quantity="many">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا</item>
+ <item quantity="other">تعذر نقل <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات</item>
+ <item quantity="one">تعذر نقل ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>)</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"المس لعرض التفاصيل"</string>
<string name="retry" msgid="7564024179122207376">"إعادة المحاولة"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"لم يتم نسخ هذه الملفات: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"لم يتم نقل الملفات التالية: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="zero">لم يتم نسخ أي ملف (<xliff:g id="COUNT_1">%1$d</xliff:g>) إلى الحافظة.</item>
+ <item quantity="two">تم نسخ ملفين اثنين (<xliff:g id="COUNT_1">%1$d</xliff:g>) إلى الحافظة.</item>
+ <item quantity="few">تم نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفات إلى الحافظة.</item>
+ <item quantity="many">تم نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> ملفًا إلى الحافظة.</item>
+ <item quantity="other">تم نسخ <xliff:g id="COUNT_1">%1$d</xliff:g> من الملفات إلى الحافظة.</item>
+ <item quantity="one">تم نسخ ملف واحد (<xliff:g id="COUNT_0">%1$d</xliff:g>) إلى الحافظة.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"يتعذر لصق الملفات المحددة في هذا الموقع."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-az-rAZ/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-az-rAZ/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-az-rAZ/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index 1374982..f91f2ee 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Sənədlər"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="title_open" msgid="4353228937663917801">"Vasitəsilə açın"</string>
<string name="title_save" msgid="2433679664882857999">"buraya saxlayın"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Qovluq yaradın"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Yeni qovluq"</string>
<string name="menu_grid" msgid="6878021334497835259">"Torlu görünüş"</string>
<string name="menu_list" msgid="7279285939892417279">"Siyahı görünüşü"</string>
<string name="menu_sort" msgid="7677740407158414452">"Bunlardan biri üzrə sırala"</string>
@@ -29,25 +30,74 @@
<string name="menu_save" msgid="2394743337684426338">"Yadda saxlayın"</string>
<string name="menu_share" msgid="3075149983979628146">"Paylaşın"</string>
<string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seçilmiş"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Hamısını seçin"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Buraya kopyalayın:"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Köçürün…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Yeni pəncərə"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyalayın"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Yerləşdirin"</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Daxili yaddaşı göstərin"</string>
+ <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD kartı göstərin"</string>
+ <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Daxili yaddaşı gizlədin"</string>
+ <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD kartı gizlədin"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Fayl ölçüsünü göstərin"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Fayl ölçüsünü gizlədin"</string>
+ <string name="button_select" msgid="527196987259139214">"Seçin"</string>
+ <string name="button_copy" msgid="8706475544635021302">"Kopyala"</string>
+ <string name="button_move" msgid="2202666023104202232">"Köçürün"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Rədd edin"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Yenidən cəhd edin"</string>
<string name="sort_name" msgid="9183560467917256779">"Ad üzrə"</string>
<string name="sort_date" msgid="586080032956151448">"Tarix üzrə dəyişmiş"</string>
<string name="sort_size" msgid="3350681319735474741">"Ölçü üzrə"</string>
<string name="drawer_open" msgid="4545466532430226949">"Kökləri göstərin"</string>
<string name="drawer_close" msgid="7602734368552123318">"Kökləri gizlədin"</string>
<string name="save_error" msgid="6167009778003223664">"Sənədi yadda saxlaya bilmədi"</string>
+ <string name="create_error" msgid="3735649141335444215">"Qovluq yaradıla bilmədi"</string>
+ <string name="query_error" msgid="1222448261663503501">"Sənəd sorğusu alınmadı"</string>
<string name="root_recent" msgid="4470053704320518133">"Son"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ödənişsiz"</string>
- <!-- no translation found for root_type_service (2178854894416775409) -->
- <skip />
+ <string name="root_type_service" msgid="2178854894416775409">"Saxlama xidmətləri"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Qısa yollar"</string>
<string name="root_type_device" msgid="7121342474653483538">"Cihazlar"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Daha çox tətbiq"</string>
- <string name="pref_advanced_devices" msgid="903257239609301276">"Qabaqcıl cihazları görüntüləyin"</string>
- <string name="pref_file_size" msgid="2826879315743961459">"Fayl ölçüsünü görüntüləyin"</string>
- <string name="pref_device_size" msgid="3542106883278997222">"Cihaz ölçüsünü görüntüləyin"</string>
<string name="empty" msgid="7858882803708117596">"Element yoxdur"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Faylı aça bilmir"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Bəzi sənədləri silə bilmir"</string>
<string name="share_via" msgid="8966594246261344259">"Bunun vasitəsilə paylaş:"</string>
+ <string name="copy_notification_title" msgid="6374299806748219777">"Fayllar kopyalanır"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Fayllar köçürülür"</string>
+ <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> qalıb"</string>
+ <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanır.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl kopyalanır.</item>
+ </plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülür.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülür.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinir.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinir.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Ləğv edin"</string>
+ <string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmaq üçün hazırlanır ..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Köçürmə üçün hazırlanır..."</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl kopyalanmadı</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl kopyalanmadı</item>
+ </plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl köçürülə bilmədi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl köçürülə bilmədi</item>
+ </plurals>
+ <string name="notification_touch_for_details" msgid="4483108577842961665">"Detallara baxmaq üçün toxunun"</string>
+ <string name="retry" msgid="7564024179122207376">"Yenidən cəhd edin"</string>
+ <string name="copy_failure_alert_content" msgid="3715575000297709082">"Bu fayllar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Bu fayllar köçürülmədi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fayl buferə kopyalandı.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fayl buferə kopyalandı.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçilmiş faylları bu məkana yerləşdirmək olmaz."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-bg/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-bg/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-bg/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 3f9774a..67a1c6a 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файлове"</string>
<string name="title_open" msgid="4353228937663917801">"Отваряне от"</string>
- <string name="title_save" msgid="2433679664882857999">"Запазване в/ъв"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Създаване на папка"</string>
+ <string name="title_save" msgid="2433679664882857999">"Запазване във:"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Нова папка"</string>
<string name="menu_grid" msgid="6878021334497835259">"Изглед в мрежа"</string>
<string name="menu_list" msgid="7279285939892417279">"Списъчен изглед"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортиране по"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Запазване"</string>
<string name="menu_share" msgid="3075149983979628146">"Споделяне"</string>
<string name="menu_delete" msgid="8138799623850614177">"Изтриване"</string>
- <string name="menu_select" msgid="8711270657353563424">"Избиране на „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Избиране на всички"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Избиране на всичко"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копиране във…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Преместване във…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Нов прозорец"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копиране"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Поставяне"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Вътр. хранилище: Показв."</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD карта: Показване"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Вътр. хранилище: Скрив."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD карта: Скриване"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Размер на файла: Показв."</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Размер на файла: Скрив."</string>
+ <string name="button_select" msgid="527196987259139214">"Избиране"</string>
<string name="button_copy" msgid="8706475544635021302">"Копиране"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Избрахте <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Преместване"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Отхвърляне"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Нов опит"</string>
<string name="sort_name" msgid="9183560467917256779">"По име"</string>
<string name="sort_date" msgid="586080032956151448">"По дата на промяната"</string>
<string name="sort_size" msgid="3350681319735474741">"По размер"</string>
@@ -48,7 +55,7 @@
<string name="save_error" msgid="6167009778003223664">"Запазването на документа не бе успешно"</string>
<string name="create_error" msgid="3735649141335444215">"Създаването на папката не бе успешно"</string>
<string name="query_error" msgid="1222448261663503501">"Заявката за документи не бе успешна"</string>
- <string name="root_recent" msgid="4470053704320518133">"Скорошно"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Скорошни"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Свободно: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Услуги за съхранение"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Преки пътища"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Някои документи не могат да бъдат изтрити"</string>
<string name="share_via" msgid="8966594246261344259">"Споделяне чрез"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файловете се копират"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Файловете се преместват"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Оставащо време: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Копират се <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
<item quantity="one">Копира се <xliff:g id="COUNT_0">%1$d</xliff:g> файл.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла се преместват.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл се премества.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Изтриват се <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ <item quantity="one">Изтрива се <xliff:g id="COUNT_0">%1$d</xliff:g> файл.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Отмяна"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Подготвя се за копиране…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Преместването се подготвя…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да се копират</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да се копира</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файла не можаха да бъдат преместени</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл не можа да бъде преместен</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Докоснете, за да видите подробностите"</string>
<string name="retry" msgid="7564024179122207376">"Нов опит"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Следните файлове не бяха копирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Следните файлове не бяха преместени: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Копирахте <xliff:g id="COUNT_1">%1$d</xliff:g> файла в буферната памет.</item>
+ <item quantity="one">Копирахте <xliff:g id="COUNT_0">%1$d</xliff:g> файл в буферната памет.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Избраните файлове не могат да се поставят на това място."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-bn-rBD/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-bn-rBD/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-bn-rBD/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 71ab447..b01cc84 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -17,29 +17,36 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"দস্তাবেজগুলি"</string>
+ <string name="files_label" msgid="6051402950202690279">"ফাইলগুলি"</string>
<string name="title_open" msgid="4353228937663917801">"এখান থেকে খুলুন"</string>
<string name="title_save" msgid="2433679664882857999">"এতে সংরক্ষণ করুন"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ফোল্ডার তৈরি করুন"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"নতুন ফোল্ডার"</string>
<string name="menu_grid" msgid="6878021334497835259">"গ্রিড দৃশ্য"</string>
<string name="menu_list" msgid="7279285939892417279">"তালিকা দৃশ্য"</string>
- <string name="menu_sort" msgid="7677740407158414452">"এর দ্বারা সাজান"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"এই অনুসারে বাছুন"</string>
<string name="menu_search" msgid="3816712084502856974">"অনুসন্ধান করুন"</string>
<string name="menu_settings" msgid="6008033148948428823">"সেটিংস"</string>
<string name="menu_open" msgid="432922957274920903">"খুলুন"</string>
<string name="menu_save" msgid="2394743337684426338">"সংরক্ষণ করুন"</string>
<string name="menu_share" msgid="3075149983979628146">"ভাগ করুন"</string>
<string name="menu_delete" msgid="8138799623850614177">"মুছুন"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" নির্বাচন করুন"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"সমস্ত নির্বাচন করুন"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"সবগুলি নির্বাচন করুন"</string>
<string name="menu_copy" msgid="3612326052677229148">"এতে অনুলিপি করুন…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"এতে সরান..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"নতুন উইন্ডো"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"প্রতিলিপি করুন"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"আটকান"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"অভ্যন্তরীণ সঞ্চয়স্থান দেখান"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD কার্ড দেখান"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"অভ্যন্তরীণ সঞ্চয়স্থান লুকান"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD কার্ড লুকান"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ফাইলের আকার দেখান"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ফাইলের আকার লুকান"</string>
+ <string name="button_select" msgid="527196987259139214">"নির্বাচন করুন"</string>
<string name="button_copy" msgid="8706475544635021302">"অনুলিপি করুন"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> নির্বাচন করা হয়েছে"</string>
+ <string name="button_move" msgid="2202666023104202232">"সরান"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"খারিজ করুন"</string>
+ <string name="button_retry" msgid="4392027584153752797">"আবার চেষ্টা করুন"</string>
<string name="sort_name" msgid="9183560467917256779">"নামের দ্বারা"</string>
<string name="sort_date" msgid="586080032956151448">"পরিবর্তনের তারিখ দ্বারা"</string>
<string name="sort_size" msgid="3350681319735474741">"আকার অনুযায়ী"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"কিছু দস্তাবেজ মুছতে অসমর্থ"</string>
<string name="share_via" msgid="8966594246261344259">"এর মাধ্যমে ভাগ করুন"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ফাইলগুলি অনুলিপি করা হচ্ছে"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ফাইলগুলি সরানো হচ্ছে"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> বাকি"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল অনুলিপি করা হচ্ছে৷</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল অনুলিপি করা হচ্ছে৷</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো হচ্ছে৷</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো হচ্ছে৷</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা হচ্ছে।</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মোছা হচ্ছে।</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"পূর্বাবস্থায় ফিরুন"</string>
<string name="copy_preparing" msgid="3896202461003039386">"অনুলিপি করার জন্য প্রস্তুত করা হচ্ছে..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"সরানোর জন্য প্রস্তুত হচ্ছে..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইলের প্রতিলিপি করা যায়নি</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইলের প্রতিলিপি করা যায়নি</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো যায়নি৷</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল সরানো যায়নি৷</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"বিশদ বিবরণ দেখতে স্পর্শ করুন"</string>
<string name="retry" msgid="7564024179122207376">"পুনরায় চেষ্টা করুন"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"এই ফাইলগুলির প্রতিলিপি করা হয় নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"এই ফাইলগুলি সরানো হয়নি: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল ক্লিপবোর্ডে প্রতিলিপি করা হয়েছে।</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল ক্লিপবোর্ডে প্রতিলিপি করা হয়েছে।</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"এই স্থানে নির্বাচিত ফাইলগুলি আটকানো যাবে না।"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ca/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ca/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ca/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 59cbd04..663608b 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fitxers"</string>
<string name="title_open" msgid="4353228937663917801">"Obre des de"</string>
<string name="title_save" msgid="2433679664882857999">"Desa a"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Crea una carpeta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Carpeta nova"</string>
<string name="menu_grid" msgid="6878021334497835259">"Visualització de quadrícula"</string>
<string name="menu_list" msgid="7279285939892417279">"Visualització de llista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordena per"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Desa"</string>
<string name="menu_share" msgid="3075149983979628146">"Comparteix"</string>
<string name="menu_delete" msgid="8138799623850614177">"Suprimeix"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Selecciona\'ls tots"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selecciona-ho tot"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copia a…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mou a..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Finestra nova"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copia"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Enganxa"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostra emmagatz. intern"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostra la targeta SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Amaga emmagatz. intern"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Amaga la targeta SD"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"Mostra la mida de fitxer"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Mostra la mida del fitxer"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Amaga la mida del fitxer"</string>
+ <string name="button_select" msgid="527196987259139214">"Selecciona"</string>
<string name="button_copy" msgid="8706475544635021302">"Copia"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Seleccionats: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Desplaça"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ignora"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Torna-ho a provar"</string>
<string name="sort_name" msgid="9183560467917256779">"Per nom"</string>
<string name="sort_date" msgid="586080032956151448">"Per data de modificació"</string>
<string name="sort_size" msgid="3350681319735474741">"Per mida"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"No es poden suprimir alguns documents."</string>
<string name="share_via" msgid="8966594246261344259">"Comparteix mitjançant"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"S\'estan copiant fitxers"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"S\'estan movent fitxers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Temps restant: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">S\'estan copiant <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
<item quantity="one">S\'està copiant <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">S\'estan movent <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
+ <item quantity="one">S\'està movent <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">S\'estan suprimint <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers.</item>
+ <item quantity="one">S\'està suprimint <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Desfés"</string>
<string name="copy_preparing" msgid="3896202461003039386">"S\'està preparant una còpia…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"S\'està preparant per moure\'ls..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">No s\'han pogut copiar <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
<item quantity="one">No s\'ha pogut copiar <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">No s\'han pogut moure <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers</item>
+ <item quantity="one">No s\'ha pogut moure <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toca per veure els detalls"</string>
<string name="retry" msgid="7564024179122207376">"Torna-ho a provar"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Aquests fitxers no s\'han copiat: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Aquests fitxers no s\'han mogut: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">S\'han copiat <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers al porta-retalls.</item>
+ <item quantity="one">S\'ha copiat <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer al porta-retalls.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No s\'han pogut enganxar els fitxers seleccionats en aquesta ubicació."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-cs/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-cs/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-cs/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 7697a99..81d8dc8 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -17,11 +17,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
+ <string name="files_label" msgid="6051402950202690279">"Soubory"</string>
<string name="title_open" msgid="4353228937663917801">"Otevřít"</string>
<string name="title_save" msgid="2433679664882857999">"Uložit do"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Vytvořit složku"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nová složka"</string>
<string name="menu_grid" msgid="6878021334497835259">"Mřížkové zobrazení"</string>
- <string name="menu_list" msgid="7279285939892417279">"Seznam"</string>
+ <string name="menu_list" msgid="7279285939892417279">"Zobrazení seznamu"</string>
<string name="menu_sort" msgid="7677740407158414452">"Řadit podle"</string>
<string name="menu_search" msgid="3816712084502856974">"Hledat"</string>
<string name="menu_settings" msgid="6008033148948428823">"Nastavení"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Uložit"</string>
<string name="menu_share" msgid="3075149983979628146">"Sdílet"</string>
<string name="menu_delete" msgid="8138799623850614177">"Smazat"</string>
- <string name="menu_select" msgid="8711270657353563424">"Vyberte adresář <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Vybrat vše"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Vybrat vše"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopírovat do…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Přesunout do…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nové okno"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopírovat"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Vložit"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Zobrazit inter. úložiště"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Zobrazit SD kartu"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skrýt interní úložiště"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skrýt SD kartu"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Zobrazit velikost souboru"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Skrýt velikost souboru"</string>
+ <string name="button_select" msgid="527196987259139214">"Vybrat"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopírovat"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Vybráno: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Přesunout"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Zavřít"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Zkusit znovu"</string>
<string name="sort_name" msgid="9183560467917256779">"Podle názvu"</string>
<string name="sort_date" msgid="586080032956151448">"Podle data úpravy"</string>
<string name="sort_size" msgid="3350681319735474741">"Podle velikosti"</string>
@@ -48,7 +55,7 @@
<string name="save_error" msgid="6167009778003223664">"Uložení dokumentu se nezdařilo"</string>
<string name="create_error" msgid="3735649141335444215">"Složku se nepodařilo vytvořit"</string>
<string name="query_error" msgid="1222448261663503501">"Seznam dokumentů se nepodařilo načíst"</string>
- <string name="root_recent" msgid="4470053704320518133">"Poslední"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Nedávné"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"Volné místo: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Služby úložiště"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Klávesové zkratky"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Některé dokumenty nelze smazat"</string>
<string name="share_via" msgid="8966594246261344259">"Sdílet pomocí"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopírování souborů"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Přesouvání souborů"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zbývající čas: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
@@ -66,14 +74,42 @@
<item quantity="other">Kopírování <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
<item quantity="one">Kopírování <xliff:g id="COUNT_0">%1$d</xliff:g> souboru</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="few">Přesouvají se <xliff:g id="COUNT_1">%1$d</xliff:g> soubory.</item>
+ <item quantity="many">Přesouvá se <xliff:g id="COUNT_1">%1$d</xliff:g> souboru.</item>
+ <item quantity="other">Přesouvá se <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
+ <item quantity="one">Přesouvá se <xliff:g id="COUNT_0">%1$d</xliff:g> soubor.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="few">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
+ <item quantity="many">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souboru.</item>
+ <item quantity="other">Mazání <xliff:g id="COUNT_1">%1$d</xliff:g> souborů.</item>
+ <item quantity="one">Mazání <xliff:g id="COUNT_0">%1$d</xliff:g> souboru.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Vrátit zpět"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Příprava na kopírování…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Příprava na přesunutí…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="few">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> soubory</item>
<item quantity="many">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souboru</item>
<item quantity="other">Nepodařilo se zkopírovat <xliff:g id="COUNT_1">%1$d</xliff:g> souborů</item>
<item quantity="one">Nepodařilo se zkopírovat <xliff:g id="COUNT_0">%1$d</xliff:g> soubor</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory nelze přesunout</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru nelze přesunout</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů nelze přesunout</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor nelze přesunout</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Podrobnosti zobrazíte klepnutím"</string>
<string name="retry" msgid="7564024179122207376">"Opakovat"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Tyto soubory nebyly zkopírovány: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Následující soubory nebyly přesunuty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> soubory byly zkopírovány do schránky.</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> souboru bylo zkopírováno do schránky.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> souborů bylo zkopírováno do schránky.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> soubor byl zkopírován do schránky.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Vybrané soubory nelze vložit do tohoto umístění."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-da/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-da/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-da/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 919d785..e109048 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Åbn fra"</string>
- <string name="title_save" msgid="2433679664882857999">"Gem på"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Opret mappe"</string>
+ <string name="title_save" msgid="2433679664882857999">"Gem i"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Ny mappe"</string>
<string name="menu_grid" msgid="6878021334497835259">"Gittervisning"</string>
<string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortér efter"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Gem"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
<string name="menu_delete" msgid="8138799623850614177">"Slet"</string>
- <string name="menu_select" msgid="8711270657353563424">"Vælg \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Vælg alle"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Markér alle"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiér til…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Flyt til…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nyt vindue"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiér"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Indsæt"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Vis intern lagerplads"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Vis SD-kort"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skjul intern lagerplads"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skjul SD-kort"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Vis filstørrelse"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Skjul filstørrelse"</string>
+ <string name="button_select" msgid="527196987259139214">"Vælg"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiér"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> er valgt"</string>
+ <string name="button_move" msgid="2202666023104202232">"Flyt"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Luk"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Prøv igen"</string>
<string name="sort_name" msgid="9183560467917256779">"Efter navn"</string>
<string name="sort_date" msgid="586080032956151448">"Efter ændringsdato"</string>
<string name="sort_size" msgid="3350681319735474741">"Efter størrelse"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Nogle dokumenter kan ikke slettes"</string>
<string name="share_via" msgid="8966594246261344259">"Del via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Flytter filer"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> tilbage"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
<item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ <item quantity="other">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer slettes.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer slettes.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Fortryd"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytning…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke kopieret</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev ikke flyttet</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Tryk for at se yderligere oplysninger."</string>
<string name="retry" msgid="7564024179122207376">"Prøv igen"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filer blev ikke kopieret: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Følgende filer blev ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev kopieret til udklipsholder.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer blev kopieret til udklipsholder.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"De valgte filer kan ikke indsættes på denne placering."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-de/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-de/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-de/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 2fca9a9..7c467ef 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
+ <string name="files_label" msgid="6051402950202690279">"Dateien"</string>
<string name="title_open" msgid="4353228937663917801">"Öffnen von"</string>
<string name="title_save" msgid="2433679664882857999">"Speichern unter"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Ordner erstellen"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Neuer Ordner"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rasteransicht"</string>
<string name="menu_list" msgid="7279285939892417279">"Listenansicht"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortieren nach"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Speichern"</string>
<string name="menu_share" msgid="3075149983979628146">"Teilen"</string>
<string name="menu_delete" msgid="8138799623850614177">"Löschen"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" auswählen"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Alle auswählen"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Alle auswählen"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopieren nach..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Verschieben nach…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Neues Fenster"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopieren"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Einfügen"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Int. Speicher anzeigen"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-Karte anzeigen"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Int. Speicher ausblenden"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD-Karte ausblenden"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Dateigröße anzeigen"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Dateigröße ausblenden"</string>
+ <string name="button_select" msgid="527196987259139214">"Auswählen"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopieren"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ausgewählt"</string>
+ <string name="button_move" msgid="2202666023104202232">"Verschieben"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Schließen"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Erneut versuchen"</string>
<string name="sort_name" msgid="9183560467917256779">"Nach Name"</string>
<string name="sort_date" msgid="586080032956151448">"Nach Änderungsdatum"</string>
<string name="sort_size" msgid="3350681319735474741">"Nach Größe"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Einige Dokumente konnten nicht gelöscht werden."</string>
<string name="share_via" msgid="8966594246261344259">"Teilen über"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Dateien werden kopiert"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Dateien werden verschoben"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Noch <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden kopiert.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird kopiert.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden verschoben.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird verschoben.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien werden gelöscht.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wird gelöscht.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Rückgängig machen"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopieren wird vorbereitet…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Verschieben wird vorbereitet…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht kopiert werden.</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht kopiert werden.</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien konnten nicht verschoben werden.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei konnte nicht verschoben werden.</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Zum Einblenden von Details tippen"</string>
<string name="retry" msgid="7564024179122207376">"Erneut versuchen"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Diese Dateien wurden nicht kopiert: <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Diese Dateien wurden nicht verschoben: <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> Dateien wurden in die Zwischenablage kopiert.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> Datei wurde in die Zwischenablage kopiert.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Die ausgewählten Dateien können an diesem Ort nicht eingefügt werden."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-el/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-el/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-el/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 409cca7..a350002 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Έγγραφα"</string>
+ <string name="files_label" msgid="6051402950202690279">"Αρχεία"</string>
<string name="title_open" msgid="4353228937663917801">"Άνοιγμα από"</string>
<string name="title_save" msgid="2433679664882857999">"Αποθήκευση σε"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Δημιουργία φακέλου"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Νέος φάκελος"</string>
<string name="menu_grid" msgid="6878021334497835259">"Προβολή πλέγματος"</string>
<string name="menu_list" msgid="7279285939892417279">"Προβολή λίστας"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ταξινόμηση κατά"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Αποθήκευση"</string>
<string name="menu_share" msgid="3075149983979628146">"Κοινή χρήση"</string>
<string name="menu_delete" msgid="8138799623850614177">"Διαγραφή"</string>
- <string name="menu_select" msgid="8711270657353563424">"Επιλογή \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Επιλογή όλων"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Επιλογή όλων"</string>
<string name="menu_copy" msgid="3612326052677229148">"Αντιγραφή σε…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Μετακίνηση σε..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Νέο παράθυρο"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Αντιγραφή"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Επικόλληση"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Εμφ.εσωτ.χώρου αποθήκ."</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Εμφάνιση κάρτας SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Απόκρ.εσωτ.χώρου αποθήκ."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Απόκρυψη κάρτας SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Εμφ. μεγέθους αρχείου"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Απόκρ. μεγέθους αρχείου"</string>
+ <string name="button_select" msgid="527196987259139214">"Επιλογή"</string>
<string name="button_copy" msgid="8706475544635021302">"Αντιγραφή"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Επιλέχθηκαν <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Μετακίνηση"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Παράβλεψη"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Δοκιμάστε ξανά"</string>
<string name="sort_name" msgid="9183560467917256779">"Κατά όνομα"</string>
<string name="sort_date" msgid="586080032956151448">"Κατά ημερομηνία τροποποίησης"</string>
<string name="sort_size" msgid="3350681319735474741">"Κατά μέγεθος"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Δεν είναι δυνατή η διαγραφή ορισμένων εγγράφων"</string>
<string name="share_via" msgid="8966594246261344259">"Κοινή χρήση μέσω"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Αντιγραφή αρχείων"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Μετακίνηση αρχείων"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Απομένουν <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
<item quantity="one">Αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Μετακίνηση <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
+ <item quantity="one">Μετακίνηση <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Διαγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων.</item>
+ <item quantity="one">Διαγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Αναίρεση"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Προετοιμασία για αντιγραφή…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Προετοιμασία για μετακίνηση…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
<item quantity="one">Δεν ήταν δυνατή η αντιγραφή <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_1">%1$d</xliff:g> αρχείων</item>
+ <item quantity="one">Δεν ήταν δυνατή η μετακίνηση <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείου</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Αγγίξτε για προβολή λεπτομερειών"</string>
<string name="retry" msgid="7564024179122207376">"Επανάληψη"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Αυτά τα αρχεία δεν αντιγράφηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Αυτά τα αρχεία δεν μετακινήθηκαν: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> αρχεία αντιγράφηκαν στο πρόχειρο.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> αρχείο αντιγράφηκε στο πρόχειρο.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Δεν είναι δυνατή η επικόλληση των επιλεγμένων αρχείων σε αυτήν την τοποθεσία."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-en-rAU/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-en-rAU/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-en-rAU/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 7af8c4e..e9ba34b 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
+ <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"New folder"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
<string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
- <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Select all"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Hide SD card"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Show file size"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Hide file size"</string>
+ <string name="button_select" msgid="527196987259139214">"select"</string>
<string name="button_copy" msgid="8706475544635021302">"Copy"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+ <string name="button_move" msgid="2202666023104202232">"Move"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Dismiss"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Try again"</string>
<string name="sort_name" msgid="9183560467917256779">"By name"</string>
<string name="sort_date" msgid="586080032956151448">"By date modified"</string>
<string name="sort_size" msgid="3350681319735474741">"By size"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Undo"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
<item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
<string name="retry" msgid="7564024179122207376">"Retry"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
+ <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-en-rGB/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-en-rGB/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-en-rGB/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 7af8c4e..e9ba34b 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
+ <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"New folder"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
<string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
- <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Select all"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Hide SD card"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Show file size"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Hide file size"</string>
+ <string name="button_select" msgid="527196987259139214">"select"</string>
<string name="button_copy" msgid="8706475544635021302">"Copy"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+ <string name="button_move" msgid="2202666023104202232">"Move"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Dismiss"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Try again"</string>
<string name="sort_name" msgid="9183560467917256779">"By name"</string>
<string name="sort_date" msgid="586080032956151448">"By date modified"</string>
<string name="sort_size" msgid="3350681319735474741">"By size"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Undo"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
<item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
<string name="retry" msgid="7564024179122207376">"Retry"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
+ <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-en-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-en-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-en-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 7af8c4e..e9ba34b 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
+ <string name="files_label" msgid="6051402950202690279">"Files"</string>
<string name="title_open" msgid="4353228937663917801">"Open from"</string>
<string name="title_save" msgid="2433679664882857999">"Save to"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Create folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"New folder"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grid view"</string>
<string name="menu_list" msgid="7279285939892417279">"List view"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sort by"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Save"</string>
<string name="menu_share" msgid="3075149983979628146">"Share"</string>
<string name="menu_delete" msgid="8138799623850614177">"Delete"</string>
- <string name="menu_select" msgid="8711270657353563424">"Select \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Select All"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Select all"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copy to…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Move to…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"New window"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copy"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Paste"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Show internal storage"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Show SD card"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Hide internal storage"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Hide SD card"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Show file size"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Hide file size"</string>
+ <string name="button_select" msgid="527196987259139214">"select"</string>
<string name="button_copy" msgid="8706475544635021302">"Copy"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selected"</string>
+ <string name="button_move" msgid="2202666023104202232">"Move"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Dismiss"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Try again"</string>
<string name="sort_name" msgid="9183560467917256779">"By name"</string>
<string name="sort_date" msgid="586080032956151448">"By date modified"</string>
<string name="sort_size" msgid="3350681319735474741">"By size"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Unable to delete some documents"</string>
<string name="share_via" msgid="8966594246261344259">"Share via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copying files"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Moving files"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> left"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copying <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
<item quantity="one">Copying <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Moving <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Moving <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Deleting <xliff:g id="COUNT_1">%1$d</xliff:g> files.</item>
+ <item quantity="one">Deleting <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Undo"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparing for copy…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparing for move…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Couldn\'t copy <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
<item quantity="one">Couldn\'t copy <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Couldn\'t move <xliff:g id="COUNT_1">%1$d</xliff:g> files</item>
+ <item quantity="one">Couldn\'t move <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Touch to view details"</string>
<string name="retry" msgid="7564024179122207376">"Retry"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"These files weren\'t copied: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"These files weren\'t moved: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Copied <xliff:g id="COUNT_1">%1$d</xliff:g> files to clipboard.</item>
+ <item quantity="one">Copied <xliff:g id="COUNT_0">%1$d</xliff:g> file to clipboard.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Cannot paste the selected files in this location."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-es-rUS/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-es-rUS/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-es-rUS/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 4edbeda..8e0a18c 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Crear carpeta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Carpeta nueva"</string>
<string name="menu_grid" msgid="6878021334497835259">"Vista de cuadrícula"</string>
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
- <string name="menu_select" msgid="8711270657353563424">"Seleccionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todos"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Seleccionar todo"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiar a…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Ventana nueva"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarjeta SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almacen. interno"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar tarjeta SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tamaño archivos"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tamaño archivos"</string>
+ <string name="button_select" msgid="527196987259139214">"Seleccionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seleccionado(s)"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Descartar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Reintentar"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
<string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
<string name="sort_size" msgid="3350681319735474741">"Por tamaño"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos."</string>
<string name="share_via" msgid="8966594246261344259">"Compartir mediante"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Moviendo archivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Faltan <xliff:g id="DURATION">%s</xliff:g>."</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Moviendo <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+ <item quantity="one">Moviendo <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Se están borrando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+ <item quantity="one">Se está borrando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparación para mover archivos…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">No se pudieron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
<item quantity="one">No se pudo copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">No se pudieron mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+ <item quantity="one">No se pudo mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toca el elemento para ver más información."</string>
<string name="retry" msgid="7564024179122207376">"Reintentar"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"No se copiaron estos archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"No se movieron los siguientes archivos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Se copiaron <xliff:g id="COUNT_1">%1$d</xliff:g> archivos al portapapeles.</item>
+ <item quantity="one">Se copió <xliff:g id="COUNT_0">%1$d</xliff:g> archivo al portapapeles.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"No se pueden pegar los archivos seleccionados en esta ubicación."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-es/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-es/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-es/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index ac9692c..cf0b607 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Archivos"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar en"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Crear carpeta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nueva carpeta"</string>
<string name="menu_grid" msgid="6878021334497835259">"Vista de cuadrícula"</string>
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todo"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Seleccionar todo"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nueva ventana"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almac. interno"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarjeta SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almac. interno"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar tarjeta SD"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tamaño archivo"</string>
- <string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tamaño archivo"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tamaño del archivo"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tamaño del archivo"</string>
+ <string name="button_select" msgid="527196987259139214">"Seleccionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Seleccionado: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ignorar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Reintentar"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nombre"</string>
<string name="sort_date" msgid="586080032956151448">"Por fecha de modificación"</string>
<string name="sort_size" msgid="3350681319735474741">"Por tamaño"</string>
@@ -54,22 +61,43 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"Accesos directos"</string>
<string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Más aplicaciones"</string>
- <string name="empty" msgid="7858882803708117596">"Sin elementos"</string>
+ <string name="empty" msgid="7858882803708117596">"No hay elementos"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Error al abrir el archivo"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"No es posible eliminar algunos documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando archivos"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Moviendo archivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Tiempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
<item quantity="one">Copiando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Moviendo <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+ <item quantity="one">Moviendo <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Eliminando <xliff:g id="COUNT_1">%1$d</xliff:g> archivos.</item>
+ <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> archivo.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Deshacer"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">No se han podido copiar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
<item quantity="one">No se ha podido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">No se han podido mover <xliff:g id="COUNT_1">%1$d</xliff:g> archivos</item>
+ <item quantity="one">No se ha podido mover <xliff:g id="COUNT_0">%1$d</xliff:g> archivo</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver más información"</string>
<string name="retry" msgid="7564024179122207376">"Volver a intentar"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Archivos que no se han copiado: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Archivos que no se han movido: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Se han copiado <xliff:g id="COUNT_1">%1$d</xliff:g> archivos al portapapeles.</item>
+ <item quantity="one">Se ha copiado <xliff:g id="COUNT_0">%1$d</xliff:g> archivo al portapapeles.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Los archivos seleccionados no se pueden pegar en esta ubicación."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-et-rEE/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-et-rEE/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-et-rEE/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 8f02871..76d1f48 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumendid"</string>
+ <string name="files_label" msgid="6051402950202690279">"Failid"</string>
<string name="title_open" msgid="4353228937663917801">"Ava:"</string>
<string name="title_save" msgid="2433679664882857999">"Salvesta:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Loo kaust"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Uus kaust"</string>
<string name="menu_grid" msgid="6878021334497835259">"Ruudustikkuva"</string>
<string name="menu_list" msgid="7279285939892417279">"Loendikuva"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortimisalus:"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Salvesta"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaga"</string>
<string name="menu_delete" msgid="8138799623850614177">"Kustuta"</string>
- <string name="menu_select" msgid="8711270657353563424">"Kataloogi „<xliff:g id="DIRECTORY">^1</xliff:g>” valimine"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Vali kõik"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Vali kõik"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopeeri asukohta ..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Teisaldamine kohta ..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Uus aken"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopeeri"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Kleebi"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Kuva sis. salvestusruum"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Kuva SD-kaart"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Peida sis. salvestusruum"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Peida SD-kaart"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Kuva faili suurus"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Peida faili suurus"</string>
+ <string name="button_select" msgid="527196987259139214">"Vali"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopeeri"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> on valitud"</string>
+ <string name="button_move" msgid="2202666023104202232">"Teisalda"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Loobu"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Proovi uuesti"</string>
<string name="sort_name" msgid="9183560467917256779">"Nime järgi"</string>
<string name="sort_date" msgid="586080032956151448">"Muutmiskuupäeva järgi"</string>
<string name="sort_size" msgid="3350681319735474741">"Suuruse järgi"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Mõnda dokumenti ei õnnestu kustutada"</string>
<string name="share_via" msgid="8966594246261344259">"Jagage teenusega"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Failide kopeerimine"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Failide teisaldamine"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Jäänud on <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili kopeerimine.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili kopeerimine.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Teisaldatakse <xliff:g id="COUNT_1">%1$d</xliff:g> faili.</item>
+ <item quantity="one">Teisaldatakse <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Kustutatakse <xliff:g id="COUNT_1">%1$d</xliff:g> faili.</item>
+ <item quantity="one">Kustutatakse <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Võta tagasi"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopeerimise ettevalmistamine …"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Teisaldamise ettevalmistamine …"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud kopeerida</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud kopeerida</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili ei saanud teisaldada</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> faili ei saanud teisaldada</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Puudutage üksikasjade vaatamiseks"</string>
<string name="retry" msgid="7564024179122207376">"Proovi uuesti"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Neid faile ei kopeeritud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Neid faile ei teisaldatud: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili kopeeriti lõikelauale.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fail kopeeriti lõikelauale.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valitud faile ei saa sellesse asukohta kleepida."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-eu-rES/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-eu-rES/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-eu-rES/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 3ddc0d1..f24cf60 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentuak"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fitxategiak"</string>
<string name="title_open" msgid="4353228937663917801">"Ireki hemendik"</string>
<string name="title_save" msgid="2433679664882857999">"Gorde hemen"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Sortu karpeta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Karpeta berria"</string>
<string name="menu_grid" msgid="6878021334497835259">"Sareta-ikuspegia"</string>
<string name="menu_list" msgid="7279285939892417279">"Zerrenda-ikuspegia"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenatzeko irizpidea"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Gorde"</string>
<string name="menu_share" msgid="3075149983979628146">"Partekatu"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ezabatu"</string>
- <string name="menu_select" msgid="8711270657353563424">"Hautatu \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Hautatu guztiak"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Hautatu guztiak"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiatu hemen…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Eraman hona…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Leiho berria"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiatu"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Itsatsi"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Erakutsi barneko memoria"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Erakutsi SD txartela"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ezkutatu barneko memoria"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ezkutatu SD txartela"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Erakutsi fitxategi-tamaina"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ezkutatu fitxategi-tamaina"</string>
+ <string name="button_select" msgid="527196987259139214">"Hautatu"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiatu"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> hautatuta"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mugitu"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Baztertu"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Saiatu berriro"</string>
<string name="sort_name" msgid="9183560467917256779">"Izenaren arabera"</string>
<string name="sort_date" msgid="586080032956151448">"Aldatze-dataren arabera"</string>
<string name="sort_size" msgid="3350681319735474741">"Tamainaren arabera"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Ezin izan dira dokumentu batzuk ezabatu"</string>
<string name="share_via" msgid="8966594246261344259">"Partekatu honen bidez:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fitxategiak kopiatzen"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Fitxategiak mugitzea"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Falta den denbora: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatzen.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi kopiatzen.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi mugitzen.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi mugitzen.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi ezabatzen ari dira.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi ezabatzen ari da.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Desegin"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopiatzeko prestatzen…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Mugitzeko prestatzen…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Ezin izan dira kopiatu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
<item quantity="one">Ezin izan da kopiatu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Ezin izan dira mugitu <xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi</item>
+ <item quantity="one">Ezin izan da mugitu <xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Xehetasunak ikusteko, ukitu hau."</string>
<string name="retry" msgid="7564024179122207376">"Saiatu berriro"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Ez dira kopiatu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Ez dira mugitu fitxategi hauek: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi kopiatu dira arbelean.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi kopiatu da arbelean.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ezin dira itsatsi hautatutako fitxategiak kokapen honetan."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-fa/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-fa/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-fa/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 5101e16..432205e 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -17,32 +17,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"اسناد"</string>
+ <string name="files_label" msgid="6051402950202690279">"فایلها"</string>
<string name="title_open" msgid="4353228937663917801">"باز کردن از"</string>
<string name="title_save" msgid="2433679664882857999">"ذخیره در"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ایجاد پوشه"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"پوشه جدید"</string>
<string name="menu_grid" msgid="6878021334497835259">"نمای جدولی"</string>
- <string name="menu_list" msgid="7279285939892417279">"نمای فهرستوار"</string>
- <string name="menu_sort" msgid="7677740407158414452">"مرتبسازی بر اساس"</string>
+ <string name="menu_list" msgid="7279285939892417279">"نمای فهرستی"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"مرتبسازی براساس"</string>
<string name="menu_search" msgid="3816712084502856974">"جستجو"</string>
<string name="menu_settings" msgid="6008033148948428823">"تنظیمات"</string>
<string name="menu_open" msgid="432922957274920903">"باز کردن"</string>
<string name="menu_save" msgid="2394743337684426338">"ذخیره"</string>
<string name="menu_share" msgid="3075149983979628146">"اشتراکگذاری"</string>
<string name="menu_delete" msgid="8138799623850614177">"حذف"</string>
- <string name="menu_select" msgid="8711270657353563424">"انتخاب «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"انتخاب همه"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"انتخاب همه"</string>
<string name="menu_copy" msgid="3612326052677229148">"کپی در..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"انتقال به…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"پنجره جدید"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"کپی"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"جایگذاری"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"نمایش فضای ذخیرهسازی داخلی"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"نمایش کارت SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"پنهان کردن فضای ذخیرهسازی داخلی"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"پنهان کردن کارت SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"نمایش اندازه فایل"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"پنهان کردن اندازه فایل"</string>
+ <string name="button_select" msgid="527196987259139214">"انتخاب"</string>
<string name="button_copy" msgid="8706475544635021302">"کپی"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> انتخاب شد"</string>
- <string name="sort_name" msgid="9183560467917256779">"بر اساس نام"</string>
- <string name="sort_date" msgid="586080032956151448">"بر اساس تاریخ اصلاح"</string>
- <string name="sort_size" msgid="3350681319735474741">"بر اساس اندازه"</string>
+ <string name="button_move" msgid="2202666023104202232">"انتقال"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"نپذیرفتن"</string>
+ <string name="button_retry" msgid="4392027584153752797">"دوباره امتحان کنید"</string>
+ <string name="sort_name" msgid="9183560467917256779">"براساس نام"</string>
+ <string name="sort_date" msgid="586080032956151448">"براساس تاریخ اصلاح"</string>
+ <string name="sort_size" msgid="3350681319735474741">"براساس اندازه"</string>
<string name="drawer_open" msgid="4545466532430226949">"نمایش ریشهها"</string>
<string name="drawer_close" msgid="7602734368552123318">"پنهان کردن ریشهها"</string>
<string name="save_error" msgid="6167009778003223664">"ذخیره سند انجام نشد"</string>
@@ -51,7 +58,7 @@
<string name="root_recent" msgid="4470053704320518133">"اخیر"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> آزاد"</string>
<string name="root_type_service" msgid="2178854894416775409">"خدمات ذخیرهسازی"</string>
- <string name="root_type_shortcut" msgid="3318760609471618093">"میانبرها"</string>
+ <string name="root_type_shortcut" msgid="3318760609471618093">"میانبرها"</string>
<string name="root_type_device" msgid="7121342474653483538">"دستگاهها"</string>
<string name="root_type_apps" msgid="8838065367985945189">"برنامههای بیشتر"</string>
<string name="empty" msgid="7858882803708117596">"موردی موجود نیست"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"برخی از اسناد حذف نمیشوند"</string>
<string name="share_via" msgid="8966594246261344259">"اشتراکگذاری از طریق"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"در حال کپی کردن فایلها"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"درحال انتقال فایلها"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقیمانده"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">در حال کپی کردن <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
<item quantity="other">در حال کپی کردن <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">در حال انتقال <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+ <item quantity="other">در حال انتقال <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">در حال حذف <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+ <item quantity="other">در حال حذف <xliff:g id="COUNT_1">%1$d</xliff:g> فایل.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"لغو"</string>
<string name="copy_preparing" msgid="3896202461003039386">"در حال آمادهسازی برای کپی..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"درحال آمادهسازی برای انتقال…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل کپی نشد</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل کپی نشد</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل منتقل نشد</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"برای مشاهده جزئیات لمس کنید"</string>
<string name="retry" msgid="7564024179122207376">"امتحان مجدد"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"این فایلها کپی نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"این فایلها منتقل نشدند: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریدهدان کپی شد.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل در بریدهدان کپی شد.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"نمیتوان فایلهای انتخابی را در این مکان جایگذاری کرد."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-fi/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-fi/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-fi/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index a9fe251..33f2e3d 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Asiakirjat"</string>
+ <string name="files_label" msgid="6051402950202690279">"Tiedostot"</string>
<string name="title_open" msgid="4353228937663917801">"Avaa sijainnista"</string>
<string name="title_save" msgid="2433679664882857999">"Tallenna kohteeseen"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Luo kansio"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Uusi kansio"</string>
<string name="menu_grid" msgid="6878021334497835259">"Ruudukkonäkymä"</string>
<string name="menu_list" msgid="7279285939892417279">"Luettelonäkymä"</string>
<string name="menu_sort" msgid="7677740407158414452">"Lajitteluperuste"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Tallenna"</string>
<string name="menu_share" msgid="3075149983979628146">"Jaa"</string>
<string name="menu_delete" msgid="8138799623850614177">"Poista"</string>
- <string name="menu_select" msgid="8711270657353563424">"Valitse <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Valitse kaikki"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Valitse kaikki"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopioi kohteeseen…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Siirrä kohteeseen…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Uusi ikkuna"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopioi"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Liitä"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Näytä sis. tallennustila"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Näytä SD-kortti"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Piilota sis. tallennust."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Piilota SD-kortti"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Näytä tiedostokoko"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Piilota tiedostokoko"</string>
+ <string name="button_select" msgid="527196987259139214">"Valitse"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopioi"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valittua"</string>
+ <string name="button_move" msgid="2202666023104202232">"Siirrä"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Hylkää"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Yritä uudelleen"</string>
<string name="sort_name" msgid="9183560467917256779">"Nimen mukaan"</string>
<string name="sort_date" msgid="586080032956151448">"Muokkauspäivän mukaan"</string>
<string name="sort_size" msgid="3350681319735474741">"Koon mukaan"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Joitakin asiakirjoja ei voi poistaa"</string>
<string name="share_via" msgid="8966594246261344259">"Jaa sovelluksessa"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopioidaan tiedostoja"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Siirretään tiedostoja"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> jäljellä"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopioidaan <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
<item quantity="one">Kopioidaan <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Siirretään <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
+ <item quantity="one">Siirretään <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Poistetaan <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa.</item>
+ <item quantity="one">Poistetaan <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Kumoa"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Valmistellaan kopiointia…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Valmistellaan siirtämistä…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston kopioiminen epäonnistui.</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedoston siirtäminen epäonnistui.</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Lue lisätietoja koskettamalla"</string>
<string name="retry" msgid="7564024179122207376">"Yritä uudelleen"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Seuraavia tiedostoja ei kopioitu: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Näitä tiedostoja ei siirretty: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa kopioitiin leikepöydälle.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto kopioitiin leikepöydälle.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Valittuja tiedostoja ei voi liittää tähän sijaintiin."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-fr-rCA/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-fr-rCA/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-fr-rCA/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index b0c96e8..228dc7a 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documents"</string>
- <string name="title_open" msgid="4353228937663917801">"Ouvert à partir de"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
+ <string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer dans"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nouveau dossier"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grille"</string>
<string name="menu_list" msgid="7279285939892417279">"Liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
<string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
- <string name="menu_select" msgid="8711270657353563424">"Sélectionner « <xliff:g id="DIRECTORY">^1</xliff:g> »"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Tout sélectionner"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Tout sélectionner"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copier vers..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Déplacer dans…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nouvelle fenêtre"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copier"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Coller"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afficher la carte SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Masquer mém. stock. int."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Masquer la carte SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Afficher taille fichier"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Masquer taille fichier"</string>
+ <string name="button_select" msgid="527196987259139214">"Sélectionner"</string>
<string name="button_copy" msgid="8706475544635021302">"Copier"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> sélectionné(s)"</string>
+ <string name="button_move" msgid="2202666023104202232">"Déplacer"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Faire disparaître"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Réessayer"</string>
<string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
<string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
<string name="sort_size" msgid="3350681319735474741">"Par taille"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents"</string>
<string name="share_via" msgid="8966594246261344259">"Partager par"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers..."</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Déplacement des fichiers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Durée restante : <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours.</item>
<item quantity="other">Copier de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours.</item>
+ <item quantity="other">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier.</item>
+ <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Annuler"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Préparation du déplacement..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+ <item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Touchez ici pour afficher les détails"</string>
<string name="retry" msgid="7564024179122207376">"Réessayer"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Ces fichiers ne ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Ces fichiers n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a été copié dans le presse-papiers.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ont été copiés dans le presse-papiers.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-fr/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-fr/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-fr/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 57fe11a..eb9f84a 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Docs"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fichiers"</string>
<string name="title_open" msgid="4353228937663917801">"Ouvrir à partir de"</string>
<string name="title_save" msgid="2433679664882857999">"Enregistrer sous"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Créer un dossier"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nouveau dossier"</string>
<string name="menu_grid" msgid="6878021334497835259">"Grille"</string>
<string name="menu_list" msgid="7279285939892417279">"Liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Trier par"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Enregistrer"</string>
<string name="menu_share" msgid="3075149983979628146">"Partager"</string>
<string name="menu_delete" msgid="8138799623850614177">"Supprimer"</string>
- <string name="menu_select" msgid="8711270657353563424">"Sélectionner \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Tout sélectionner"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Tout sélectionner"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copier vers…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Placer dans…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nouvelle fenêtre"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copier"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Coller"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Aff. mém. stock. interne"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afficher la carte SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Masquer mém. stock. int."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Masquer la carte SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Afficher taille fichier"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Masquer taille fichier"</string>
+ <string name="button_select" msgid="527196987259139214">"Sélectionner"</string>
<string name="button_copy" msgid="8706475544635021302">"Copier"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> élément(s) sélectionné(s)"</string>
+ <string name="button_move" msgid="2202666023104202232">"Déplacer"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Fermer"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Réessayer"</string>
<string name="sort_name" msgid="9183560467917256779">"Par nom"</string>
<string name="sort_date" msgid="586080032956151448">"Par date de modification"</string>
<string name="sort_size" msgid="3350681319735474741">"Par taille"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossible de supprimer certains documents."</string>
<string name="share_via" msgid="8966594246261344259">"Partager via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copie de fichiers en cours"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Déplacement de fichiers"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Temps restant : <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
<item quantity="other">Copie de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
+ <item quantity="other">Déplacement de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichier en cours…</item>
+ <item quantity="other">Suppression de <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers en cours…</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Annuler"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Préparation de la copie en cours…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Préparation au déplacement…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
<item quantity="other">Impossible de copier <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier</item>
+ <item quantity="other">Impossible de déplacer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Appuyez pour en savoir plus."</string>
<string name="retry" msgid="7564024179122207376">"Réessayer"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Les fichiers suivants n\'ont pas été copiés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Les fichiers suivants n\'ont pas été déplacés : <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fichier a bien été copié dans le Presse-papiers.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ont bien été copiés dans le Presse-papiers.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossible de coller les fichiers sélectionnés à cet endroit."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-gl-rES/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-gl-rES/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-gl-rES/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 3b7cccf..07c5d39 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir desde"</string>
<string name="title_save" msgid="2433679664882857999">"Gardar en"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Crear cartafol"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Novo cartafol"</string>
<string name="menu_grid" msgid="6878021334497835259">"Vista de grade"</string>
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Gardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartir"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selecciona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Seleccionar todos"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Seleccionar todo"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiar en…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover a…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nova ventá"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Pegar"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar almacen. interno"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar tarxeta SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar almacen. interno"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar tarxeta SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tamaño ficheiro"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tamaño ficheiro"</string>
+ <string name="button_select" msgid="527196987259139214">"Seleccionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> seleccionados"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ignorar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Tentar de novo"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
<string name="sort_date" msgid="586080032956151448">"Por data de modificación"</string>
<string name="sort_size" msgid="3350681319735474741">"Por tamaño"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Non se poden eliminar algúns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartir a través de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando ficheiros"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Mover ficheiros"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Tempo restante: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
<item quantity="one">Copianto <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+ <item quantity="one">Movendo <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Eliminando <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+ <item quantity="one">Eliminando <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Desfacer"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparándose para mover..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Non se puideron copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Non se puido copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Non se puideron mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+ <item quantity="one">Non se puido mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toca para ver detalles"</string>
<string name="retry" msgid="7564024179122207376">"Tentar de novo"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Non se copiaron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Non se moveron estes ficheiros: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Copiáronse <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros no portapapeis.</item>
+ <item quantity="one">Copiouse <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro no portapapeis.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Non se poden pegar os ficheiros seleccionados nesta localización."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-gu-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-gu-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-gu-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index cac6021..dade7df 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"દસ્તાવેજો"</string>
+ <string name="files_label" msgid="6051402950202690279">"ફાઇલો"</string>
<string name="title_open" msgid="4353228937663917801">"અહીંથી ખોલો"</string>
<string name="title_save" msgid="2433679664882857999">"આમાં સાચવો"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ફોલ્ડર બનાવો"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"નવું ફોલ્ડર"</string>
<string name="menu_grid" msgid="6878021334497835259">"ગ્રિડ દૃશ્ય"</string>
<string name="menu_list" msgid="7279285939892417279">"સૂચિ દૃશ્ય"</string>
<string name="menu_sort" msgid="7677740407158414452">"આ પ્રમાણે સૉર્ટ કરો"</string>
@@ -29,21 +30,27 @@
<string name="menu_save" msgid="2394743337684426338">"સાચવો"</string>
<string name="menu_share" msgid="3075149983979628146">"શેર કરો"</string>
<string name="menu_delete" msgid="8138799623850614177">"કાઢી નાખો"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" પસંદ કરો"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"બધા પસંદ કરો"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"બધા પસંદ કરો"</string>
<string name="menu_copy" msgid="3612326052677229148">"આના પર કૉપિ કરો…"</string>
- <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"આંતરિક સ્ટોરેજ દર્શાવો"</string>
- <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD કાર્ડ દર્શાવો"</string>
+ <string name="menu_move" msgid="1828090633118079817">"આમાં ખસેડો…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"નવી વિંડો"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"કૉપિ કરો"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"પેસ્ટ કરો"</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"આંતરિક સ્ટોરેજ બતાવો"</string>
+ <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD કાર્ડ બતાવો"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"આંતરિક સંગ્રહ છુપાવો"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD કાર્ડ છુપાવો"</string>
- <string name="menu_file_size_show" msgid="3240323619260823076">"ફાઇલ કદ દર્શાવો"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"ફાઇલ કદ બતાવો"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ફાઇલ કદ છુપાવો"</string>
+ <string name="button_select" msgid="527196987259139214">"પસંદ કરો"</string>
<string name="button_copy" msgid="8706475544635021302">"કૉપિ કરો"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> પસંદ કર્યા"</string>
+ <string name="button_move" msgid="2202666023104202232">"ખસેડો"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"છોડી દો"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ફરીથી પ્રયત્ન કરો"</string>
<string name="sort_name" msgid="9183560467917256779">"નામ દ્વારા"</string>
<string name="sort_date" msgid="586080032956151448">"સંશોધન તારીખ દ્વારા"</string>
<string name="sort_size" msgid="3350681319735474741">"કદ દ્વારા"</string>
- <string name="drawer_open" msgid="4545466532430226949">"રૂટ્સ દર્શાવો"</string>
+ <string name="drawer_open" msgid="4545466532430226949">"રૂટ્સ બતાવો"</string>
<string name="drawer_close" msgid="7602734368552123318">"રૂટ્સ છુપાવો"</string>
<string name="save_error" msgid="6167009778003223664">"દસ્તાવેજ સાચવવામાં નિષ્ફળ થયાં."</string>
<string name="create_error" msgid="3735649141335444215">"ફોલ્ડર બનાવવામાં નિષ્ફળ થયા"</string>
@@ -53,23 +60,44 @@
<string name="root_type_service" msgid="2178854894416775409">"સંગ્રહ સેવાઓ"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"શોર્ટકટ્સ"</string>
<string name="root_type_device" msgid="7121342474653483538">"ઉપકરણો"</string>
- <string name="root_type_apps" msgid="8838065367985945189">"વધુ એપ્લિકેશન્સ"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"વધુ એપ્લિકેશનો"</string>
<string name="empty" msgid="7858882803708117596">"કોઈ આઇટમ્સ નથી"</string>
<string name="toast_no_application" msgid="1339885974067891667">"ફાઇલ ખોલી શકાતી નથી"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"કેટલાક દસ્તાવેજો કાઢી નાખવામાં અસમર્થ"</string>
<string name="share_via" msgid="8966594246261344259">"આના દ્વારા શેર કરો"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ફાઇલો કૉપિ કરી રહ્યાં છે"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ફાઇલો ખસેડી રહ્યાં છે"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> બાકી"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી રહ્યાં છે.</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી રહ્યાં છે.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી રહ્યાં છે.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી રહ્યાં છે.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી રહ્યાં છે.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખી રહ્યાં છે.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"પૂર્વવત્ કરો"</string>
<string name="copy_preparing" msgid="3896202461003039386">"કૉપિ માટે તૈયારી કરી રહ્યું છે…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ખસેડવા માટે તૈયાર કરી રહ્યું છે…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી શકાઈ નથી</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી શકાઈ નથી</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી શકાઈ નથી</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો ખસેડી શકાઈ નથી</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"વિગતો જોવા માટે ટચ કરો"</string>
<string name="retry" msgid="7564024179122207376">"ફરી પ્રયાસ કરો"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"આ ફાઇલો કૉપિ કરી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"આ ફાઇલો ખસેડી નહોતી: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">ક્લિપબોર્ડ પર <xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી.</item>
+ <item quantity="other">ક્લિપબોર્ડ પર <xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલો કૉપિ કરી.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"આ સ્થાનમાં પસંદ કરેલ ફાઇલો પેસ્ટ કરી શકાતી નથી."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-hi/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-hi/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-hi/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 19269b0..0a5de16 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तावेज़"</string>
+ <string name="files_label" msgid="6051402950202690279">"फ़ाइलें"</string>
<string name="title_open" msgid="4353228937663917801">"यहां से खोलें"</string>
- <string name="title_save" msgid="2433679664882857999">"यहां जोड़ें"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"फ़ोल्डर बनाएं"</string>
+ <string name="title_save" msgid="2433679664882857999">"यहां सहेजें"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"नया फ़ोल्डर"</string>
<string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
<string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
<string name="menu_sort" msgid="7677740407158414452">"इससे क्रमित करें"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"जोड़ें"</string>
<string name="menu_share" msgid="3075149983979628146">"साझा करें"</string>
<string name="menu_delete" msgid="8138799623850614177">"हटाएं"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" चुनें"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"सभी चुनें"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"सभी चुनें"</string>
<string name="menu_copy" msgid="3612326052677229148">"इनकी कॉपी बनाएं..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"इसमें ले जाएं…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"नई विंडो"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"कॉपी करें"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"चिपकाएं"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आंतरिक मेमोरी दिखाएं"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड दिखाएं"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आंतरिक मेमोरी छिपाएं"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD कार्ड छिपाएं"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"फ़ाइल आकार दिखाएं"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"फ़ाइल आकार छिपाएं"</string>
+ <string name="button_select" msgid="527196987259139214">"चुनें"</string>
<string name="button_copy" msgid="8706475544635021302">"कॉपी करें"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> चयनित"</string>
+ <string name="button_move" msgid="2202666023104202232">"ले जाएं"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ख़ारिज करें"</string>
+ <string name="button_retry" msgid="4392027584153752797">"पुनः प्रयास करें"</string>
<string name="sort_name" msgid="9183560467917256779">"नाम के अनुसार"</string>
<string name="sort_date" msgid="586080032956151448">"बदलाव के दिनांक के अनुसार"</string>
<string name="sort_size" msgid="3350681319735474741">"आकार के अनुसार"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"कुछ दस्तावेज़ों को हटाने में अक्षम"</string>
<string name="share_via" msgid="8966594246261344259">"इसके द्वारा साझा करें"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फ़ाइलें कॉपी हो रही हैं"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"फाइलें ले जाई जा रही हैं"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शेष"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें कॉपी की जा रही हैं.</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें कॉपी की जा रही हैं.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें ले जाई जा रही हैं.</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें ले जाई जा रही हैं.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई जा रही हैं.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाई जा रही हैं.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"वापस लाएं"</string>
<string name="copy_preparing" msgid="3896202461003039386">"कॉपी करने की तैयारी हो रही है…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ले जाने की तैयारी हो रही है…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी नहीं बनाई जा सकती</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी नहीं बनाई जा सकती</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें नहीं ले जाई जा सकीं</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें नहीं ले जाई जा सकीं</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"विवरण देखने के लिए स्पर्श करें"</string>
<string name="retry" msgid="7564024179122207376">"पुन: प्रयास करें"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"इन फ़ाइलों की कॉपी नहीं बनाई गई: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ये फ़ाइलें नहीं ले जाई गईं: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">क्लिपबोर्ड पर <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी बनाई गई.</item>
+ <item quantity="other">क्लिपबोर्ड पर <xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलों की कॉपी बनाई गई.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"चयनित फ़ाइलों को इस स्थान में नहीं चिपकाया जा सकता."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-hr/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-hr/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-hr/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 1357fc0..78c1485 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
+ <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
<string name="title_open" msgid="4353228937663917801">"Otvori iz"</string>
<string name="title_save" msgid="2433679664882857999">"Spremi u"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Izradi mapu"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova mapa"</string>
<string name="menu_grid" msgid="6878021334497835259">"Prikaz rešetke"</string>
<string name="menu_list" msgid="7279285939892417279">"Prikaz popisa"</string>
<string name="menu_sort" msgid="7677740407158414452">"Poredano po"</string>
@@ -29,18 +30,24 @@
<string name="menu_save" msgid="2394743337684426338">"Spremi"</string>
<string name="menu_share" msgid="3075149983979628146">"Dijeli"</string>
<string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
- <string name="menu_select" msgid="8711270657353563424">"Odaberi \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Odaberi sve"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Odaberi sve"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiraj u…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Premjesti u…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Novi prozor"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Zalijepi"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaži internu pohranu"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaži SD karticu"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sakrij internu pohranu"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Sakrij SD karticu"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Pokaži veličinu datoteke"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Sakrij veličinu datoteke"</string>
+ <string name="button_select" msgid="527196987259139214">"Odaberi"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiraj"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Odabrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
- <string name="sort_name" msgid="9183560467917256779">"Po korisniku"</string>
+ <string name="button_move" msgid="2202666023104202232">"Premjesti"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Odbaci"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Pokušaj ponovo"</string>
+ <string name="sort_name" msgid="9183560467917256779">"Po nazivu"</string>
<string name="sort_date" msgid="586080032956151448">"Po datumu izmjene"</string>
<string name="sort_size" msgid="3350681319735474741">"Po veličini"</string>
<string name="drawer_open" msgid="4545466532430226949">"Prikaži korijene"</string>
@@ -59,19 +66,44 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Nije moguće izbrisati neke dokumente"</string>
<string name="share_via" msgid="8966594246261344259">"Dijeli putem"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datoteka"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Premještanje datoteka"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Još <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
<item quantity="few">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
<item quantity="other">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Premještanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="few">Premještanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="other">Premještanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="few">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="other">Brisanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Poništi"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Priprema za kopiranje…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Priprema za premještanje…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirana</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu kopirane</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije kopirano</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije premještena</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke nisu premještene</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka nije premješteno</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Dodirnite da biste vidjeli pojedinosti"</string>
<string name="retry" msgid="7564024179122207376">"Pokušaj ponovo"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Ove datoteke nisu kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Ove datoteke nisu premještene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka kopirana je u međuspremnik.</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke kopirane su u međuspremnik.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteka kopirano je u međuspremnik.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nije moguće zalijepiti odabrane datoteke na ovu lokaciju."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-hu/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-hu/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-hu/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 07c8ff1..4948116 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentumok"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fájlok"</string>
<string name="title_open" msgid="4353228937663917801">"Megnyitás innen"</string>
<string name="title_save" msgid="2433679664882857999">"Mentés ide"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Mappa létrehozása"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Új mappa"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rács"</string>
<string name="menu_list" msgid="7279285939892417279">"Lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Rendezés"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Mentés"</string>
<string name="menu_share" msgid="3075149983979628146">"Megosztás"</string>
<string name="menu_delete" msgid="8138799623850614177">"Törlés"</string>
- <string name="menu_select" msgid="8711270657353563424">"A(z) „<xliff:g id="DIRECTORY">^1</xliff:g>” mappa kiválasztása"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Az összes kijelölése"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Összes kijelölése"</string>
<string name="menu_copy" msgid="3612326052677229148">"Másolás ide…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Áthelyezés…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Új ablak"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Másolás"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Beillesztés"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Belső tárhely"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-kártya megjelenítése"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Belső tárhely elrejtése"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD-kártya elrejtése"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Fájlméret megjelenítése"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Fájlméret elrejtése"</string>
+ <string name="button_select" msgid="527196987259139214">"Kiválasztás"</string>
<string name="button_copy" msgid="8706475544635021302">"Másolás"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> kiválasztva"</string>
+ <string name="button_move" msgid="2202666023104202232">"Áthelyezés"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Elvetés"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Újrapróbálkozás"</string>
<string name="sort_name" msgid="9183560467917256779">"Név szerint"</string>
<string name="sort_date" msgid="586080032956151448">"Módosítás dátuma szerint"</string>
<string name="sort_size" msgid="3350681319735474741">"Méret szerint"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Néhány dokumentumot nem lehet törölni"</string>
<string name="share_via" msgid="8966594246261344259">"Megosztás itt:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fájlok másolása"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Fájlok áthelyezése"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> van hátra"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl másolása.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl másolása.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl áthelyezése.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl áthelyezése.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájl törlése.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájl törlése.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Visszavonás"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Felkészülés a másolásra…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Áthelyezés előkészítése…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fájlt nem sikerült átmásolni</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Nem sikerült áthelyezni <xliff:g id="COUNT_1">%1$d</xliff:g> fájlt</item>
+ <item quantity="one">Nem sikerült áthelyezni <xliff:g id="COUNT_0">%1$d</xliff:g> fájlt</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Érintse meg a részletek megtekintéséhez"</string>
<string name="retry" msgid="7564024179122207376">"Újra"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"A következő fájlokat nem sikerült átmásolni: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"A következő fájlok nem lettek áthelyezve: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fájl vágólapra másolva.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fájl vágólapra másolva.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"A kijelölt fájlokat nem lehet beilleszteni erre a helyre."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-hy-rAM/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-hy-rAM/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-hy-rAM/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 3a214a6..6dc66b0 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -17,10 +17,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Փաստաթղթեր"</string>
+ <string name="files_label" msgid="6051402950202690279">"Ֆայլեր"</string>
<string name="title_open" msgid="4353228937663917801">"Բացել այստեղից"</string>
<string name="title_save" msgid="2433679664882857999">"Պահել այստեղ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Ստեղծել պանակ"</string>
- <string name="menu_grid" msgid="6878021334497835259">"Ցանցի տեսք"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Նոր պանակ"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Ցանցի տեսքով"</string>
<string name="menu_list" msgid="7279285939892417279">"Ցուցակի տեսք"</string>
<string name="menu_sort" msgid="7677740407158414452">"Դասավորել ըստ"</string>
<string name="menu_search" msgid="3816712084502856974">"Որոնել"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Պահել"</string>
<string name="menu_share" msgid="3075149983979628146">"Համօգտագործել"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ջնջել"</string>
- <string name="menu_select" msgid="8711270657353563424">"Ընտրել «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Ընտրել բոլորը"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Ընտրել բոլորը"</string>
<string name="menu_copy" msgid="3612326052677229148">"Պատճենել…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Տեղափոխում դեպի…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Նոր պատուհան"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Պատճենել"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Տեղադրել"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ցույց տալ ներքին պահոցը"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Ցույց տալ SD քարտը"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Թաքցնել ներքին պահոցը"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Թաքցնել SD քարտը"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Ցույց տալ ֆայլի չափը"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Թաքցնել ֆայլի չափը"</string>
+ <string name="button_select" msgid="527196987259139214">"Ընտրել"</string>
<string name="button_copy" msgid="8706475544635021302">"Պատճենել"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ընտրված"</string>
+ <string name="button_move" msgid="2202666023104202232">"Տեղափոխել"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Փակել"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Փորձել նորից"</string>
<string name="sort_name" msgid="9183560467917256779">"Ըստ անվան"</string>
<string name="sort_date" msgid="586080032956151448">"Ըստ փոփոխման ամսաթվի"</string>
<string name="sort_size" msgid="3350681319735474741">"Ըստ չափի"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Անհնար է ջնջել որոշ փաստաթղթեր"</string>
<string name="share_via" msgid="8966594246261344259">"Տարածել"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Ֆայլերի պատճենում"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Ֆայլերի տեղափոխում"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Մնացել է <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի պատճենում:</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի պատճենում:</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի տեղափոխում:</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի տեղափոխում:</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի ջնջում:</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլի ջնջում:</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Հետարկել"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Պատճենման նախապատրաստում…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Տեղափոխման նախապատրաստում…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
<item quantity="other">Չհաջողվեց պատճենել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+ <item quantity="other">Չհաջողվեց տեղափոխել <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Հպեք՝ մանրամասները դիտելու համար"</string>
<string name="retry" msgid="7564024179122207376">"Կրկնել"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Հետևյալ ֆայլերը չեն պատճենվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Հետևյալ ֆայլերը չեն տեղափոխվել՝ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ պատճենվեց սեղմատախտակին:</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ պատճենվեց սեղմատախտակին:</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Հնարավոր չէ տեղադրել ընտրված ֆայլերը այս տեղադրությունում:"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-in/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-in/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-in/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 690596f..2412488 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
+ <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Buat folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Folder baru"</string>
<string name="menu_grid" msgid="6878021334497835259">"Tampilan kisi"</string>
<string name="menu_list" msgid="7279285939892417279">"Tampilan daftar"</string>
<string name="menu_sort" msgid="7677740407158414452">"Urutkan menurut"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
<string name="menu_share" msgid="3075149983979628146">"Bagikan"</string>
<string name="menu_delete" msgid="8138799623850614177">"Hapus"</string>
- <string name="menu_select" msgid="8711270657353563424">"Pilih \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Pilih Semua"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Pilih semua"</string>
<string name="menu_copy" msgid="3612326052677229148">"Salin ke…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Pindahkan ke..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Jendela baru"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Salin"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Tempel"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Tampilkan simpanan internal"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Tampilkan kartu SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sembunyikan simpanan internal"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Sembunyikan kartu SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Tampilkan ukuran file"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Sembunyikan ukuran file"</string>
+ <string name="button_select" msgid="527196987259139214">"Pilih"</string>
<string name="button_copy" msgid="8706475544635021302">"Salin"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
+ <string name="button_move" msgid="2202666023104202232">"Pindahkan"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Tutup"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Coba Lagi"</string>
<string name="sort_name" msgid="9183560467917256779">"Menurut nama"</string>
<string name="sort_date" msgid="586080032956151448">"Menurut tanggal diubah"</string>
<string name="sort_size" msgid="3350681319735474741">"Menurut ukuran"</string>
@@ -49,7 +56,7 @@
<string name="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
<string name="query_error" msgid="1222448261663503501">"Gagal mengirim kueri untuk dokumen"</string>
<string name="root_recent" msgid="4470053704320518133">"Terkini"</string>
- <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bebas"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> kosong"</string>
<string name="root_type_service" msgid="2178854894416775409">"Layanan penyimpanan"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Pintasan"</string>
<string name="root_type_device" msgid="7121342474653483538">"Perangkat"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat menghapus beberapa dokumen"</string>
<string name="share_via" msgid="8966594246261344259">"Bagikan melalui"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Menyalin file"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Memindahkan file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
<item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Memindahkan <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="one">Memindahkan <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Menghapus <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="one">Menghapus <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Urungkan"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Menyiapkan salinan..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Menyiapkan pemindahan…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Tidak dapat memindahkan <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+ <item quantity="one">Tidak dapat memindahkan <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Sentuh untuk melihat detail"</string>
<string name="retry" msgid="7564024179122207376">"Coba lagi"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Semua file ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Semua file ini tidak dipindahkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> file disalin ke papan klip.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> file disalin ke papan klip.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak dapat menempel file yang dipilih di lokasi ini."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-is-rIS/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-is-rIS/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-is-rIS/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 00818aa..d09a44b 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Skjöl"</string>
+ <string name="files_label" msgid="6051402950202690279">"Skrár"</string>
<string name="title_open" msgid="4353228937663917801">"Opna frá"</string>
<string name="title_save" msgid="2433679664882857999">"Vista í"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Búa til möppu"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Ný mappa"</string>
<string name="menu_grid" msgid="6878021334497835259">"Töfluyfirlit"</string>
<string name="menu_list" msgid="7279285939892417279">"Listayfirlit"</string>
<string name="menu_sort" msgid="7677740407158414452">"Raða eftir"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Vista"</string>
<string name="menu_share" msgid="3075149983979628146">"Deila"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eyða"</string>
- <string name="menu_select" msgid="8711270657353563424">"Velja „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Velja allt"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Velja allt"</string>
<string name="menu_copy" msgid="3612326052677229148">"Afrita í ..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Færa í…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nýr gluggi"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Afrita"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Líma"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Sýna innbyggða geymslu"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Sýna SD-kort"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Fela innbyggða geymslu"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Fela SD-kort"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Sýna skráarstærð"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Fela skráarstærð"</string>
+ <string name="button_select" msgid="527196987259139214">"Velja"</string>
<string name="button_copy" msgid="8706475544635021302">"Afrita"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valin"</string>
+ <string name="button_move" msgid="2202666023104202232">"Færa"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Hunsa"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Reyna aftur"</string>
<string name="sort_name" msgid="9183560467917256779">"Eftir heiti"</string>
<string name="sort_date" msgid="586080032956151448">"Eftir breytingadags."</string>
<string name="sort_size" msgid="3350681319735474741">"Eftir stærð"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Ekki er hægt að eyða einhverjum skjölum"</string>
<string name="share_via" msgid="8966594246261344259">"Deila í gegnum"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Afritar skrár"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Skrár færðar"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> eftir"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
<item quantity="other">Afritar <xliff:g id="COUNT_1">%1$d</xliff:g> skrár.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Færir <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
+ <item quantity="other">Færir <xliff:g id="COUNT_1">%1$d</xliff:g> skrár.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Eyðir <xliff:g id="COUNT_1">%1$d</xliff:g> skrá.</item>
+ <item quantity="other">Eyðir <xliff:g id="COUNT_1">%1$d</xliff:g> skrám.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Afturkalla"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Undirbúningur fyrir afritun…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Flutningur undirbúinn…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
<item quantity="other">Ekki var hægt að afrita <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrá</item>
+ <item quantity="other">Ekki tókst að færa <xliff:g id="COUNT_1">%1$d</xliff:g> skrár</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Snertu til að skoða nánari upplýsingar"</string>
<string name="retry" msgid="7564024179122207376">"Reyna aftur"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Þessar skrár voru ekki afritaðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Þessar skrár voru ekki færðar: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> skrá afrituð á klippiborð.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skrár afritaðar á klippiborð.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ekki er hægt að vista valdar skrár á þessum stað."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-it/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-it/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-it/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 35afe54..4824205 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenti"</string>
+ <string name="files_label" msgid="6051402950202690279">"File"</string>
<string name="title_open" msgid="4353228937663917801">"Apri da"</string>
<string name="title_save" msgid="2433679664882857999">"Salva in"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Crea cartella"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nuova cartella"</string>
<string name="menu_grid" msgid="6878021334497835259">"Visualizzazione griglia"</string>
<string name="menu_list" msgid="7279285939892417279">"Visualizzazione elenco"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordina per"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Salva"</string>
<string name="menu_share" msgid="3075149983979628146">"Condividi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Elimina"</string>
- <string name="menu_select" msgid="8711270657353563424">"Seleziona \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Seleziona tutti"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Seleziona tutto"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copia in…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Sposta in..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nuova finestra"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copia"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Incolla"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostra memoria interna"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostra scheda SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Nascondi memoria interna"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Nascondi scheda SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Mostra dimensioni file"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Nascondi dimensioni file"</string>
+ <string name="button_select" msgid="527196987259139214">"Seleziona"</string>
<string name="button_copy" msgid="8706475544635021302">"Copia"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selezionati"</string>
+ <string name="button_move" msgid="2202666023104202232">"Sposta"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ignora"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Riprova"</string>
<string name="sort_name" msgid="9183560467917256779">"Per nome"</string>
<string name="sort_date" msgid="586080032956151448">"Per data di modifica"</string>
<string name="sort_size" msgid="3350681319735474741">"Per dimensioni"</string>
@@ -54,22 +61,43 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"Scorciatoie"</string>
<string name="root_type_device" msgid="7121342474653483538">"Dispositivi"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Altre app"</string>
- <string name="empty" msgid="7858882803708117596">"Nessun articolo"</string>
+ <string name="empty" msgid="7858882803708117596">"Nessun elemento"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Impossibile aprire il file"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Impossibile eliminare alcuni documenti"</string>
<string name="share_via" msgid="8966594246261344259">"Condividi via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copia di file in corso"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Spostamento di file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> rimanenti"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Copia di <xliff:g id="COUNT_1">%1$d</xliff:g> file in corso.</item>
<item quantity="one">Copia di <xliff:g id="COUNT_0">%1$d</xliff:g> file in corso.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Spostamento di <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="one">Spostamento di <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Eliminazione di <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="one">Eliminazione di <xliff:g id="COUNT_0">%1$d</xliff:g> file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Annulla"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparazione alla copia…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparazione dello spostamento…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Impossibile copiare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="one">Impossibile copiare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Impossibile spostare <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+ <item quantity="one">Impossibile spostare <xliff:g id="COUNT_0">%1$d</xliff:g> file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Tocca per visualizzare i dettagli"</string>
<string name="retry" msgid="7564024179122207376">"Riprova"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"I seguenti file non sono stati copiati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"I seguenti file non sono stati spostati: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> file copiati negli appunti.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> file copiato negli appunti.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Impossibile incollare i file selezionati in questa posizione."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-iw/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-iw/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-iw/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 4fe0822..1a19510 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"מסמכים"</string>
+ <string name="files_label" msgid="6051402950202690279">"קבצים"</string>
<string name="title_open" msgid="4353228937663917801">"פתח מ-"</string>
<string name="title_save" msgid="2433679664882857999">"שמור ב-"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"צור תיקיה"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"תיקייה חדשה"</string>
<string name="menu_grid" msgid="6878021334497835259">"תצוגת רשת"</string>
<string name="menu_list" msgid="7279285939892417279">"תצוגת רשימה"</string>
<string name="menu_sort" msgid="7677740407158414452">"מיין לפי"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"שמור"</string>
<string name="menu_share" msgid="3075149983979628146">"שתף"</string>
<string name="menu_delete" msgid="8138799623850614177">"מחק"</string>
- <string name="menu_select" msgid="8711270657353563424">"בחר ב-\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"בחר הכל"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"בחר הכל"</string>
<string name="menu_copy" msgid="3612326052677229148">"העתק אל…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"העברה אל…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"חלון חדש"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"העתק"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"הדבק"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"הצג אחסון פנימי"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"הצג כרטיס SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"הסתר אחסון פנימי"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"הסתר כרטיס SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"הצג גודל קובץ"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"הסתר גודל קובץ"</string>
+ <string name="button_select" msgid="527196987259139214">"בחר"</string>
<string name="button_copy" msgid="8706475544635021302">"העתק"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> נבחרו"</string>
+ <string name="button_move" msgid="2202666023104202232">"העבר"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"הסר"</string>
+ <string name="button_retry" msgid="4392027584153752797">"נסה שוב"</string>
<string name="sort_name" msgid="9183560467917256779">"לפי שם"</string>
<string name="sort_date" msgid="586080032956151448">"לפי תאריך שינוי"</string>
<string name="sort_size" msgid="3350681319735474741">"לפי גודל"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"לא ניתן למחוק חלק מהמסמכים"</string>
<string name="share_via" msgid="8966594246261344259">"שתף באמצעות"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"מעתיק קבצים"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"מעביר קבצים"</string>
<string name="copy_remaining" msgid="6283790937387975095">"זמן נותר: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="two">מעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
@@ -66,14 +74,42 @@
<item quantity="other">מעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
<item quantity="one">מעתיק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="two">מעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="many">מעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="other">מעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="one">מעביר קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="two">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="many">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="other">מוחק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים.</item>
+ <item quantity="one"> מוחק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"בטל"</string>
<string name="copy_preparing" msgid="3896202461003039386">"מתכונן להעתקה..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"מתכונן להעברה…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="two">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="many">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="other">לא ניתן היה להעתיק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
<item quantity="one">לא ניתן היה להעתיק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="two">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+ <item quantity="many">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+ <item quantity="other">לא ניתן היה להעביר <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים</item>
+ <item quantity="one">לא ניתן היה להעביר קובץ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"גע כדי להציג את הפרטים"</string>
<string name="retry" msgid="7564024179122207376">"נסה שוב"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"הקבצים הבאים לא הועתקו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"הקבצים הבאים לא הועברו: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> קבצים הועתקו אל הלוח.</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> קבצים הועתקו אל הלוח.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> קבצים הועתקו אל הלוח.</item>
+ <item quantity="one">קובץ <xliff:g id="COUNT_0">%1$d</xliff:g> הועתק אל הלוח.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"לא ניתן להדביק את הקבצים הנבחרים במיקום הזה."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ja/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ja/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ja/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index dbf386b..7e356af 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ドキュメント"</string>
+ <string name="files_label" msgid="6051402950202690279">"ファイル"</string>
<string name="title_open" msgid="4353228937663917801">"次から開く:"</string>
<string name="title_save" msgid="2433679664882857999">"次に保存:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"フォルダを作成"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"新しいフォルダ"</string>
<string name="menu_grid" msgid="6878021334497835259">"グリッド表示"</string>
<string name="menu_list" msgid="7279285939892417279">"リスト表示"</string>
<string name="menu_sort" msgid="7677740407158414452">"並べ替え"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"共有"</string>
<string name="menu_delete" msgid="8138799623850614177">"削除"</string>
- <string name="menu_select" msgid="8711270657353563424">"「<xliff:g id="DIRECTORY">^1</xliff:g>」を選択"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"すべて選択"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"すべて選択"</string>
<string name="menu_copy" msgid="3612326052677229148">"コピー…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"移動..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"新しいウィンドウ"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"コピー"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼り付け"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"内部ストレージを表示"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SDカードを表示"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"内部ストレージを非表示"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SDカードを非表示"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ファイルサイズを表示"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ファイルサイズを非表示"</string>
+ <string name="button_select" msgid="527196987259139214">"選択"</string>
<string name="button_copy" msgid="8706475544635021302">"コピー"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>件選択済み"</string>
+ <string name="button_move" msgid="2202666023104202232">"移動"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"表示しない"</string>
+ <string name="button_retry" msgid="4392027584153752797">"再試行"</string>
<string name="sort_name" msgid="9183560467917256779">"名前順"</string>
<string name="sort_date" msgid="586080032956151448">"更新日順"</string>
<string name="sort_size" msgid="3350681319735474741">"サイズ順"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"一部のドキュメントを削除できません"</string>
<string name="share_via" msgid="8966594246261344259">"共有ツール"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ファイルのコピー中"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ファイルを移動中"</string>
<string name="copy_remaining" msgid="6283790937387975095">"残り<xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>個のファイルをコピーしています。</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>個のファイルをコピーしています。</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>個のファイルを移動しています。</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>個のファイルを移動しています。</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件のファイルを削除しています。</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件のファイルを削除しています。</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"元に戻す"</string>
<string name="copy_preparing" msgid="3896202461003039386">"コピーの準備をしています…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"移動の準備をしています…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ファイルをコピーできませんでした</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ファイルをコピーできませんでした</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>個のファイルを移動できませんでした</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>個のファイルを移動できませんでした</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"タップして詳細をご覧ください"</string>
<string name="retry" msgid="7564024179122207376">"再試行"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)をコピーできませんでした"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ファイル(<xliff:g id="LIST">%1$s</xliff:g>)を移動できませんでした"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>件のファイルをクリップボードにコピーしました。</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>件のファイルをクリップボードにコピーしました。</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"選択したファイルをこの場所に貼り付けることはできません。"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ka-rGE/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ka-rGE/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ka-rGE/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 85e9b4e..6e880aa 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"დოკუმენტები"</string>
+ <string name="files_label" msgid="6051402950202690279">"ფაილები"</string>
<string name="title_open" msgid="4353228937663917801">"გახსნა აქედან:"</string>
<string name="title_save" msgid="2433679664882857999">"შენახვა აქ:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"საქაღალდის შექმნა"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ახალი საქაღალდე"</string>
<string name="menu_grid" msgid="6878021334497835259">"ბადის ხედი"</string>
<string name="menu_list" msgid="7279285939892417279">"სიის ხედი"</string>
<string name="menu_sort" msgid="7677740407158414452">"სორტირება:"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"შენახვა"</string>
<string name="menu_share" msgid="3075149983979628146">"გაზიარება"</string>
<string name="menu_delete" msgid="8138799623850614177">"წაშლა"</string>
- <string name="menu_select" msgid="8711270657353563424">"„<xliff:g id="DIRECTORY">^1</xliff:g>“-ის არჩევა"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ყველას არჩევა"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ყველას არჩევა"</string>
<string name="menu_copy" msgid="3612326052677229148">"კოპირება…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"გადაადგილება..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"ახალი ფანჯარა"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"კოპირება"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ჩასმა"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"შიდა საცავის ჩვენება"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ბარათის ჩვენება"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"შიდა მეხსიერების დამალვა"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD ბარათის დამალვა"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ფაილის ზომის ჩვენება"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ფაილის ზომის დამალვა"</string>
+ <string name="button_select" msgid="527196987259139214">"არჩევა"</string>
<string name="button_copy" msgid="8706475544635021302">"კოპირება"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> მონიშნული"</string>
+ <string name="button_move" msgid="2202666023104202232">"გადაადგილება"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"დახურვა"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ისევ ცდა"</string>
<string name="sort_name" msgid="9183560467917256779">"სახელით"</string>
<string name="sort_date" msgid="586080032956151448">"ცვლილების თარიღით"</string>
<string name="sort_size" msgid="3350681319735474741">"ზომით"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ზოგიერთი დოკუმენტის წაშლა ვერ ხერხდება"</string>
<string name="share_via" msgid="8966594246261344259">"გაზიარება:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"მიმდ. ფაილების კოპირება"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ფაილების გადაადგილება"</string>
<string name="copy_remaining" msgid="6283790937387975095">"დარჩა <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">მიმდინარეობს <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის კოპირება.</item>
<item quantity="one">მიმდინარეობს <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის კოპირება.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">გადაადგილდება <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი.</item>
+ <item quantity="one">გადაადგილდება <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">მიმდინარეობს <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის წაშლა.</item>
+ <item quantity="one">მიმდინარეობს <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის წაშლა.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"დაბრუნება"</string>
<string name="copy_preparing" msgid="3896202461003039386">"მომზადება კოპირებისთვის…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"გადაადგილება მზადდება..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">ვერ მოხდა <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის კოპირება</item>
<item quantity="one">ვერ მოხდა <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის კოპირება.</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ფაილი ვერ გადაადგილდა</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"შეეხეთ მონაცემების სანახავად."</string>
<string name="retry" msgid="7564024179122207376">"ხელახლა ცდა"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ეს ფაილები არ იყო გადაწერილი: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ეს ფაილები ვერ გადაადგილდა: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">მოხდა <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის გაცვლის ბუფერში კოპირება.</item>
+ <item quantity="one">მოხდა <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის გაცვლის ბუფერში კოპირება.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ამ მდებარეობაში შერჩეული ფაილების ჩასმა შეუძლებელია."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-kk-rKZ/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-kk-rKZ/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-kk-rKZ/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index d2a6424..0d553e0 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Құжаттар"</string>
- <string name="title_open" msgid="4353228937663917801">"Келесі тармақ арқылы ашу:"</string>
- <string name="title_save" msgid="2433679664882857999">"Келесі файлға сақтау:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Қалта жасақтау"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
+ <string name="title_open" msgid="4353228937663917801">"Мынадан ашу:"</string>
+ <string name="title_save" msgid="2433679664882857999">"Сақталатын орны"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Жаңа қалта"</string>
<string name="menu_grid" msgid="6878021334497835259">"Торлы көрініс"</string>
<string name="menu_list" msgid="7279285939892417279">"Тізім көрінісі"</string>
<string name="menu_sort" msgid="7677740407158414452">"Белгіге қарай сұрыптау"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Сақтау"</string>
<string name="menu_share" msgid="3075149983979628146">"Бөлісу"</string>
<string name="menu_delete" msgid="8138799623850614177">"Жою"</string>
- <string name="menu_select" msgid="8711270657353563424">"«<xliff:g id="DIRECTORY">^1</xliff:g>» таңдау"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Барлығын таңдау"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Барлығын таңдау"</string>
<string name="menu_copy" msgid="3612326052677229148">"Көшіру орны…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Орнын ауыстыру…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Жаңа терезе"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Көшіру"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Қою"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ішкі жадты көрсету"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картасын көрсету"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ішкі жадты жасыру"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD картасын жасыру"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Файл өлшемін көрсету"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Файл өлшемін жасыру"</string>
+ <string name="button_select" msgid="527196987259139214">"Таңдау"</string>
<string name="button_copy" msgid="8706475544635021302">"Көшіру"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> таңдалды"</string>
+ <string name="button_move" msgid="2202666023104202232">"Жылжыту"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Өшіру"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Әрекетті қайталау"</string>
<string name="sort_name" msgid="9183560467917256779">"Атауы бойынша"</string>
<string name="sort_date" msgid="586080032956151448">"Өзгертілген мерзімі бойынша"</string>
<string name="sort_size" msgid="3350681319735474741">"Өлшемі бойынша"</string>
@@ -57,19 +64,40 @@
<string name="empty" msgid="7858882803708117596">"Бос"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Файлды аша алмады"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Кейбір құжаттарды жою мүмкін болмады"</string>
- <string name="share_via" msgid="8966594246261344259">"арқылы бөлісу"</string>
+ <string name="share_via" msgid="8966594246261344259">"Бөлісу"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлдарды көшіру"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Файлдар тасымалдануда"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> қалды"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды көшіру.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды көшіру.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл орын ауыстыруда.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл орын ауыстыруда.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жойылуда.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жойылуда.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Кері қайтару"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Көшіруге дайындау…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Тасымалдауға дайындалуда..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды көшіру мүмкін емес</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды көшіру мүмкін емес</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл тасымалданбады</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл тасымалданбады</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Толығырақ мәліметті көру үшін түртіңіз"</string>
<string name="retry" msgid="7564024179122207376">"Қайталау"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Мына файлдар көшірілген жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Мына файлдар тасымалданған жоқ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Аралық сақтағышқа <xliff:g id="COUNT_1">%1$d</xliff:g> файл көшірілді.</item>
+ <item quantity="one">Аралық сақтағышқа <xliff:g id="COUNT_0">%1$d</xliff:g> файл көшірілді.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Таңдалған файлдарды бұл орынға қою мүмкін емес."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-km-rKH/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-km-rKH/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-km-rKH/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index a8cd4fe..4680879 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ឯកសារ"</string>
+ <string name="files_label" msgid="6051402950202690279">"ឯកសារ"</string>
<string name="title_open" msgid="4353228937663917801">"បើកពី"</string>
<string name="title_save" msgid="2433679664882857999">"រក្សាទុកទៅ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"បង្កើតថត"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ថតថ្មី"</string>
<string name="menu_grid" msgid="6878021334497835259">"ទិដ្ឋភាពក្រឡា"</string>
<string name="menu_list" msgid="7279285939892417279">"ទិដ្ឋភាពបញ្ជី"</string>
<string name="menu_sort" msgid="7677740407158414452">"តម្រៀបតាម"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"រក្សាទុក"</string>
<string name="menu_share" msgid="3075149983979628146">"ចែករំលែក"</string>
<string name="menu_delete" msgid="8138799623850614177">"លុប"</string>
- <string name="menu_select" msgid="8711270657353563424">"ជ្រើស \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ជ្រើសរើសទាំងអស់"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ជ្រើសរើសទាំងអស់"</string>
<string name="menu_copy" msgid="3612326052677229148">"ថតចម្លងទៅ…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ផ្លាស់ទីទៅ៖"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"បង្អួចថ្មី"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ចម្លង"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"បិទភ្ជាប់"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"បង្ហាញឧបករណ៍ផ្ទុកខាងក្នុង"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"បង្ហាញកាតអេសឌី"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"លាក់ឧបករណ៍ផ្ទុកខាងក្នុង"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"លាក់កាតអេសឌី"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"បង្ហាញទំហំឯកសារ"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"លាក់ទំហំឯកសារ"</string>
+ <string name="button_select" msgid="527196987259139214">"ជ្រើស"</string>
<string name="button_copy" msgid="8706475544635021302">"ចម្លង"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"បានជ្រើស <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"ផ្លាស់ទី"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"បដិសេធ"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ព្យាយាមម្ដងទៀត"</string>
<string name="sort_name" msgid="9183560467917256779">"តាមឈ្មោះ"</string>
<string name="sort_date" msgid="586080032956151448">"តាមកាលបរិច្ឆេទបានកែប្រែ"</string>
<string name="sort_size" msgid="3350681319735474741">"តាមទំហំ"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"មិនអាចលុបឯកសារមួយចំនួន"</string>
<string name="share_via" msgid="8966594246261344259">"ចែករំលែកតាម"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"កំពុងថតចម្លងឯកសារ"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ផ្លាស់ទីឯកសារ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"នៅសល់ <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">កំពុងថតចម្លងឯកសារចំនួន <xliff:g id="COUNT_1">%1$d</xliff:g> ។</item>
<item quantity="one">កំពុងថតចម្លងឯកសារចំនួន <xliff:g id="COUNT_0">%1$d</xliff:g> ។</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">កំពុងផ្លាស់ទីឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g>។</item>
+ <item quantity="one">កំពុងផ្លាស់ទីឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g>។</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">កំពុងលុបឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">កំពុងលុបឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"មិនធ្វើវិញ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"កំពុងរៀបចំចម្លង…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"កំពុងរៀបចំផ្លាស់ទី…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">មិនអាចចម្លងឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="one">មិនអាចចម្លងឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">មិនអាចផ្លាស់ទីឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">មិនអាចផ្លាស់ទីឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"ប៉ះ ដើម្បីមើលព័ត៌មានលម្អិត"</string>
<string name="retry" msgid="7564024179122207376">"ព្យាយាមម្ដងទៀត"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ឯកសារទាំងនេះមិនបានចម្លងទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ឯកសារទាំងនេះមិនអាចផ្លាស់ទីបានទេ៖ <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">បានចម្លងឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ទៅតម្បៀតខ្ទាស់។</item>
+ <item quantity="one">បានចម្លងឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ទៅតម្បៀតខ្ទាស់។</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"មិនអាចបិទភ្ជាប់ឯកសារដែលបានជ្រើសនៅក្នុងទីតាំងនេះបានទេ។"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-kn-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-kn-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-kn-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 2cb4d8e..7d5770a 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ಡಾಕ್ಯುಮೆಂಟ್ಗಳು"</string>
+ <string name="files_label" msgid="6051402950202690279">"ಫೈಲ್ಗಳು"</string>
<string name="title_open" msgid="4353228937663917801">"ಇದರ ಮೂಲಕ ತೆರೆಯಿರಿ"</string>
- <string name="title_save" msgid="2433679664882857999">"ಇದಕ್ಕೆ ಉಳಿಸಿ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ಫೋಲ್ಡರ್ ರಚಿಸು"</string>
+ <string name="title_save" msgid="2433679664882857999">"ಇವುಗಳಲ್ಲಿ ಉಳಿಸಿ"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ಹೊಸ ಫೋಲ್ಡರ್"</string>
<string name="menu_grid" msgid="6878021334497835259">"ಗ್ರಿಡ್ ವೀಕ್ಷಣೆ"</string>
<string name="menu_list" msgid="7279285939892417279">"ಪಟ್ಟಿ ವೀಕ್ಷಣೆ"</string>
<string name="menu_sort" msgid="7677740407158414452">"ಈ ಪ್ರಕಾರ ವಿಂಗಡಿಸು"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"ಉಳಿಸು"</string>
<string name="menu_share" msgid="3075149983979628146">"ಹಂಚು"</string>
<string name="menu_delete" msgid="8138799623850614177">"ಅಳಿಸು"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ಎಲ್ಲವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ಎಲ್ಲವನ್ನೂ ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="menu_copy" msgid="3612326052677229148">"ಇದಕ್ಕೆ ನಕಲಿಸಿ…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ಇದಕ್ಕೆ ಸರಿಸು…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"ಹೊಸ ವಿಂಡೋ"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ನಕಲಿಸು"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ಅಂಟಿಸು"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯನ್ನು ತೋರಿಸು"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ಕಾಡ್ ಅನ್ನು ತೋರಿಸು"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆಯನ್ನು ಮರೆಮಾಡಿ"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD ಕಾರ್ಡ್ ಅನ್ನು ಮರೆಮಾಡಿ"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ಫೈಲ್ ಗಾತ್ರವನ್ನು ತೋರಿಸು"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ಫೈಲ್ ಗಾತ್ರವನ್ನು ಮರೆಮಾಡಿ"</string>
+ <string name="button_select" msgid="527196987259139214">"ಆಯ್ಕೆಮಾಡು"</string>
<string name="button_copy" msgid="8706475544635021302">"ನಕಲಿಸು"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="button_move" msgid="2202666023104202232">"ಸರಿಸು"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="sort_name" msgid="9183560467917256779">"ಹೆಸರಿನ ಪ್ರಕಾರ"</string>
<string name="sort_date" msgid="586080032956151448">"ಮಾರ್ಪಡಿಸಿರುವ ದಿನಾಂಕದ ಪ್ರಕಾರ"</string>
<string name="sort_size" msgid="3350681319735474741">"ಗಾತ್ರದ ಪ್ರಕಾರ"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ಕೆಲವು ಡಾಕ್ಯುಮೆಂಟ್ಗಳನ್ನು ಅಳಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
<string name="share_via" msgid="8966594246261344259">"ಈ ಮೂಲಕ ಹಂಚಿಕೊಳ್ಳಿ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ಫೈಲ್ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ಉಳಿದಿದೆ"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ.</item>
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲಿಸಲಾಗುತ್ತಿದೆ.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗುತ್ತಿದೆ.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"ರದ್ದುಗೊಳಿಸಿ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"ನಕಲಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ಸರಿಸಲು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲು ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲು ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗಲಿಲ್ಲ</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string>
<string name="retry" msgid="7564024179122207376">"ಮರುಪ್ರಯತ್ನಿಸು"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ಈ ಫೈಲ್ಗಳನ್ನು ನಕಲು ಮಾಡಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ಈ ಫೈಲ್ಗಳನ್ನು ಸರಿಸಲಾಗಿಲ್ಲ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲಿಸಲಾಗಿದೆ.</item>
+ <item quantity="other">ಕ್ಲಿಪ್ಬೋರ್ಡ್ಗೆ <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ನಕಲಿಸಲಾಗಿದೆ.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ಈ ಸ್ಥಳದಲ್ಲಿ ಆಯ್ಕೆಮಾಡಿದ ಫೈಲ್ಗಳನ್ನು ಅಂಟಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ko/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ko/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ko/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 3e6facf..3032eed 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"문서"</string>
+ <string name="files_label" msgid="6051402950202690279">"파일"</string>
<string name="title_open" msgid="4353228937663917801">"열기:"</string>
<string name="title_save" msgid="2433679664882857999">"저장 위치:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"폴더 만들기"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"새 폴더"</string>
<string name="menu_grid" msgid="6878021334497835259">"바둑판식 보기"</string>
<string name="menu_list" msgid="7279285939892417279">"목록 보기"</string>
<string name="menu_sort" msgid="7677740407158414452">"정렬 기준"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"저장"</string>
<string name="menu_share" msgid="3075149983979628146">"공유"</string>
<string name="menu_delete" msgid="8138799623850614177">"삭제"</string>
- <string name="menu_select" msgid="8711270657353563424">"\'<xliff:g id="DIRECTORY">^1</xliff:g>\' 선택"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"모두 선택"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"모두 선택"</string>
<string name="menu_copy" msgid="3612326052677229148">"복사…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"이동…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"새 창"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"복사"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"붙여넣기"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"내부 저장소 표시"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD 카드 표시"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"내부 저장소 숨기기"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD 카드 숨기기"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"파일 크기 표시"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"파일 크기 숨기기"</string>
+ <string name="button_select" msgid="527196987259139214">"선택"</string>
<string name="button_copy" msgid="8706475544635021302">"복사"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g>개 선택됨"</string>
+ <string name="button_move" msgid="2202666023104202232">"이동"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"닫기"</string>
+ <string name="button_retry" msgid="4392027584153752797">"다시 시도"</string>
<string name="sort_name" msgid="9183560467917256779">"이름순"</string>
<string name="sort_date" msgid="586080032956151448">"수정된 날짜순"</string>
<string name="sort_size" msgid="3350681319735474741">"크기순"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"일부 문서를 삭제할 수 없음"</string>
<string name="share_via" msgid="8966594246261344259">"공유 방법"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"파일 복사 중"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"파일 이동"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> 남음"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 복사합니다.</item>
<item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 복사합니다.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개 이동</item>
+ <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개 이동</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개 삭제</item>
+ <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개 삭제</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"실행취소"</string>
<string name="copy_preparing" msgid="3896202461003039386">"사본 준비 중…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"이동 준비 중…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
<item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 복사할 수 없습니다.</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>개 파일을 이동할 수 없습니다.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g>개 파일을 이동할 수 없습니다.</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"세부정보를 보려면 터치하세요."</string>
<string name="retry" msgid="7564024179122207376">"다시 시도"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"다음 파일이 복사되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"다음 파일이 이동되지 않았습니다. <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 클립보드에 복사함</item>
+ <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 클립보드에 복사함</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"선택한 파일을 이 위치에 붙여넣을 수 없습니다."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ky-rKG/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ky-rKG/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ky-rKG/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 8f5bb25..14a25bc 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документтер"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файлдар"</string>
<string name="title_open" msgid="4353228937663917801">"Кийинкиден ачуу:"</string>
<string name="title_save" msgid="2433679664882857999">"Кийинкиге сактоо:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Папка түзүү"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Жаңы куржун"</string>
<string name="menu_grid" msgid="6878021334497835259">"Тор көрүнүшү"</string>
<string name="menu_list" msgid="7279285939892417279">"Тизмек көрүнүшү"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ылгоо"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Сактоо"</string>
<string name="menu_share" msgid="3075149983979628146">"Бөлүшүү"</string>
<string name="menu_delete" msgid="8138799623850614177">"Өчүрүү"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" тандоо"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Бардыгын тандоо"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Бардыгын тандоо"</string>
<string name="menu_copy" msgid="3612326052677229148">"Төмөнкүгө көчүрүү…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Төмөнкүгө жылдыруу..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Жаңы терезе"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Көчүрүү"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Чаптоо"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ички сактагычты көрсөтүү"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картаны көрсөтүү"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ички эстутумду жашыруу"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD картаны жашыруу"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Файл өлчөмүн көрсөтүү"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Файл өлчөмүн жашыруу"</string>
+ <string name="button_select" msgid="527196987259139214">"Тандоо"</string>
<string name="button_copy" msgid="8706475544635021302">"Көчүрүү"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> тандалды"</string>
+ <string name="button_move" msgid="2202666023104202232">"Жылдыруу"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Этибарга албоо"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Дагы аракет кылыңыз"</string>
<string name="sort_name" msgid="9183560467917256779">"Аты боюнча"</string>
<string name="sort_date" msgid="586080032956151448">"Өзгөртүлгөн күнү боюнча"</string>
<string name="sort_size" msgid="3350681319735474741">"Өлчөмү боюнча"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Кээ бир документтерди өчүрүү кыйрады"</string>
<string name="share_via" msgid="8966594246261344259">"Кийинки аркылуу бөлүшүү:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлдар көчүрүлүүдө"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Файлдар жылдырылууда…"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> калды"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлүүдө.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлүүдө.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файл жылдырылууда.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл жылдырылууда.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынууда.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынууда.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Артка кайтаруу"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Көчүрүүгө даярдалууда…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Жылдырууга даярдалууда…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл көчүрүлбөй койду</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл көчүрүлбөй койду</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файл жылдырылбай калды</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жылдырылбай калды</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Чоо-жайын билүү үчүн тийип коюңуз"</string>
<string name="retry" msgid="7564024179122207376">"Дагы аракет кылуу"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Төмөнкү файлдар көчүрүлгөн жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Төмөнкү файлдар жылдырылган жок: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл буферге көчүрүлдү.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл буферге көчүрүлдү.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Тандалган файлдарды бул жерге чаптоого мүмкүн эмес."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-lo-rLA/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-lo-rLA/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-lo-rLA/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index f57071b..2a680bf 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ເອກະສານ"</string>
+ <string name="files_label" msgid="6051402950202690279">"ໄຟລ໌"</string>
<string name="title_open" msgid="4353228937663917801">"ເປີດຈາກ"</string>
<string name="title_save" msgid="2433679664882857999">"ບັນທຶກໄປທີ່"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ສ້າງໂຟນເດີ"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ໂຟລເດີໃໝ່"</string>
<string name="menu_grid" msgid="6878021334497835259">"ມຸມມອງແບບຊ່ອງ"</string>
<string name="menu_list" msgid="7279285939892417279">"ມຸມມອງແບບລາຍຊື່"</string>
<string name="menu_sort" msgid="7677740407158414452">"ຮຽງລຳດັບຕາມ"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"ບັນທຶກ"</string>
<string name="menu_share" msgid="3075149983979628146">"ແບ່ງປັນ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ລຶບ"</string>
- <string name="menu_select" msgid="8711270657353563424">"ເລືອກ \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ເລືອກທັງຫມົດ"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ເລືອກທັງຫມົດ"</string>
<string name="menu_copy" msgid="3612326052677229148">"ອັດສຳເນົາໃສ່…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ຍ້າຍໄປໃສ່..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"ໜ້າຈໍໃໝ່"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ສຳເນົາ"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ວາງໃສ່"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ສະແດງໂຕເກັບຂໍ້ມູນພາຍໃນ"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"ສະແດງ SD Card"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ເຊື່ອງໂຕເກັບຂໍ້ມູນພາຍໃນ"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"ເຊື່ອງ SD Card"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ສະແດງຂະໜາດໄຟລ໌"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ເຊື່ອງຂະຫນາດໄຟລ໌"</string>
+ <string name="button_select" msgid="527196987259139214">"ເລືອກ"</string>
<string name="button_copy" msgid="8706475544635021302">"ສຳເນົາ"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"ເລືອກແລ້ວ <xliff:g id="COUNT">%1$d</xliff:g> ລາຍການ"</string>
+ <string name="button_move" msgid="2202666023104202232">"ຍ້າຍ"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ປິດໄວ້"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ລອງໃໝ່ອີກ"</string>
<string name="sort_name" msgid="9183560467917256779">"ຕາມຊື່"</string>
<string name="sort_date" msgid="586080032956151448">"ຕາມວັນທີທີ່ແກ້ໄຂ"</string>
<string name="sort_size" msgid="3350681319735474741">"ຕາມຂະໜາດ"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ບໍ່ສາມາດລຶບບາງເອກະສານໄດ້"</string>
<string name="share_via" msgid="8966594246261344259">"ແບ່ງປັນຜ່ານ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ກຳລັງອັດສຳເນົາໄຟລ໌"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ກຳລັງຍ້າຍໄຟລ໌"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ຍັງເຫຼືອຢູ່"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">ກຳລັງອັດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌.</item>
<item quantity="one">ກຳລັງອັດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">ກຳລັງຍ້າຍ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌.</item>
+ <item quantity="one">ກຳລັງຍ້າຍ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">ກຳລັງລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌.</item>
+ <item quantity="one">ກຳລັງລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"ບໍ່ເຮັດ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"ກຳລັງກຽມອັດສຳເນົາ…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ກຳລັງກະກຽມຍ້າຍ…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">ບໍ່ສາມາດອັດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
<item quantity="one">ບໍ່ສາມາດອັດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໄດ້</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">ບໍ່ສາມາດຍ້າຍໄດ້ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌</item>
+ <item quantity="one">ບໍ່ສາມາດຍ້າຍໄດ້ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"ສຳພັດເພື່ອເບິ່ງລາຍລະອຽດ"</string>
<string name="retry" msgid="7564024179122207376">"ລອງໃໝ່"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ຖືກອັດສຳເນົາ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ໄຟລ໌ເຫຼົ່ານີ້ບໍ່ຖືກຍ້າຍ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">ອັດສຳເນົາ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ໃສ່ຄລິບບອດແລ້ວ.</item>
+ <item quantity="one">ອັດສຳເນົາ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ໃສ່ຄລິບບອດແລ້ວ.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ບໍ່ສາມາດແປະໄຟລ໌ເລືອກໄວ້ຢູ່ໃນທີ່ຕັ້ງນີ້ໄດ້."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-lt/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-lt/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-lt/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 66f5387..8105846 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumentai"</string>
+ <string name="files_label" msgid="6051402950202690279">"Failai"</string>
<string name="title_open" msgid="4353228937663917801">"Atidaryti iš"</string>
<string name="title_save" msgid="2433679664882857999">"Išsaugoti į"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Kurti aplanką"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Naujas aplankas"</string>
<string name="menu_grid" msgid="6878021334497835259">"Tinklelio rodinys"</string>
<string name="menu_list" msgid="7279285939892417279">"Sąrašo rodinys"</string>
<string name="menu_sort" msgid="7677740407158414452">"Rūšiuoti pagal"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Išsaugoti"</string>
<string name="menu_share" msgid="3075149983979628146">"Bendrinti"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ištrinti"</string>
- <string name="menu_select" msgid="8711270657353563424">"Pasirinkti katalogą „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Pasirinkti viską"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Pasirinkti viską"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopijuoti į..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Perkelti į…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Naujas langas"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopijuoti"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Įklijuoti"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Rodyti vidinę atmintį"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Rodyti SD kortelę"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Slėpti vidinę atmintį"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Slėpti SD kortelę"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Rodyti failo dydį"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Slėpti failo dydį"</string>
+ <string name="button_select" msgid="527196987259139214">"Pasirinkti"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopijuoti"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Pasirinkta: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Perkelti"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Atsisakyti"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Bandyti dar kartą"</string>
<string name="sort_name" msgid="9183560467917256779">"Pagal pavadinimą"</string>
<string name="sort_date" msgid="586080032956151448">"Pagal keitimo datą"</string>
<string name="sort_size" msgid="3350681319735474741">"Pagal dydį"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Nepavyko ištrinti kai kurių dokumentų"</string>
<string name="share_via" msgid="8966594246261344259">"Bendrinti naudojant"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopijuojami failai"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Perkeliami failai"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Liko: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopijuojamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
@@ -66,14 +74,42 @@
<item quantity="many">Kopijuojama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
<item quantity="other">Kopijuojama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Perkeliamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
+ <item quantity="few">Perkeliami <xliff:g id="COUNT_1">%1$d</xliff:g> failai.</item>
+ <item quantity="many">Perkeliama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
+ <item quantity="other">Perkeliama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Trinamas <xliff:g id="COUNT_1">%1$d</xliff:g> failas.</item>
+ <item quantity="few">Trinami <xliff:g id="COUNT_1">%1$d</xliff:g> failai.</item>
+ <item quantity="many">Trinama <xliff:g id="COUNT_1">%1$d</xliff:g> failo.</item>
+ <item quantity="other">Trinama <xliff:g id="COUNT_1">%1$d</xliff:g> failų.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Anuliuoti"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Ruošiamasi kopijuoti…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Ruošiamasi perkelti…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="few">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
<item quantity="many">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
<item quantity="other">Nepavyko nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+ <item quantity="few">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+ <item quantity="many">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failo</item>
+ <item quantity="other">Nepavyko perkelti <xliff:g id="COUNT_1">%1$d</xliff:g> failų</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Palieskite, kad peržiūr. išsamią informaciją"</string>
<string name="retry" msgid="7564024179122207376">"Bandyti dar kartą"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Šie failai nenukopijuoti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie failai nebuvo perkelti: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Nukopijuotas <xliff:g id="COUNT_1">%1$d</xliff:g> failas į iškarpinę.</item>
+ <item quantity="few">Nukopijuoti <xliff:g id="COUNT_1">%1$d</xliff:g> failai į iškarpinę.</item>
+ <item quantity="many">Nukopijuota <xliff:g id="COUNT_1">%1$d</xliff:g> failo į iškarpinę.</item>
+ <item quantity="other">Nukopijuota <xliff:g id="COUNT_1">%1$d</xliff:g> failų į iškarpinę.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nepavyko įklijuoti pasirinktų failų šioje vietoje."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-lv/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-lv/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-lv/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 4e254a1..48715e6 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
+ <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="title_open" msgid="4353228937663917801">"Atvēršana no:"</string>
<string name="title_save" msgid="2433679664882857999">"Saglabāšana:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Izveidot mapi"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Jauna mape"</string>
<string name="menu_grid" msgid="6878021334497835259">"Režģis"</string>
<string name="menu_list" msgid="7279285939892417279">"Saraksts"</string>
<string name="menu_sort" msgid="7677740407158414452">"Kārtot pēc"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Saglabāt"</string>
<string name="menu_share" msgid="3075149983979628146">"Kopīgot"</string>
<string name="menu_delete" msgid="8138799623850614177">"Dzēst"</string>
- <string name="menu_select" msgid="8711270657353563424">"Atlasīt “<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Atlasīt visus"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Atlasīt visus"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopēt…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Pārvietot uz…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Jauns logs"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopēt"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Ielīmēt"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Rādīt iekšējo atmiņu"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Rādīt SD karti"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Paslēpt iekšējo atmiņu"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Paslēpt SD karti"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Rādīt failu lielumu"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Paslēpt failu lielumu"</string>
+ <string name="button_select" msgid="527196987259139214">"Atlasīt"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopēt"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Atlasīts: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Pārvietot"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Noraidīt"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Mēģināt vēlreiz"</string>
<string name="sort_name" msgid="9183560467917256779">"Pēc nosaukuma"</string>
<string name="sort_date" msgid="586080032956151448">"Pēc pārveidošanas datuma"</string>
<string name="sort_size" msgid="3350681319735474741">"Pēc lieluma"</string>
@@ -59,19 +66,44 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Nevar dzēst dažus dokumentus."</string>
<string name="share_via" msgid="8966594246261344259">"Kopīgot, izmantojot"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Notiek failu kopēšana"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Failu pārvietošana"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Atlikušais laiks: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
<item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila kopēšana.</item>
<item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu kopēšana.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu pārvietošana.</item>
+ <item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila pārvietošana.</item>
+ <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu pārvietošana.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="zero">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu dzēšana.</item>
+ <item quantity="one">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> faila dzēšana.</item>
+ <item quantity="other">Notiek <xliff:g id="COUNT_1">%1$d</xliff:g> failu dzēšana.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Atsaukt"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Gatavošanās kopēšanai…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Sagatavošana pārvietošanai…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="zero">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
<item quantity="one">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failu</item>
<item quantity="other">Nevarēja nokopēt <xliff:g id="COUNT_1">%1$d</xliff:g> failus</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="zero">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
+ <item quantity="one">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failu.</item>
+ <item quantity="other">Nevarēja pārvietot <xliff:g id="COUNT_1">%1$d</xliff:g> failus.</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Pieskarieties, lai skatītu informāciju"</string>
<string name="retry" msgid="7564024179122207376">"Mēģināt vēlreiz"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Netika nokopēti šādi faili: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Šie faili netika pārvietoti: <xliff:g id="LIST">%1$s</xliff:g>."</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> faili tika kopēti starpliktuvē.</item>
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> fails tika kopēts starpliktuvē.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> faili tika kopēti starpliktuvē.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Atlasītos failus šeit nevar ielīmēt."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-mk-rMK/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-mk-rMK/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-mk-rMK/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index cfe7947..950a9b1 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
+ <string name="files_label" msgid="6051402950202690279">"Датотеки"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори од"</string>
<string name="title_save" msgid="2433679664882857999">"Зачувај во"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Создади папка"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Нова папка"</string>
<string name="menu_grid" msgid="6878021334497835259">"Приказ на мрежа"</string>
<string name="menu_list" msgid="7279285939892417279">"Приказ на список"</string>
<string name="menu_sort" msgid="7677740407158414452">"Подреди по"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Зачувај"</string>
<string name="menu_share" msgid="3075149983979628146">"Сподели"</string>
<string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
- <string name="menu_select" msgid="8711270657353563424">"Одберете „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Избери ги сите"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Избери ги сите"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копирај во…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Премести во..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Нов прозорец"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копирај"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Залепи"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Прикажи внатрешна мемор."</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Прикажи СД-картичка"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Скриј внатрешна меморија"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Сoкриј СД-картичка"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Прикажи целосна големина"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Сокриј целосна големина"</string>
+ <string name="button_select" msgid="527196987259139214">"Избери"</string>
<string name="button_copy" msgid="8706475544635021302">"Копирај"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Избрани се <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Премести"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Отфрли"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Обиди се пак"</string>
<string name="sort_name" msgid="9183560467917256779">"По име"</string>
<string name="sort_date" msgid="586080032956151448">"Изменети по датум"</string>
<string name="sort_size" msgid="3350681319735474741">"По големина"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Некои документи не може да се избришат"</string>
<string name="share_via" msgid="8966594246261344259">"Сподели преку"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Се копираат датотеки"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Датотеките се преместуваат"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Уште <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Се копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
<item quantity="other">Се копираат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Се преместува <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ <item quantity="other">Се преместуваат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Се брише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ <item quantity="other">Се бришат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Врати"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Се подготвува за копирање…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Се подготвува за преместување…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Не може да копира <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
<item quantity="other">Не може да копираат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Не можеше да се премести <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+ <item quantity="other">Не можеше да се преместат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Допрете за да ги погледнете деталите"</string>
<string name="retry" msgid="7564024179122207376">"Обидете се повторно"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Датотекиве не се ископирани: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Овие датотеки не се преместија: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Копирана е <xliff:g id="COUNT_1">%1$d</xliff:g> датотека на таблата со исечоци.</item>
+ <item quantity="other">Копирани се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки на таблата со исечоци.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не може да ги залепи избраните датотеки на локацијава."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ml-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ml-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ml-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index a5b5bbd..32411b2 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"പ്രമാണങ്ങൾ"</string>
+ <string name="files_label" msgid="6051402950202690279">"ഫയലുകൾ"</string>
<string name="title_open" msgid="4353228937663917801">"ഇതിൽ നിന്നും തുറക്കുക"</string>
<string name="title_save" msgid="2433679664882857999">"ഇതില് സംരക്ഷിക്കുക"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ഫോൾഡർ സൃഷ്ടിക്കുക"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"പുതിയ ഫോൾഡർ"</string>
<string name="menu_grid" msgid="6878021334497835259">"ഗ്രിഡ് കാഴ്ച"</string>
<string name="menu_list" msgid="7279285939892417279">"ലിസ്റ്റ് കാഴ്ച"</string>
<string name="menu_sort" msgid="7677740407158414452">"ഇപ്രകാരം അടുക്കുക"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"സംരക്ഷിക്കുക"</string>
<string name="menu_share" msgid="3075149983979628146">"പങ്കിടുക"</string>
<string name="menu_delete" msgid="8138799623850614177">"ഇല്ലാതാക്കുക"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" തിരഞ്ഞെടുക്കുക"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"എല്ലാം തിരഞ്ഞെടുക്കുക"</string>
<string name="menu_copy" msgid="3612326052677229148">"ഇതിൽ പകർത്തുക…"</string>
- <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ആന്തരിക സംഭരണം കാണിക്കുക"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ഇതിലേക്ക് നീക്കുക..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"പുതിയ വിന്ഡോ"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"പകര്ത്തുക"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ഒട്ടിക്കുക"</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ആന്തരിക സ്റ്റോറേജ് കാണിക്കുക"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD കാർഡ് കാണിക്കുക"</string>
- <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ആന്തരിക സംഭരണം മറയ്ക്കുക"</string>
+ <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ആന്തരിക സ്റ്റോറേജ് മറയ്ക്കുക"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD കാർഡ് മറയ്ക്കുക"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ഫയൽ വലുപ്പം കാണിക്കുക"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ഫയൽ വലുപ്പം മറയ്ക്കുക"</string>
+ <string name="button_select" msgid="527196987259139214">"തിരഞ്ഞെടുക്കുക"</string>
<string name="button_copy" msgid="8706475544635021302">"പകര്ത്തുക"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> തിരഞ്ഞെടുത്തു"</string>
+ <string name="button_move" msgid="2202666023104202232">"നീക്കുക"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ഡിസ്മിസ് ചെയ്യുക"</string>
+ <string name="button_retry" msgid="4392027584153752797">"വീണ്ടും ശ്രമിക്കുക"</string>
<string name="sort_name" msgid="9183560467917256779">"പേര് പ്രകാരം"</string>
<string name="sort_date" msgid="586080032956151448">"പരിഷ്ക്കരിച്ച തീയതി പ്രകാരം"</string>
<string name="sort_size" msgid="3350681319735474741">"വലുപ്പം പ്രകാരം"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ചില പ്രമാണങ്ങൾ ഇല്ലാതാക്കാനായില്ല"</string>
<string name="share_via" msgid="8966594246261344259">"ഇതുവഴി പങ്കിടുക"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ഫയലുകൾ പകർത്തുന്നു"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ഫയലുകൾ നീക്കുന്നു"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ശേഷിക്കുന്നു"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ പകർത്തുന്നു.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ പകർത്തുന്നു.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ നീക്കുന്നു.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ നീക്കുന്നു.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ഇല്ലാതാക്കുന്നു.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ഇല്ലാതാക്കുന്നു.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"പഴയപടിയാക്കുക"</string>
<string name="copy_preparing" msgid="3896202461003039386">"പകർപ്പിനായി തയ്യാറെടുക്കുന്നു…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"നീക്കാനൊരുങ്ങുന്നു…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ പകർത്താനായില്ല</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ പകർത്താനായില്ല</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ നീക്കാനായില്ല</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ നീക്കാനായില്ല</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"വിശദാംശങ്ങൾ കാണാൻ സ്പർശിക്കുക"</string>
<string name="retry" msgid="7564024179122207376">"വീണ്ടും ശ്രമിക്കുക"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ഈ ഫയലുകൾ പകർത്താനായില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ഈ ഫയലുകളെ നീക്കിയില്ല: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തി.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തി.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"തിരഞ്ഞെടുത്ത ഫയലുകൾ ഈ ലൊക്കേഷനിൽ ഒട്ടിക്കാനാകുന്നില്ല."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-mn-rMN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-mn-rMN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-mn-rMN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 1f1218f..0c5c72d 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документүүд"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файл"</string>
<string name="title_open" msgid="4353228937663917801">"Нээх"</string>
<string name="title_save" msgid="2433679664882857999">"Хадгалах"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Фолдер үүсгэх"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Шинэ фолдер"</string>
<string name="menu_grid" msgid="6878021334497835259">"Эгнүүлж харах"</string>
<string name="menu_list" msgid="7279285939892417279">"Жагсааж харах"</string>
<string name="menu_sort" msgid="7677740407158414452">"Эрэмбэлэх"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Хадгалах"</string>
<string name="menu_share" msgid="3075149983979628146">"Хуваалцах"</string>
<string name="menu_delete" msgid="8138799623850614177">"Устгах"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\"-г сонгох"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Бүгдийг сонгох"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Бүгдийг сонгох"</string>
<string name="menu_copy" msgid="3612326052677229148">"...руу хуулах"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Байршуулах газар"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Шинэ цонх"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Хуулах"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Буулгах"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Дотоод санг харуулах"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD картыг харуулах"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Дотоод санг нуух"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD картыг нуух"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Файлын хэмжээг харуулах"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Файлын хэмжээг нуух"</string>
+ <string name="button_select" msgid="527196987259139214">"Сонгох"</string>
<string name="button_copy" msgid="8706475544635021302">"Хуулах"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> сонгогдсон"</string>
+ <string name="button_move" msgid="2202666023104202232">"Зөөх"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Алгасах"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Дахин оролдоно уу"</string>
<string name="sort_name" msgid="9183560467917256779">"Нэрээр"</string>
<string name="sort_date" msgid="586080032956151448">"Өөрчлөгдсөн огноогоор"</string>
<string name="sort_size" msgid="3350681319735474741">"Хэмжээгээр"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Зарим документуудыг устгах боломжгүй"</string>
<string name="share_via" msgid="8966594246261344259">"Дараахаар дамжуулан хуваалцах"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Файлуудыг хуулж байна"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Файлыг зөөвөрлөж байна"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> үлдсэн"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлуудыг хуулж байна.</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл хуулж байна.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файл зөөж байна.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файл зөөж байна.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлыг устгаж байна.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлыг устгаж байна.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Буцаах"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Хуулбарлахад бэлтгэж байна..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Зөөвөрлөхөд бэлтгэж байна..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг хуулбарлаж чадсангүй</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг хуулбарлаж чадсангүй</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг зөөвөрлөх боломжгүй байна</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг зөөвөрлөх боломжгүй байна</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Дэлгэрэнгүй мэдээллийг үзэхийн тулд хүрнэ үү."</string>
<string name="retry" msgid="7564024179122207376">"Дахин оролдох"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Дараах файлуудыг хуулаагүй: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Эдгээр файлыг зөөвөрлөөгүй байна: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> материалыг түр санах ой руу хуулсан.</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> материалыг түр санах ой руу хуулсан.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Энэ байршилд сонгосон файлыг байршуулах боломжгүй байна."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-mr-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-mr-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-mr-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index b7b1f23..15c1291 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"दस्तऐवज"</string>
+ <string name="files_label" msgid="6051402950202690279">"फायली"</string>
<string name="title_open" msgid="4353228937663917801">"वरून उघडा"</string>
<string name="title_save" msgid="2433679664882857999">"येथे जतन करा"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"फोल्डर तयार करा"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"नवीन फोल्डर"</string>
<string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
<string name="menu_list" msgid="7279285939892417279">"सूची"</string>
<string name="menu_sort" msgid="7677740407158414452">"नुसार क्रमवारी लावा"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"जतन करा"</string>
<string name="menu_share" msgid="3075149983979628146">"सामायिक करा"</string>
<string name="menu_delete" msgid="8138799623850614177">"हटवा"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" निवडा"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"सर्व निवडा"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"सर्व निवडा"</string>
<string name="menu_copy" msgid="3612326052677229148">"यावर कॉपी करा…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"यावर हलवा…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"नवीन विंडो"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"कॉपी करा"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"पेस्ट करा"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"अंतर्गत संचयन दर्शवा"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड दर्शवा"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"अंतर्गत संचयन लपवा"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD कार्ड लपवा"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"फाईल आकार दर्शवा"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"फाईल आकार लपवा"</string>
+ <string name="button_select" msgid="527196987259139214">"निवडा"</string>
<string name="button_copy" msgid="8706475544635021302">"कॉपी करा"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> निवडले"</string>
+ <string name="button_move" msgid="2202666023104202232">"हलवा"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"डिसमिस करा"</string>
+ <string name="button_retry" msgid="4392027584153752797">"पुन्हा प्रयत्न करा"</string>
<string name="sort_name" msgid="9183560467917256779">"नावानुसार"</string>
<string name="sort_date" msgid="586080032956151448">"सुधारित केलेल्या तारखेनुसार"</string>
<string name="sort_size" msgid="3350681319735474741">"आकारानुसार"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"काही दस्तऐवज हटविण्यात अक्षम"</string>
<string name="share_via" msgid="8966594246261344259">"द्वारे सामायिक करा"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फायली कॉपी करीत आहे"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"फायली हलविणे"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> शिल्लक"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी करीत आहे.</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी करीत आहे.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हलवित आहे.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हलवित आहे.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हटवित आहे.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हटवित आहे.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"पूर्ववत करा"</string>
<string name="copy_preparing" msgid="3896202461003039386">"कॉपी करण्यासाठी तयार करीत आहे…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"हलविण्यास तयार होत आहे…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी करू शकलो नाही</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी करू शकलो नाही</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हलविणे शक्य झाले नाही</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फायली हलविणे शक्य झाले नाही</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"तपशील पाहण्यासाठी स्पर्श करा"</string>
<string name="retry" msgid="7564024179122207376">"पुन्हा प्रयत्न करा"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"या फायली कॉपी झाल्या नाहीत: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"या फायली हलविल्या नव्हत्या: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">क्लिपबोर्डवर <xliff:g id="COUNT_1">%1$d</xliff:g> फाईल कॉपी केली.</item>
+ <item quantity="other">क्लिपबोर्डवर <xliff:g id="COUNT_1">%1$d</xliff:g> फायली कॉपी केल्या.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"या स्थानामध्ये निवडलेल्या फायली पेस्ट करू शकत नाही."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ms-rMY/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ms-rMY/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ms-rMY/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 9762c00..12cf2e3 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumen"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fail"</string>
<string name="title_open" msgid="4353228937663917801">"Buka dari"</string>
<string name="title_save" msgid="2433679664882857999">"Simpan ke"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Buat folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Folder baharu"</string>
<string name="menu_grid" msgid="6878021334497835259">"Paparan grid"</string>
<string name="menu_list" msgid="7279285939892417279">"Paparan senarai"</string>
<string name="menu_sort" msgid="7677740407158414452">"Isih mengikut"</string>
@@ -29,19 +30,25 @@
<string name="menu_save" msgid="2394743337684426338">"Simpan"</string>
<string name="menu_share" msgid="3075149983979628146">"Kongsi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Padam"</string>
- <string name="menu_select" msgid="8711270657353563424">"Pilih \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Pilih Semua"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Pilih semua"</string>
<string name="menu_copy" msgid="3612326052677229148">"Salin ke..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Alihkan ke…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Tetingkap baharu"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Salin"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Tampal"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Papar storan dalaman"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Papar kad SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Sembunyikan storan dlmn"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Sembunyikan kad SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Papar saiz fail"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Sembunyikan saiz fail"</string>
+ <string name="button_select" msgid="527196987259139214">"Pilih"</string>
<string name="button_copy" msgid="8706475544635021302">"Salin"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dipilih"</string>
+ <string name="button_move" msgid="2202666023104202232">"Alihkan"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Tolak"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Cuba Lagi"</string>
<string name="sort_name" msgid="9183560467917256779">"Mengikut nama"</string>
- <string name="sort_date" msgid="586080032956151448">"Diubah suai mengikut tarikh"</string>
+ <string name="sort_date" msgid="586080032956151448">"Mengikut tarikh diubah"</string>
<string name="sort_size" msgid="3350681319735474741">"Mengikut saiz"</string>
<string name="drawer_open" msgid="4545466532430226949">"Tunjukkan akar"</string>
<string name="drawer_close" msgid="7602734368552123318">"Sembunyikan akar"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Tidak dapat memadam beberapa dokumen"</string>
<string name="share_via" msgid="8966594246261344259">"Kongsi melalui"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Menyalin fail"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Mengalihkan fail"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> lagi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
<item quantity="one">Menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Mengalihkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
+ <item quantity="one">Mengalihkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Memadam <xliff:g id="COUNT_1">%1$d</xliff:g> fail.</item>
+ <item quantity="one">Memadam <xliff:g id="COUNT_0">%1$d</xliff:g> fail.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Buat asal"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Bersedia untuk salin..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Bersedia untuk mengalih…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Tidak dapat menyalin <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
<item quantity="one">Tidak dapat menyalin <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Tidak dapat mengalihkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail</item>
+ <item quantity="one">Tidak dapat mengalihkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Sentuh untuk melihat butiran"</string>
<string name="retry" msgid="7564024179122207376">"Cuba semula"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Fail ini tidak disalin: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Fail ini tidak dialihkan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fail disalin ke papan keratan.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fail disalin ke papan keratan.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tidak boleh menampalkan fail yang dipilih dalam lokasi ini."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-my-rMM/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-my-rMM/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-my-rMM/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index ac4a8ec..a1ab012 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"စာရွက်စာတန်းများ"</string>
+ <string name="files_label" msgid="6051402950202690279">"ဖိုင်များ"</string>
<string name="title_open" msgid="4353228937663917801">"မှ ဖွင့်ပါ"</string>
<string name="title_save" msgid="2433679664882857999">"သို့ သိမ်းပါ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"အကန့် တည်ဆောက်ရန်"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ဖိုလ်ဒါ အသစ်"</string>
<string name="menu_grid" msgid="6878021334497835259">"ဖယားကွက်မြင်ကွင်း"</string>
<string name="menu_list" msgid="7279285939892417279">"အစဉ်လိုက်မြင်ကွင်း"</string>
<string name="menu_sort" msgid="7677740407158414452">"အစဉ်အလိုက် စီခြင်း"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"သိမ်းပါ"</string>
<string name="menu_share" msgid="3075149983979628146">"မျှဝေခြင်း"</string>
<string name="menu_delete" msgid="8138799623850614177">"ဖျက်ပစ်ရန်"</string>
- <string name="menu_select" msgid="8711270657353563424">"ရွေးရန်\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"အားလုံးရွေးရန်"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"အားလုံးကို ရွေးရန်"</string>
<string name="menu_copy" msgid="3612326052677229148">"သို့ကူးယူရန်…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"...သို့ ရွှေ့ရန်"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"ဝင်းဒိုးသစ်"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ကူးယူရန်"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ကပ်ရန်"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"စက်ရှိစတိုရုံ ပြပါ"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ကဒ် ပြပါ"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"စက်ရှိစတိုရုံ ဖျောက်ထားပါ"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD ကဒ် ဖျောက်ပါ"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ဖိုင်အရွယ်အစား ပြပါ"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ဖိုင်အရွယ်အစား ဖျောက်ပါ"</string>
+ <string name="button_select" msgid="527196987259139214">"ရွေးရန်"</string>
<string name="button_copy" msgid="8706475544635021302">"ကူးယူရန်"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ခရွေးချယ်ပြီး"</string>
+ <string name="button_move" msgid="2202666023104202232">"ရွေ့မည်"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ပယ်ရန်"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ထပ် စမ်းကြည့်ပါ"</string>
<string name="sort_name" msgid="9183560467917256779">"အမည်ဖြင့်"</string>
<string name="sort_date" msgid="586080032956151448">"ပြင်ဆင်မှု ရက်စွဲဖြင့်"</string>
<string name="sort_size" msgid="3350681319735474741">"အရွယ်အစားဖြင့်"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"တချို့ စာရွက်စာတန်းများ မဖျက်စီးနိုင်ပါ"</string>
<string name="share_via" msgid="8966594246261344259">"မှ ဝေမျှပါ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ဖိုင်များကူယူနေသည်"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ဖိုင်များ ရွှေ့နေသည်"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ကျန်ရှိသည်"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်များကို ကူးယူနေသည်။</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင် ကူးယူနေသည်။</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင် ရွှေ့နေစဉ်</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင် ရွှေ့နေစဉ်</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုဖျက်နေသည်။</item>
+ <item quantity="one">ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုဖျက်နေသည်။</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"ပြန်ဖျက်ရန်"</string>
<string name="copy_preparing" msgid="3896202461003039386">"မိတ္တူကူးရန်ပြင်ဆင်နေ..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ရွှေ့ရန် ပြင်ဆင်နေသည်…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင် ကော်ပီ မကူးနိုင်ပါ</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင် ကော်ပီမကူးနိုင်ပါ</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်များကို မရွှေ့နိုင်ပါ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင်ကို မရွှေ့နိုင်ပါ</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"အသေးစိတ် ကြည့်ရန် ထိပါ။"</string>
<string name="retry" msgid="7564024179122207376">"ထပ်စမ်းရန်"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ဤဖိုင်များ ကော်ပီကူးမထားပါ- <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ဤဖိုင်များကို မရွှေ့ခဲ့ပါ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"> ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ဖိုင်ကိုအချက်အလက်သိမ်းတဲ့နေရာသို့ ကူးယူပါ။</item>
+ <item quantity="one"> ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ဖိုင်ကိုအချက်အလက်သိမ်းတဲ့နေရာသို့ ကူးယူပါ။</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ဤနေရာတွင် ရွေးချယ်ထားသည့် ဖိုင်များကို ကူးထည့်၍မရပါ။"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-nb/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-nb/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-nb/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 8f70690..edeaa6d 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenter"</string>
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Åpne fra"</string>
<string name="title_save" msgid="2433679664882857999">"Lagre i"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Opprett en mappe"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Ny mappe"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rutenettvisning"</string>
<string name="menu_list" msgid="7279285939892417279">"Listevisning"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortér etter"</string>
@@ -29,19 +30,25 @@
<string name="menu_save" msgid="2394743337684426338">"Lagre"</string>
<string name="menu_share" msgid="3075149983979628146">"Del"</string>
<string name="menu_delete" msgid="8138799623850614177">"Slett"</string>
- <string name="menu_select" msgid="8711270657353563424">"Velg «<xliff:g id="DIRECTORY">^1</xliff:g>»"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Velg alle"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Markér alt"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiér til …"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Flytt til"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nytt vindu"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiér"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Lim inn"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Vis den interne lagringen"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Vis SD-kortet"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skjul den interne lagringen"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skjul SD-kortet"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Vis filstørrelsen"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Skjul filstørrelsen"</string>
+ <string name="button_select" msgid="527196987259139214">"Velg"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiér"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> valgt"</string>
+ <string name="button_move" msgid="2202666023104202232">"Flytt"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Avvis"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Prøv på nytt"</string>
<string name="sort_name" msgid="9183560467917256779">"Etter navn"</string>
- <string name="sort_date" msgid="586080032956151448">"«Etter dato» endret"</string>
+ <string name="sort_date" msgid="586080032956151448">"Etter endringsdato"</string>
<string name="sort_size" msgid="3350681319735474741">"Etter størrelse"</string>
<string name="drawer_open" msgid="4545466532430226949">"Vis røtter"</string>
<string name="drawer_close" msgid="7602734368552123318">"Skjul røtter"</string>
@@ -49,7 +56,7 @@
<string name="create_error" msgid="3735649141335444215">"Kunne ikke opprette mappen"</string>
<string name="query_error" msgid="1222448261663503501">"Kunne ikke undersøke dokumenter"</string>
<string name="root_recent" msgid="4470053704320518133">"Siste"</string>
- <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> gratis"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ledig"</string>
<string name="root_type_service" msgid="2178854894416775409">"Lagringstjenester"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Snarveier"</string>
<string name="root_type_device" msgid="7121342474653483538">"Enheter"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Enkelte dokumenter kunne ikke slettes"</string>
<string name="share_via" msgid="8966594246261344259">"Del via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierer filer"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Flytter filer"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> gjenstår"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopierer <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
<item quantity="one">Kopierer <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Flytter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ <item quantity="one">Flytter <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Sletter <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ <item quantity="one">Sletter <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Angre"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Forbereder kopiering …"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Forbereder flytting …"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Kunne ikke kopiere <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
<item quantity="one">Kunne ikke kopiere <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Kunne ikke flytte <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+ <item quantity="one">Kunne ikke flytte <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Trykk for å se detaljer"</string>
<string name="retry" msgid="7564024179122207376">"Prøv på nytt"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Disse filene ble ikke kopiert: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Disse filene ble ikke flyttet: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Kopierte <xliff:g id="COUNT_1">%1$d</xliff:g> filer til utklippstavlen.</item>
+ <item quantity="one">Kopierte <xliff:g id="COUNT_0">%1$d</xliff:g> fil til utklippstavlen.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan ikke lime inn de valgte filene her."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ne-rNP/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ne-rNP/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ne-rNP/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index 283e6f2..bd54211 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"कागजातहरू"</string>
+ <string name="files_label" msgid="6051402950202690279">"फाइलहरू"</string>
<string name="title_open" msgid="4353228937663917801">"यसबाट खोल्नुहोस्"</string>
<string name="title_save" msgid="2433679664882857999">"यसमा सुरक्षित गर्नुहोस्"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"फोल्डर सिर्जना गर्नुहोस्"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"नयाँ फोल्डर"</string>
<string name="menu_grid" msgid="6878021334497835259">"ग्रिड दृश्य"</string>
<string name="menu_list" msgid="7279285939892417279">"सूची दृश्य"</string>
<string name="menu_sort" msgid="7677740407158414452">"यसद्वारा क्रमवद्घ गर्नुहोस्"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"सुरक्षित गर्नुहोस्"</string>
<string name="menu_share" msgid="3075149983979628146">"साझेदारी गर्नुहोस्"</string>
<string name="menu_delete" msgid="8138799623850614177">"मेटाउनुहोस्"</string>
- <string name="menu_select" msgid="8711270657353563424">"चयनगर्नुहोस् \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"सबै चयन गर्नुहोस्"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"सबै चयन गर्नुहोस्"</string>
<string name="menu_copy" msgid="3612326052677229148">"यसमा प्रतिलिपि गर्नुहोस् ..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"…मा सार्नुहोस्"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"नयाँ विन्डो"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"प्रतिलिपि बनाउनुहोस्"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"टाँस्नुहोस्"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"आन्तरिक भण्डारण देखाउनुहोस्"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD कार्ड देखाउनुहोस्"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"आन्तरिक भण्डारण लुकाउनुहोस्"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD कार्ड लुकाउनुहोस्"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"फाइल आकार देखाउनुहोस्"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"फाइल आकार लुकाउनुहोस्"</string>
+ <string name="button_select" msgid="527196987259139214">"चयन गर्नुहोस्"</string>
<string name="button_copy" msgid="8706475544635021302">"प्रतिलिपि बनाउनुहोस्"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> चयन गरियो"</string>
+ <string name="button_move" msgid="2202666023104202232">"सार्नुहोस्"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"खारेज गर्नुहोस्"</string>
+ <string name="button_retry" msgid="4392027584153752797">"पुन: प्रयास गर्नुहोस्"</string>
<string name="sort_name" msgid="9183560467917256779">"नाम अनुसार"</string>
<string name="sort_date" msgid="586080032956151448">"परिमार्जित मिति अनुसार"</string>
<string name="sort_size" msgid="3350681319735474741">"आकार अनुसार"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"केही कागजातहरू मेट्न असमर्थ छ"</string>
<string name="share_via" msgid="8966594246261344259">"माध्यमबाट साझेदारी गर्नुहोस्"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"फाइलहरू प्रतिलिपि गर्दै:"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"फाइलहरू सार्दै"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g>बाँकी"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g>फाइलहरू प्रतिलिप गर्दै।</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्दै।</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू सार्दै।</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइलहरु सार्दै।</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू मेट्दै।</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइल मेट्दै।</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"अनडू गर्नुहोस्"</string>
<string name="copy_preparing" msgid="3896202461003039386">"प्रतिलिपिको लागि तयारी गर्दै ..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"सार्नको लागि तयारी गर्दै ..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू प्रतिलिपि गर्न सकेन</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल प्रतिलिपि गर्न सकेन</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू सार्न सकिएन</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> फाइल सार्न सकिएन</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"विवरणहरू हेर्न छुनुहोस्"</string>
<string name="retry" msgid="7564024179122207376">"पुनःप्रयास गर्नुहोस्"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"यी फाइलहरू प्रतिलिपि गरिएको थिएनः <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"यी फाइलहरू सारिएनन्: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"> क्लिपबोर्डमा <xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरू प्रतिलिपि बनाइए।</item>
+ <item quantity="one"> क्लिपबोर्डमा <xliff:g id="COUNT_0">%1$d</xliff:g> फाइलहरूका प्रतिलिपि बनाइए।</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"यो स्थानमा चयन गरिएका फाइलहरू टाँस्न सकिँदैन।"</string>
</resources>
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 87cac78..f77017d 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -15,6 +15,6 @@
-->
<resources>
- <color name="item_doc_grid_background">#ff111111</color>
+ <color name="directory_background">#ff111111</color>
<color name="item_doc_grid_protect_background">#88ffffff</color>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-nl/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-nl/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-nl/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index ba37d81..f2eda72 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documenten"</string>
+ <string name="files_label" msgid="6051402950202690279">"Bestanden"</string>
<string name="title_open" msgid="4353228937663917801">"Openen vanuit"</string>
<string name="title_save" msgid="2433679664882857999">"Opslaan in"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Map maken"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nieuwe map"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rasterweergave"</string>
<string name="menu_list" msgid="7279285939892417279">"Lijstweergave"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sorteren op"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Opslaan"</string>
<string name="menu_share" msgid="3075149983979628146">"Delen"</string>
<string name="menu_delete" msgid="8138799623850614177">"Verwijderen"</string>
- <string name="menu_select" msgid="8711270657353563424">"<xliff:g id="DIRECTORY">^1</xliff:g> selecteren"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Alles selecteren"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Alles selecteren"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiëren naar…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Verplaatsen naar…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nieuw venster"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiëren"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Plakken"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Interne opslag weergeven"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-kaart weergeven"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Interne opslag verbergen"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD-kaart verbergen"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Bestandsgrootte weergeven"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Bestandsgrootte verbergen"</string>
+ <string name="button_select" msgid="527196987259139214">"Selecteren"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiëren"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> geselecteerd"</string>
+ <string name="button_move" msgid="2202666023104202232">"Verplaatsen"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Sluiten"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Opnieuw proberen"</string>
<string name="sort_name" msgid="9183560467917256779">"Op naam"</string>
<string name="sort_date" msgid="586080032956151448">"Op aanpassingsdatum"</string>
<string name="sort_size" msgid="3350681319735474741">"Op grootte"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Kan bepaalde documenten niet verwijderen"</string>
<string name="share_via" msgid="8966594246261344259">"Delen via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Bestanden kopiëren"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Bestanden verplaatsen"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> resterend"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden kopiëren.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand kopiëren.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verplaatsen.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verplaatsen.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verwijderen.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verwijderen.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Ongedaan maken"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopiëren voorbereiden…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Verplaatsen voorbereiden…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet kopiëren</item>
<item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet kopiëren</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Kan <xliff:g id="COUNT_1">%1$d</xliff:g> bestanden niet verplaatsen</item>
+ <item quantity="one">Kan <xliff:g id="COUNT_0">%1$d</xliff:g> bestand niet verplaatsen</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Tik om details weer te geven"</string>
<string name="retry" msgid="7564024179122207376">"Opnieuw proberen"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Deze bestanden zijn niet gekopieerd: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Deze bestanden zijn niet verplaatst: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden gekopieerd naar klembord.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand gekopieerd naar klembord.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Kan de geselecteerde bestanden niet plakken op deze locatie."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-pa-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-pa-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-pa-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index 56e4aa8..e139dfd 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ਦਸਤਾਵੇਜ਼"</string>
+ <string name="files_label" msgid="6051402950202690279">"ਫਾਈਲਾਂ"</string>
<string name="title_open" msgid="4353228937663917801">"ਤੋਂ ਖੋਲ੍ਹੋ"</string>
<string name="title_save" msgid="2433679664882857999">"ਇਸ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ਫੋਲਡਰ ਬਣਾਓ"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"ਨਵਾਂ ਫੋਲਡਰ"</string>
<string name="menu_grid" msgid="6878021334497835259">"ਗ੍ਰਿਡ ਵਿਊ"</string>
<string name="menu_list" msgid="7279285939892417279">"ਸੂਚੀ ਦ੍ਰਿਸ਼"</string>
<string name="menu_sort" msgid="7677740407158414452">"ਇਸ ਅਨੁਸਾਰ ਛਾਂਟੋ"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"ਸੁਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="menu_share" msgid="3075149983979628146">"ਸ਼ੇਅਰ ਕਰੋ"</string>
<string name="menu_delete" msgid="8138799623850614177">"ਮਿਟਾਓ"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" ਨੂੰ ਚੁਣੋ"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"ਸਾਰਿਆਂ ਨੂੰ ਚੁਣੋ"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"ਸਾਰੇ ਚੁਣੋ"</string>
<string name="menu_copy" msgid="3612326052677229148">"ਇਸ ਵਿੱਚ ਕਾਪੀ ਕਰੋ…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ਇਸ ਵਿੱਚ ਮੂਵ ਕਰੋ..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"ਨਵੀਂ ਵਿੰਡੋ"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"ਕਾਪੀ ਕਰੋ"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ਪੇਸਟ ਕਰੋ"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਦਿਖਾਓ"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD ਕਾਰਡ ਦਿਖਾਓ"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ ਲੁਕਾਓ"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD ਕਾਰਡ ਲੁਕਾਓ"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ਫਾਈਲ ਆਕਾਰ ਦਿਖਾਓ"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ਫਾਈਲ ਆਕਾਰ ਲੁਕਾਓ"</string>
+ <string name="button_select" msgid="527196987259139214">"ਚੁਣੋ"</string>
<string name="button_copy" msgid="8706475544635021302">"ਕਾਪੀ ਕਰੋ"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ਚੁਣਿਆ"</string>
+ <string name="button_move" msgid="2202666023104202232">"ਮੂਵ ਕਰੋ"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ਬਰਖਾਸਤ ਕਰੋ"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="sort_name" msgid="9183560467917256779">"ਨਾਮ ਮੁਤਾਬਕ"</string>
<string name="sort_date" msgid="586080032956151448">"ਤਾਰੀਖ ਮੁਤਾਬਕ ਸੰਸ਼ੋਧਿਤ"</string>
<string name="sort_size" msgid="3350681319735474741">"ਆਕਾਰ ਮੁਤਾਬਕ"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ਕੁਝ ਦਸਤਾਵੇਜ਼ ਮਿਟਾਉਣ ਵਿੱਚ ਅਸਮਰੱਥ"</string>
<string name="share_via" msgid="8966594246261344259">"ਇਸ ਰਾਹੀਂ ਸ਼ੇਅਰ ਕਰੋ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ਬਾਕੀ"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ।</item>
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ਫਾਈਲਾਂ ਕਾਪੀ ਕਰ ਰਿਹਾ ਹੈ।</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰਨਾ।</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਕਰਨਾ।</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਮਿਟਾ ਰਿਹਾ ਹੈ।</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"ਪਹਿਲਾਂ ਵਰਗਾ ਕਰੋ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"ਕਾਪੀ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ਮੂਵ ਲਈ ਤਿਆਰ ਕਰ ਰਿਹਾ ਹੈ..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਨਹੀਂ ਬਣਾ ਸਕਿਆ</item>
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਨਹੀਂ ਬਣਾ ਸਕਿਆ</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"ਵੇਰਵੇ ਵੇਖਣ ਲਈ ਸਪਰਸ਼ ਕਰੋ"</string>
<string name="retry" msgid="7564024179122207376">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਨਹੀਂ ਬਣਾਈ ਗਈ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ਇਹਨਾਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕੀਤਾ ਗਿਆ: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਬਣਾਈ ਗਈ।</item>
+ <item quantity="other">ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਦੀ ਪ੍ਰਤੀਲਿਪੀ ਬਣਾਈ ਗਈ।</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ਇਸ ਸਥਾਨ ਵਿੱਚ ਚੁਣੀਆਂ ਗਈਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਪੇਸਟ ਨਹੀਂ ਕਰ ਸਕਦਾ ਹੈ।"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-pl/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-pl/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-pl/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 79485ef..bb81377 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
+ <string name="files_label" msgid="6051402950202690279">"Pliki"</string>
<string name="title_open" msgid="4353228937663917801">"Otwórz z"</string>
<string name="title_save" msgid="2433679664882857999">"Zapisz w"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Utwórz folder"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nowy folder"</string>
<string name="menu_grid" msgid="6878021334497835259">"Widok siatki"</string>
<string name="menu_list" msgid="7279285939892417279">"Widok listy"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortuj według"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Zapisz"</string>
<string name="menu_share" msgid="3075149983979628146">"Udostępnij"</string>
<string name="menu_delete" msgid="8138799623850614177">"Usuń"</string>
- <string name="menu_select" msgid="8711270657353563424">"Zaznacz „<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Wybierz wszystko"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Zaznacz wszystko"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiuj do…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Przenieś do…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nowe okno"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiuj"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Wklej"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaż pamięć wewnętrzną"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaż kartę SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ukryj pamięć wewnętrzną"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ukryj kartę SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Pokaż rozmiar pliku"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ukryj rozmiar pliku"</string>
+ <string name="button_select" msgid="527196987259139214">"Wybierz"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiuj"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Wybrano: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Przenieś"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Zamknij"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Spróbuj ponownie"</string>
<string name="sort_name" msgid="9183560467917256779">"Według nazwy"</string>
<string name="sort_date" msgid="586080032956151448">"Według daty edycji"</string>
<string name="sort_size" msgid="3350681319735474741">"Według rozmiaru"</string>
@@ -57,8 +64,9 @@
<string name="empty" msgid="7858882803708117596">"Brak elementów"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Nie można otworzyć pliku"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Nie można usunąć niektórych dokumentów"</string>
- <string name="share_via" msgid="8966594246261344259">"Udostępnij przez"</string>
+ <string name="share_via" msgid="8966594246261344259">"Udostępnij przez:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiowanie plików"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Przenoszenie plików"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Pozostało: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
@@ -66,14 +74,42 @@
<item quantity="other">Kopiowanie <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
<item quantity="one">Kopiowanie <xliff:g id="COUNT_0">%1$d</xliff:g> pliku.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="few">Przenoszę <xliff:g id="COUNT_1">%1$d</xliff:g> pliki.</item>
+ <item quantity="many">Przenoszę <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
+ <item quantity="other">Przenoszę <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
+ <item quantity="one">Przenoszę <xliff:g id="COUNT_0">%1$d</xliff:g> plik.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="few">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> pliki.</item>
+ <item quantity="many">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> plików.</item>
+ <item quantity="other">Usuwam <xliff:g id="COUNT_1">%1$d</xliff:g> pliku.</item>
+ <item quantity="one">Usuwam <xliff:g id="COUNT_0">%1$d</xliff:g> plik.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Cofnij"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Przygotowuję do kopiowania…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Przygotowuję przenoszenie…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="few">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="many">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
<item quantity="other">Nie można skopiować <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
<item quantity="one">Nie można skopiować <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="few">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+ <item quantity="many">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> plików</item>
+ <item quantity="other">Nie udało się przenieść <xliff:g id="COUNT_1">%1$d</xliff:g> pliku</item>
+ <item quantity="one">Nie udało się przenieść <xliff:g id="COUNT_0">%1$d</xliff:g> pliku</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Kliknij, by zobaczyć szczegóły"</string>
<string name="retry" msgid="7564024179122207376">"Ponów"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Te pliki nie zostały skopiowane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Te pliki nie zostały przeniesione: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="few">Skopiowano <xliff:g id="COUNT_1">%1$d</xliff:g> pliki do schowka.</item>
+ <item quantity="many">Skopiowano <xliff:g id="COUNT_1">%1$d</xliff:g> plików do schowka.</item>
+ <item quantity="other">Skopiowano <xliff:g id="COUNT_1">%1$d</xliff:g> pliku do schowka.</item>
+ <item quantity="one">Skopiowano <xliff:g id="COUNT_0">%1$d</xliff:g> plik do schowka.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Nie można wkleić wybranych plików w tej lokalizacji."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-pt-rBR/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-pt-rBR/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-pt-rBR/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..d72f0c3
--- /dev/null
+++ b/res/values-pt-rBR/strings.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ 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
+
+ http://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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
+ <string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
+ <string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova pasta"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Visualização em grade"</string>
+ <string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Pesquisar"</string>
+ <string name="menu_settings" msgid="6008033148948428823">"Configurações"</string>
+ <string name="menu_open" msgid="432922957274920903">"Abrir"</string>
+ <string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
+ <string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
+ <string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selecionar tudo"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
+ <string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
+ <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
+ <string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar armaz. interno"</string>
+ <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar cartão SD"</string>
+ <string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tam. do arquivo"</string>
+ <string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tam. do arquivo"</string>
+ <string name="button_select" msgid="527196987259139214">"Selecionar"</string>
+ <string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Dispensar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Tentar novamente"</string>
+ <string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
+ <string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
+ <string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
+ <string name="drawer_open" msgid="4545466532430226949">"Mostrar raízes"</string>
+ <string name="drawer_close" msgid="7602734368552123318">"Ocultar raízes"</string>
+ <string name="save_error" msgid="6167009778003223664">"Falha ao salvar o documento"</string>
+ <string name="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
+ <string name="query_error" msgid="1222448261663503501">"Falha ao consultar documentos"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Recentes"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> livres"</string>
+ <string name="root_type_service" msgid="2178854894416775409">"Serviços de armazenamento"</string>
+ <string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
+ <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
+ <string name="root_type_apps" msgid="8838065367985945189">"Mais apps"</string>
+ <string name="empty" msgid="7858882803708117596">"Nenhum item"</string>
+ <string name="toast_no_application" msgid="1339885974067891667">"Não é possível abrir o arquivo"</string>
+ <string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
+ <string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
+ <string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Movendo arquivos"</string>
+ <string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
+ <plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
+ <item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
+ <string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
+ <plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
+ <item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ <item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ </plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ </plurals>
+ <string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
+ <string name="retry" msgid="7564024179122207376">"Repetir"</string>
+ <string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
+</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-pt-rPT/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-pt-rPT/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-pt-rPT/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 931b85c..43265a5 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Ficheiros"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Guardar em"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova pasta"</string>
<string name="menu_grid" msgid="6878021334497835259">"Vista de grelha"</string>
<string name="menu_list" msgid="7279285939892417279">"Vista de lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Ordenar por"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Guardar"</string>
<string name="menu_share" msgid="3075149983979628146">"Partilhar"</string>
<string name="menu_delete" msgid="8138799623850614177">"Eliminar"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selecionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Selecionar tudo"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selecionar tudo"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiar para…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar mem. armaz. int."</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar mem. armaz. int."</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar cartão SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tam. de fich."</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tam. de fich."</string>
+ <string name="button_select" msgid="527196987259139214">"Selecionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionado(s)"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ignorar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Tentar novamente"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
<string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
<string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Não é possível eliminar alguns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Partilhar através de"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"A copiar ficheiros"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"A mover ficheiros"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Faltam <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">A copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
<item quantity="one">A copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">A mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+ <item quantity="one">A mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">A eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros.</item>
+ <item quantity="one">A eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Anular"</string>
<string name="copy_preparing" msgid="3896202461003039386">"A preparar para copiar…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"A preparar para mover…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
<item quantity="one">Não foi possível copiar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros</item>
+ <item quantity="one">Não foi possível mover <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
<string name="retry" msgid="7564024179122207376">"Tentar novamente"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Os seguintes ficheiros não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Os seguintes ficheiros não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Copiou <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros para a área de transferência.</item>
+ <item quantity="one">Copiou <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro para a área de transferência.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os ficheiros selecionados nesta localização."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-pt/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-pt/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-pt/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 534caf0..d72f0c3 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documentos"</string>
+ <string name="files_label" msgid="6051402950202690279">"Arquivos"</string>
<string name="title_open" msgid="4353228937663917801">"Abrir de"</string>
<string name="title_save" msgid="2433679664882857999">"Salvar em"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Criar pasta"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova pasta"</string>
<string name="menu_grid" msgid="6878021334497835259">"Visualização em grade"</string>
<string name="menu_list" msgid="7279285939892417279">"Visualização em lista"</string>
<string name="menu_sort" msgid="7677740407158414452">"Classificar por"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Salvar"</string>
<string name="menu_share" msgid="3075149983979628146">"Compartilhar"</string>
<string name="menu_delete" msgid="8138799623850614177">"Excluir"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selecionar \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Selecionar tudo"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selecionar tudo"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiar para..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mover para..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nova janela"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiar"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Colar"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Mostrar armaz. interno"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Mostrar cartão SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ocultar armaz. interno"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ocultar cartão SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Mostrar tam. do arquivo"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ocultar tam. do arquivo"</string>
+ <string name="button_select" msgid="527196987259139214">"Selecionar"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiar"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selecionados"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mover"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Dispensar"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Tentar novamente"</string>
<string name="sort_name" msgid="9183560467917256779">"Por nome"</string>
<string name="sort_date" msgid="586080032956151448">"Por data de modificação"</string>
<string name="sort_size" msgid="3350681319735474741">"Por tamanho"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Não foi possível excluir alguns documentos"</string>
<string name="share_via" msgid="8966594246261344259">"Compartilhar via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Copiando arquivos"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Movendo arquivos"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> restantes"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
<item quantity="other">Copiando <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Movendo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ <item quantity="other">Excluindo <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Desfazer"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Preparando para copiar..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Preparando para mover..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
<item quantity="other">Não foi possível copiar <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ <item quantity="other">Não foi possível mover <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Toque para ver detalhes"</string>
<string name="retry" msgid="7564024179122207376">"Repetir"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Estes arquivos não foram copiados: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Estes arquivos não foram movidos: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> arquivos copiados para a área de transferência.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Não é possível colar os arquivos selecionados neste local."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ro/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ro/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ro/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 7ffe10d..e880bbd 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Documente"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fișiere"</string>
<string name="title_open" msgid="4353228937663917801">"Deschideți din"</string>
<string name="title_save" msgid="2433679664882857999">"Salvați în"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Creați un dosar"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Dosar nou"</string>
<string name="menu_grid" msgid="6878021334497835259">"Afișare tip grilă"</string>
<string name="menu_list" msgid="7279285939892417279">"Afișare tip listă"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortați după"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Salvați"</string>
<string name="menu_share" msgid="3075149983979628146">"Distribuiți"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ștergeți"</string>
- <string name="menu_select" msgid="8711270657353563424">"Selectați „<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Selectați-le pe toate"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Selectați tot"</string>
<string name="menu_copy" msgid="3612326052677229148">"Copiați în…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Mutați în…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Fereastră nouă"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Copiați"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Inserați"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Afișați stocarea internă"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Afișați cardul SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ascundeți stocarea internă"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ascundeți cardul SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Afișați mărime fișiere"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ascundeți mărime fișiere"</string>
+ <string name="button_select" msgid="527196987259139214">"Selectați"</string>
<string name="button_copy" msgid="8706475544635021302">"Copiați"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> selectate"</string>
+ <string name="button_move" msgid="2202666023104202232">"Mutați"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Închideți"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Încercați din nou"</string>
<string name="sort_name" msgid="9183560467917256779">"După nume"</string>
<string name="sort_date" msgid="586080032956151448">"După data modificării"</string>
<string name="sort_size" msgid="3350681319735474741">"După dimensiune"</string>
@@ -57,21 +64,46 @@
<string name="empty" msgid="7858882803708117596">"Nu există elemente"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Fișierul nu poate fi deschis"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Unele documente nu au putut fi șterse"</string>
- <string name="share_via" msgid="8966594246261344259">"Distribuiți prin"</string>
+ <string name="share_via" msgid="8966594246261344259">"Trimiteți prin"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Se copiază fișierele"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Se mută fișierele"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Timp rămas: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Se copiază <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
<item quantity="other">Se copiază <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
<item quantity="one">Se copiază <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="few">Se mută <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
+ <item quantity="other">Se mută <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
+ <item quantity="one">Se mută <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="few">Se șterg <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere.</item>
+ <item quantity="other">Se șterg <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere.</item>
+ <item quantity="one">Se șterge <xliff:g id="COUNT_0">%1$d</xliff:g> fișier.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Anulați"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Se pregătește copierea..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Se pregătește mutarea…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="few">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
<item quantity="other">Nu s-au putut copia <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
<item quantity="one">Nu s-a putut copia <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="few">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere</item>
+ <item quantity="other">Nu s-au putut muta <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere</item>
+ <item quantity="one">Nu s-a putut muta <xliff:g id="COUNT_0">%1$d</xliff:g> fișier</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Atingeți pentru a afișa detaliile"</string>
<string name="retry" msgid="7564024179122207376">"Reîncercați"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Aceste fișiere nu au fost copiate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Aceste fișiere nu au fost mutate: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="few">Au fost copiate <xliff:g id="COUNT_1">%1$d</xliff:g> fișiere în clipboard.</item>
+ <item quantity="other">Au fost copiate <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere în clipboard.</item>
+ <item quantity="one">A fost copiat <xliff:g id="COUNT_0">%1$d</xliff:g> fișier în clipboard.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Fișierele selectate nu au putut fi inserate în această locație."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ru/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ru/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ru/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 5c2e530..e475591 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документы"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файлы"</string>
<string name="title_open" msgid="4353228937663917801">"Открыть"</string>
<string name="title_save" msgid="2433679664882857999">"Сохранить"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Новая папка"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Создать папку"</string>
<string name="menu_grid" msgid="6878021334497835259">"Сетка"</string>
<string name="menu_list" msgid="7279285939892417279">"Список"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортировать"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Сохранить"</string>
<string name="menu_share" msgid="3075149983979628146">"Поделиться"</string>
<string name="menu_delete" msgid="8138799623850614177">"Удалить"</string>
- <string name="menu_select" msgid="8711270657353563424">"Выбрать папку \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Выбрать все"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Выбрать все"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копировать в…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Переместить"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Новое окно"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копировать"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Вставить"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Внутренняя память"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD-карта"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Скрыть внутреннюю память"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Скрыть SD-карту"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Показать размер файлов"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Скрыть размер файлов"</string>
+ <string name="button_select" msgid="527196987259139214">"Выбрать"</string>
<string name="button_copy" msgid="8706475544635021302">"Копировать"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Выбрано: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Переместить"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Скрыть"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Повторить"</string>
<string name="sort_name" msgid="9183560467917256779">"По названию"</string>
<string name="sort_date" msgid="586080032956151448">"По дате изменения"</string>
<string name="sort_size" msgid="3350681319735474741">"По размеру"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Не удалось удалить некоторые документы"</string>
<string name="share_via" msgid="8966594246261344259">"Поделиться"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копирование файлов"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Перемещение файлов"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Осталось <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файл...</item>
@@ -66,14 +74,42 @@
<item quantity="many">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файлов...</item>
<item quantity="other">Копируется <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
+ <item quantity="few">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файлов...</item>
+ <item quantity="many">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файлов...</item>
+ <item quantity="other">Перемещение <xliff:g id="COUNT_1">%1$d</xliff:g> файла...</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файла…</item>
+ <item quantity="few">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файлов…</item>
+ <item quantity="many">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файлов…</item>
+ <item quantity="other">Удаление <xliff:g id="COUNT_1">%1$d</xliff:g> файла…</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Отменить"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Подготовка к копированию…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Подготовка…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
<item quantity="few">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
<item quantity="many">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
<item quantity="other">Не удалось скопировать <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <item quantity="many">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+ <item quantity="other">Не удалось переместить <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Нажмите, чтобы узнать подробности."</string>
<string name="retry" msgid="7564024179122207376">"Повторить"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Не удалось скопировать эти файлы: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Эти файлы не были перемещены: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Скопирован <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Скопировано <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ <item quantity="many">Скопировано <xliff:g id="COUNT_1">%1$d</xliff:g> файлов</item>
+ <item quantity="other">Скопированы <xliff:g id="COUNT_1">%1$d</xliff:g> файла</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не удается вставить сюда выбранные файлы"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-si-rLK/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-si-rLK/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-si-rLK/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index bb025b8..e380b0a 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ලේඛන"</string>
+ <string name="files_label" msgid="6051402950202690279">"ගොනු"</string>
<string name="title_open" msgid="4353228937663917801">"විවෘත වන්නේ"</string>
<string name="title_save" msgid="2433679664882857999">"සුරකින්නේ"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ෆෝල්ඩරයක් සාදන්න"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"නව ෆෝල්ඩරය"</string>
<string name="menu_grid" msgid="6878021334497835259">"ජාල පෙනුම"</string>
<string name="menu_list" msgid="7279285939892417279">"ලැයිස්තු පෙනුම"</string>
<string name="menu_sort" msgid="7677740407158414452">"අනුපිළිවෙලට සකසා ඇත්තේ"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"සුරකින්න"</string>
<string name="menu_share" msgid="3075149983979628146">"බෙදාගන්න"</string>
<string name="menu_delete" msgid="8138799623850614177">"මකන්න"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" තෝරන්න"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"සියල්ල තෝරන්න"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"සියල්ල තෝරන්න"</string>
<string name="menu_copy" msgid="3612326052677229148">"වෙත පිටපත් කරන්න..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"වෙත ගෙනයන්න..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"නව කවුළුව"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"පිටපත් කරන්න"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"අලවන්න"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"අභ්යන්තර ආචයනය පෙන්වන්න"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD කාඩ් පත පෙන්වන්න"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"අභ්යන්තර ආචයනය සඟවන්න"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD කාඩ් පත සඟවන්න"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ගොනු ප්රමණය පෙන්වන්න"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ගොනු ප්රමණය සඟවන්න"</string>
+ <string name="button_select" msgid="527196987259139214">"තෝරන්න"</string>
<string name="button_copy" msgid="8706475544635021302">"පිටපත් කිරීම"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ක් තෝරාගන්නා ලදි"</string>
+ <string name="button_move" msgid="2202666023104202232">"ගෙන යන්න"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ඉවතලන්න"</string>
+ <string name="button_retry" msgid="4392027584153752797">"නැවත උත්සාහ කරන්න"</string>
<string name="sort_name" msgid="9183560467917256779">"නමින්"</string>
<string name="sort_date" msgid="586080032956151448">"වෙනස් කරන ලද දිනයෙන්"</string>
<string name="sort_size" msgid="3350681319735474741">"ප්රමාණය මගින්"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"සමහර ලේඛන මැකීමට නොහැකි විය"</string>
<string name="share_via" msgid="8966594246261344259">"හරහා බෙදාගන්න"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ගොනු පිටපත් කරමින්"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ගොනු ගෙන යාම"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> ඉතිරියි"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරමින්.</item>
<item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරමින්.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යමින්.</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යමින්.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකමින්.</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකමින්.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"අස් කරන්න"</string>
<string name="copy_preparing" msgid="3896202461003039386">"පිටපතක් සඳහා සූදානම් කරමින්..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"ගෙන යාම සඳහා පිළියෙළ කරමින් ..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කළ නොහැකි විය</item>
<item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කළ නොහැකි විය</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යාමට නොහැකි විය</item>
+ <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් ගෙන යාමට නොහැකි විය</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"විස්තර බැලීමට ස්පර්ශ කරන්න"</string>
<string name="retry" msgid="7564024179122207376">"නැවත උත්සාහ කරන්න"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"මෙම ගොනු පිටපත් නොකරන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"මෙම ගොනු ගෙන නොයන ලදී: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">පසුරු පුවරුවට ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරන ලදි.</item>
+ <item quantity="other">පසුරු පුවරුවට ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g> ක් පිටපත් කරන ලදි.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"මෙම ස්ථානය තුළ තෝරාගත් ගොනු ඇලවිය නොහැක."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sk/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sk/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sk/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 8692913..6614dca 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenty"</string>
+ <string name="files_label" msgid="6051402950202690279">"Súbory"</string>
<string name="title_open" msgid="4353228937663917801">"Otvoriť z"</string>
<string name="title_save" msgid="2433679664882857999">"Uložiť do"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Vytvoriť priečinok"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nový priečinok"</string>
<string name="menu_grid" msgid="6878021334497835259">"Zobrazenie mriežky"</string>
<string name="menu_list" msgid="7279285939892417279">"Zobrazenie zoznamu"</string>
<string name="menu_sort" msgid="7677740407158414452">"Zoradiť podľa"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Uložiť"</string>
<string name="menu_share" msgid="3075149983979628146">"Zdieľať"</string>
<string name="menu_delete" msgid="8138799623850614177">"Odstrániť"</string>
- <string name="menu_select" msgid="8711270657353563424">"Vyberte adresár <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Vybrať všetko"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Vybrať všetko"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopírovať do…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Presunúť do…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nové okno"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopírovať"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Prilepiť"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Zobraziť interné úložisko"</string>
- <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Zobraziť kartu SD"</string>
+ <string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Zobraziť SD kartu"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skryť interné úložisko"</string>
- <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skryť kartu SD"</string>
+ <string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skryť SD kartu"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Zobraziť veľkosť súboru"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Skryť veľkosť súboru"</string>
+ <string name="button_select" msgid="527196987259139214">"Vybrať"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopírovať"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Vybraté: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Presunúť"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Odmietnuť"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Skúsiť znova"</string>
<string name="sort_name" msgid="9183560467917256779">"Podľa názvu"</string>
<string name="sort_date" msgid="586080032956151448">"Podľa dátumu zmeny"</string>
<string name="sort_size" msgid="3350681319735474741">"Podľa veľkosti"</string>
@@ -49,7 +56,7 @@
<string name="create_error" msgid="3735649141335444215">"Priečinok sa nepodarilo vytvoriť"</string>
<string name="query_error" msgid="1222448261663503501">"Zoznam dokumentov sa nepodarilo načítať"</string>
<string name="root_recent" msgid="4470053704320518133">"Nedávne"</string>
- <string name="root_available_bytes" msgid="8568452858617033281">"Voľné: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"Voľné <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="root_type_service" msgid="2178854894416775409">"Služby úložiska"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Skratky"</string>
<string name="root_type_device" msgid="7121342474653483538">"Zariadenia"</string>
@@ -57,8 +64,9 @@
<string name="empty" msgid="7858882803708117596">"Žiadne položky"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Súbor sa nepodarilo otvoriť"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Niektoré dokumenty sa nepodarilo odstrániť"</string>
- <string name="share_via" msgid="8966594246261344259">"Zdieľať pomocou"</string>
+ <string name="share_via" msgid="8966594246261344259">"Zdieľať"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopírovanie súborov"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Presúvajú sa súbory"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zostáva: <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="few">Kopírujú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
@@ -66,14 +74,42 @@
<item quantity="other">Kopíruje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
<item quantity="one">Kopíruje sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="few">Presúvajú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
+ <item quantity="many">Presúva sa <xliff:g id="COUNT_1">%1$d</xliff:g> súboru.</item>
+ <item quantity="other">Presúva sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
+ <item quantity="one">Presúva sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="few">Odstraňujú sa <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
+ <item quantity="many">Odstraňuje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súboru.</item>
+ <item quantity="other">Odstraňuje sa <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
+ <item quantity="one">Odstraňuje sa <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Späť"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Pripravuje sa na kopírovanie..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Prebieha príprava na presunutie…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="few">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
<item quantity="many">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súboru</item>
<item quantity="other">Zlyhalo kopírovanie <xliff:g id="COUNT_1">%1$d</xliff:g> súborov</item>
<item quantity="one">Zlyhalo kopírovanie <xliff:g id="COUNT_0">%1$d</xliff:g> súboru</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> súbory nie je možné presunúť</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> súboru nie je možné presunúť</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> súborov nie je možné presunúť</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> súbor nie je možné presunúť</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Klepnutím zobrazíte podrobné informácie"</string>
<string name="retry" msgid="7564024179122207376">"Skúsiť znova"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Tieto súbory neboli skopírované: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Tieto súbory neboli presunuté: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="few">Do schránky boli skopírované <xliff:g id="COUNT_1">%1$d</xliff:g> súbory.</item>
+ <item quantity="many">Do schránky bolo skopírovaného <xliff:g id="COUNT_1">%1$d</xliff:g> súboru.</item>
+ <item quantity="other">Do schránky bolo skopírovaných <xliff:g id="COUNT_1">%1$d</xliff:g> súborov.</item>
+ <item quantity="one">Do schránky bol skopírovaný <xliff:g id="COUNT_0">%1$d</xliff:g> súbor.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Do tohto umiestnenia nie je možné prilepiť vybrané súbory"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sl/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sl/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sl/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 2c1171e..58a4cc0 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumenti"</string>
- <string name="title_open" msgid="4353228937663917801">"Odpiranje iz"</string>
- <string name="title_save" msgid="2433679664882857999">"Shranjevanje v"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Ustvarjanje mape"</string>
+ <string name="files_label" msgid="6051402950202690279">"Datoteke"</string>
+ <string name="title_open" msgid="4353228937663917801">"Odpri iz mape"</string>
+ <string name="title_save" msgid="2433679664882857999">"Shrani v"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Nova mapa"</string>
<string name="menu_grid" msgid="6878021334497835259">"Mrežni pogled"</string>
<string name="menu_list" msgid="7279285939892417279">"Pogled seznama"</string>
<string name="menu_sort" msgid="7677740407158414452">"Razvrsti glede na"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Shrani"</string>
<string name="menu_share" msgid="3075149983979628146">"Skupna raba"</string>
<string name="menu_delete" msgid="8138799623850614177">"Izbriši"</string>
- <string name="menu_select" msgid="8711270657353563424">"Izbira mape »<xliff:g id="DIRECTORY">^1</xliff:g>«"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Izberi vse"</string>
- <string name="menu_copy" msgid="3612326052677229148">"Kopiranje v …"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Izberi vse"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Kopiraj v …"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Premakni v ..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Novo okno"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiraj"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Prilepi"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Pokaži notranjo shrambo"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Pokaži kartico SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Skrij notranjo shrambo"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Skrij kartico SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Pokaži velikost datoteke"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Skrij velikost datoteke"</string>
+ <string name="button_select" msgid="527196987259139214">"Izberi"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiraj"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Št. izbranih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Premik"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Opusti"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Poskusite znova"</string>
<string name="sort_name" msgid="9183560467917256779">"Po imenu"</string>
<string name="sort_date" msgid="586080032956151448">"Po datumu spremembe"</string>
<string name="sort_size" msgid="3350681319735474741">"Po velikosti"</string>
@@ -59,6 +66,7 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Nekaterih dokumentov ni mogoče izbrisati"</string>
<string name="share_via" msgid="8966594246261344259">"Deli z drugimi prek"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopiranje datotek"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Premikanje datotek"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Še <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
@@ -66,14 +74,42 @@
<item quantity="few">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
<item quantity="other">Kopiranje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="two">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+ <item quantity="few">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+ <item quantity="other">Premikanje <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke</item>
+ <item quantity="two">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+ <item quantity="few">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+ <item quantity="other">Izbris <xliff:g id="COUNT_1">%1$d</xliff:g> datotek</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Razveljavi"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Pripravljanje na kopiranje …"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Priprava na premikanje …"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče kopirati</item>
<item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
<item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče kopirati</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> datoteke ni bilo mogoče premakniti</item>
+ <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> datotek ni bilo mogoče premakniti</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Dotaknite se za ogled podrobnosti"</string>
<string name="retry" msgid="7564024179122207376">"Poskusi znova"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Te datoteke niso bile kopirane: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Te datoteke niso bile premaknjene: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">V odložišče je bila kopirana <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka.</item>
+ <item quantity="two">V odložišče sta bili kopirani <xliff:g id="COUNT_1">%1$d</xliff:g> datoteki.</item>
+ <item quantity="few">V odložišče so bile kopirane <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke.</item>
+ <item quantity="other">V odložišče je bilo kopiranih <xliff:g id="COUNT_1">%1$d</xliff:g> datotek.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Izbranih datotek ni mogoče prilepiti sem."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sq-rAL/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sq-rAL/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sq-rAL/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index 37c063f..7eba92f 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -17,10 +17,11 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokumente"</string>
+ <string name="files_label" msgid="6051402950202690279">"Skedarët"</string>
<string name="title_open" msgid="4353228937663917801">"Hap nga"</string>
- <string name="title_save" msgid="2433679664882857999">"Ruaje në"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Krijo dosje"</string>
- <string name="menu_grid" msgid="6878021334497835259">"Pamje \"sitë\""</string>
+ <string name="title_save" msgid="2433679664882857999">"Ruaje te"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Dosje e re"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Pamje rrjete"</string>
<string name="menu_list" msgid="7279285939892417279">"Pamje liste"</string>
<string name="menu_sort" msgid="7677740407158414452">"Rendit sipas"</string>
<string name="menu_search" msgid="3816712084502856974">"Kërko"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Ruaj"</string>
<string name="menu_share" msgid="3075149983979628146">"Shpërnda"</string>
<string name="menu_delete" msgid="8138799623850614177">"Fshi"</string>
- <string name="menu_select" msgid="8711270657353563424">"Përzgjidh \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Zgjidhi të gjitha"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Zgjidhi të gjitha"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopjo te..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Zhvendos te..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Dritare e re"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopjo"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Ngjit"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Trego hapësirën e brendshme ruajtëse"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Shfaq kartën SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Fshih hapësirën ruajtëse të brendshme"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Fshih kartën SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Shfaq madhësinë e skedarit"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Fshih madhësinë e skedarit"</string>
+ <string name="button_select" msgid="527196987259139214">"Zgjidh"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopjo"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> dokumente u përzgjodhën"</string>
+ <string name="button_move" msgid="2202666023104202232">"Zhvendos"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Largoje"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Provo sërish"</string>
<string name="sort_name" msgid="9183560467917256779">"Sipas emrit"</string>
<string name="sort_date" msgid="586080032956151448">"Sipas datës së modifikimit"</string>
<string name="sort_size" msgid="3350681319735474741">"Sipas madhësisë"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"E pamundur të fshihen disa dokumente"</string>
<string name="share_via" msgid="8966594246261344259">"Shpërnda publikisht përmes"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Po kopjon skedarët"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Po zhvendos skedarët"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> të mbetura"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Po kopjon <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
<item quantity="one">Po kopjon <xliff:g id="COUNT_0">%1$d</xliff:g> skedar.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Po zhvendos <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
+ <item quantity="one">Po zhvendos <xliff:g id="COUNT_0">%1$d</xliff:g> skedar.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Po fshin <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë.</item>
+ <item quantity="one">Po fshin <xliff:g id="COUNT_0">%1$d</xliff:g> skedar.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Zhbëj"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Po përgatitet për kopjimin…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Po përgatitet për zhvendosjen…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të kopjoheshin</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të kopjohej</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> skedarë nuk mund të zhvendoseshin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> skedar nuk mund të zhvendosej</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Prek për të parë detajet"</string>
<string name="retry" msgid="7564024179122207376">"Provo përsëri"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Këta skedarë nuk u kopjuan: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Këta skedarë nuk u zhvendosën: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">U kopjuan <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë në kujtesën e fragmenteve.</item>
+ <item quantity="one">U kopjua <xliff:g id="COUNT_0">%1$d</xliff:g> skedar në kujtesën e fragmenteve.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Skedarët e zgjedhur nuk mund të ngjiten në këtë vendndodhje."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sr/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sr/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sr/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 9db6e13..0bce687 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
+ <string name="files_label" msgid="6051402950202690279">"Датотеке"</string>
<string name="title_open" msgid="4353228937663917801">"Отвори са"</string>
<string name="title_save" msgid="2433679664882857999">"Сачувај у"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Направи директоријум"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Нови директоријум"</string>
<string name="menu_grid" msgid="6878021334497835259">"Приказ мреже"</string>
<string name="menu_list" msgid="7279285939892417279">"Приказ листе"</string>
<string name="menu_sort" msgid="7677740407158414452">"Сортирај према"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Сачувај"</string>
<string name="menu_share" msgid="3075149983979628146">"Дели"</string>
<string name="menu_delete" msgid="8138799623850614177">"Избриши"</string>
- <string name="menu_select" msgid="8711270657353563424">"Изабери „<xliff:g id="DIRECTORY">^1</xliff:g>“"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Изабери све"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Изабери све"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копирај на..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Премести у..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Нови прозор"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копирај"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Налепи"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Прикажи интерну меморију"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Прикажи SD картицу"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Сакриј интерну меморију"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Сакриј SD картицу"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Прикажи величину датотеке"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Сакриј величину датотеке"</string>
+ <string name="button_select" msgid="527196987259139214">"Изабери"</string>
<string name="button_copy" msgid="8706475544635021302">"Копирај"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Изабрано је <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Премести"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Одбаци"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Покушај поново"</string>
<string name="sort_name" msgid="9183560467917256779">"Према имену"</string>
<string name="sort_date" msgid="586080032956151448">"Према датуму измене"</string>
<string name="sort_size" msgid="3350681319735474741">"Према величини"</string>
@@ -59,19 +66,44 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Није могуће избрисати неке документе"</string>
<string name="share_via" msgid="8966594246261344259">"Делите преко"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копирање датотека"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Датотеке се премештају"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Још <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
<item quantity="few">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
<item quantity="other">Копирање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Премешта се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ <item quantity="few">Премештају се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
+ <item quantity="other">Премешта се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Брише се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ <item quantity="few">Бришу се <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке.</item>
+ <item quantity="other">Брише се <xliff:g id="COUNT_1">%1$d</xliff:g> датотека.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Опозови"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Припрема се копирање…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Припрема се премештање..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку</item>
<item quantity="few">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
<item quantity="other">Нисмо успели да копирамо <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке</item>
+ <item quantity="few">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотекe</item>
+ <item quantity="other">Није успело премештање <xliff:g id="COUNT_1">%1$d</xliff:g> датотека</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Додирните да бисте видели детаље"</string>
<string name="retry" msgid="7564024179122207376">"Покушај поново"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Следеће датотеке нису копиране: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Ове датотеке нису премештене: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотеку у привремену меморију.</item>
+ <item quantity="few">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке у привремену меморију.</item>
+ <item quantity="other">Копирали сте <xliff:g id="COUNT_1">%1$d</xliff:g> датотека у привремену меморију.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Изабране датотеке не могу да се налепе на овој локацији."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sv/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sv/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sv/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 6e2eddf..a4a119c 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokument"</string>
+ <string name="files_label" msgid="6051402950202690279">"Filer"</string>
<string name="title_open" msgid="4353228937663917801">"Öppna från"</string>
<string name="title_save" msgid="2433679664882857999">"Spara till"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Skapa mapp"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Ny mapp"</string>
<string name="menu_grid" msgid="6878021334497835259">"Rutnätsvy"</string>
<string name="menu_list" msgid="7279285939892417279">"Listvy"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sortera efter"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Spara"</string>
<string name="menu_share" msgid="3075149983979628146">"Dela"</string>
<string name="menu_delete" msgid="8138799623850614177">"Ta bort"</string>
- <string name="menu_select" msgid="8711270657353563424">"Välj <xliff:g id="DIRECTORY">^1</xliff:g>"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Markera alla"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Markera allt"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopiera till …"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Flytta till ..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Nytt fönster"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopiera"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Klistra in"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Visa internminne"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Visa SD-kort"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Dölj internminne"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Dölj SD-kort"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Visa filstorlek"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Dölj filstorlek"</string>
+ <string name="button_select" msgid="527196987259139214">"Välj"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopiera"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Har valt <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Flytta"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ta bort permanent"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Försök igen"</string>
<string name="sort_name" msgid="9183560467917256779">"Efter namn"</string>
<string name="sort_date" msgid="586080032956151448">"Efter ändringsdatum"</string>
<string name="sort_size" msgid="3350681319735474741">"Efter storlek"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Det gick inte att ta bort vissa dokument"</string>
<string name="share_via" msgid="8966594246261344259">"Dela via"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kopierar filer"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Filer flyttas"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> återstår"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Kopierar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
<item quantity="one">Kopierar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Flyttar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ <item quantity="one">Flyttar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Raderar <xliff:g id="COUNT_1">%1$d</xliff:g> filer.</item>
+ <item quantity="one">Raderar <xliff:g id="COUNT_0">%1$d</xliff:g> fil.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Ångra"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopieringen förbereds …"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Förbereder för att flytta …"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer gick inte att kopiera</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil gick inte att kopiera</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Det gick inte att flytta <xliff:g id="COUNT_1">%1$d</xliff:g> filer</item>
+ <item quantity="one">Det gick inte att flytta <xliff:g id="COUNT_0">%1$d</xliff:g> fil</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Tryck här om du vill veta mer"</string>
<string name="retry" msgid="7564024179122207376">"Försök igen"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Följande filer kopierades inte: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Följande filer har inte flyttats: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> filer har kopierats till Urklipp.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fil har kopierats till Urklipp.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Det går inte att klistra in den valda filen på den här platsen."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sw/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sw/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sw/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 5a3dd37..91151fb 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hati"</string>
+ <string name="files_label" msgid="6051402950202690279">"Faili"</string>
<string name="title_open" msgid="4353228937663917801">"Fungua kutoka"</string>
<string name="title_save" msgid="2433679664882857999">"Hifadhi kwenye"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Unda folda"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Folda mpya"</string>
<string name="menu_grid" msgid="6878021334497835259">"Mwonekano gridi"</string>
<string name="menu_list" msgid="7279285939892417279">"Mwonekano orodha"</string>
<string name="menu_sort" msgid="7677740407158414452">"Panga kwa"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Hifadhi"</string>
<string name="menu_share" msgid="3075149983979628146">"Shiriki"</string>
<string name="menu_delete" msgid="8138799623850614177">"Futa"</string>
- <string name="menu_select" msgid="8711270657353563424">"Chagua \" <xliff:g id="DIRECTORY">^1</xliff:g> \""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Chagua Zote"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Chagua zote"</string>
<string name="menu_copy" msgid="3612326052677229148">"Nakili kwenda..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Hamisha hadi..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Dirisha jipya"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Nakili"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Bandika"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Onyesha hifadhi ya ndani"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Onyesha kadi ya SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ficha hifadhi ya ndani"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ficha kadi ya SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Onyesha ukubwa wa faili"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ficha ukubwa wa faili"</string>
+ <string name="button_select" msgid="527196987259139214">"Teua"</string>
<string name="button_copy" msgid="8706475544635021302">"Nakili"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> zimechaguliwa"</string>
+ <string name="button_move" msgid="2202666023104202232">"Hamisha"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Ondoa"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Jaribu Tena"</string>
<string name="sort_name" msgid="9183560467917256779">"Kwa jina"</string>
<string name="sort_date" msgid="586080032956151448">"Kwa tarehe viliporekebishwa"</string>
<string name="sort_size" msgid="3350681319735474741">"Kwa ukubwa"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Imeshindwa kufuta baadhi ya hati"</string>
<string name="share_via" msgid="8966594246261344259">"Shiriki kupitia"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Inanakili faili"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Inahamisha faili"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Zimesalia <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Inanakili faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
<item quantity="one">Inanakili faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Inahamisha faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ <item quantity="one">Inahamisha faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Inafuta faili <xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ <item quantity="one">Inafuta faili <xliff:g id="COUNT_0">%1$d</xliff:g>.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Tendua"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Inaanda kunakili..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Inatayarisha kuhamisha..."</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Haikuweza kunakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> </item>
<item quantity="one">Haikuweza kunakili faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Haikuweza kuhamisha faili <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Haikuweza kuhamisha faili <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Gusa ili uone maelezo"</string>
<string name="retry" msgid="7564024179122207376">"Jaribu tena"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Faili hizi hazikunakiliwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Faili hizi hazikuhamishwa: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Alinakili faili <xliff:g id="COUNT_1">%1$d</xliff:g> kwenye ubaoklipu.</item>
+ <item quantity="one">Alinakili faili <xliff:g id="COUNT_0">%1$d</xliff:g> kwenye ubaoklipu.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Haiwezi kubandika faili zilizochaguliwa katika eneo hili."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sw600dp/dimens.xml
similarity index 72%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sw600dp/dimens.xml
index 3f50fb9..642ff7e 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources>
+ <dimen name="root_icon_margin">8dp</dimen>
+</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sw720dp-land/layouts.xml
similarity index 72%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sw720dp-land/layouts.xml
index 3f50fb9..0e1807c 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sw720dp-land/layouts.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources>
+ <item name="files_activity" type="layout">@layout/fixed_layout</item>
+</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 4786d28..f393d88 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -19,8 +19,8 @@
<item type="dimen" name="dialog_width">85%</item>
- <dimen name="grid_padding_horiz">24dp</dimen>
+ <dimen name="grid_padding_horiz">16dp</dimen>
<dimen name="grid_padding_vert">16dp</dimen>
- <dimen name="grid_item_padding">8dp</dimen>
+ <dimen name="grid_item_margin">8dp</dimen>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-sw720dp/layouts.xml
similarity index 72%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-sw720dp/layouts.xml
index 3f50fb9..7d28f9c 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-sw720dp/layouts.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources>
+ <item name="docs_activity" type="layout">@layout/fixed_layout</item>
+</resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index d7c031e..a8dcbb0 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="DialogWhenReallyLarge" parent="@*android:style/Theme.DeviceDefault.Light.Dialog">
+ <style name="DocumentsBaseTheme" parent="@style/Theme.AppCompat.Light.Dialog">
<!-- We do not specify width of window here because the max size of
floating window specified by windowFixedWidthis is limited. -->
<item name="*android:windowFixedHeightMajor">80%</item>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ta-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ta-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ta-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index cc6b1df..9a667b8 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"ஆவணங்கள்"</string>
- <string name="title_open" msgid="4353228937663917801">"இதிலிருந்து திற"</string>
+ <string name="files_label" msgid="6051402950202690279">"கோப்புகள்"</string>
+ <string name="title_open" msgid="4353228937663917801">"இதில் திற"</string>
<string name="title_save" msgid="2433679664882857999">"இதில் சேமி"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"கோப்புறையை உருவாக்கு"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"புதிய கோப்புறை"</string>
<string name="menu_grid" msgid="6878021334497835259">"கட்டக் காட்சி"</string>
<string name="menu_list" msgid="7279285939892417279">"பட்டியல்"</string>
<string name="menu_sort" msgid="7677740407158414452">"இதன்படி வரிசைப்படுத்து"</string>
@@ -29,19 +30,25 @@
<string name="menu_save" msgid="2394743337684426338">"சேமி"</string>
<string name="menu_share" msgid="3075149983979628146">"பகிர்"</string>
<string name="menu_delete" msgid="8138799623850614177">"நீக்கு"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" ஐத் தேர்ந்தெடு"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"எல்லாவற்றையும் தேர்ந்தெடு"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"எல்லாவற்றையும் தேர்ந்தெடு"</string>
<string name="menu_copy" msgid="3612326052677229148">"இங்கு நகலெடு…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"இதற்கு நகர்த்து…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"புதிய சாளரம்"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"நகலெடு"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"ஒட்டு"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"அகச் சேமிப்பகத்தைக் காட்டு"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD கார்டைக் காட்டு"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"அகச் சேமிப்பகத்தை மறை"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD கார்டை மறை"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"கோப்பு அளவைக் காட்டு"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"கோப்பு அளவை மறை"</string>
+ <string name="button_select" msgid="527196987259139214">"தேர்ந்தெடு"</string>
<string name="button_copy" msgid="8706475544635021302">"நகலெடு"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன"</string>
+ <string name="button_move" msgid="2202666023104202232">"நகர்த்து"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"நிராகரி"</string>
+ <string name="button_retry" msgid="4392027584153752797">"மீண்டும் முயற்சிக்கவும்"</string>
<string name="sort_name" msgid="9183560467917256779">"பெயரின்படி"</string>
- <string name="sort_date" msgid="586080032956151448">"தேதியின்படி திருத்தப்பட்டது"</string>
+ <string name="sort_date" msgid="586080032956151448">"திருத்தப்பட்ட தேதியின்படி"</string>
<string name="sort_size" msgid="3350681319735474741">"அளவின்படி"</string>
<string name="drawer_open" msgid="4545466532430226949">"வழிகளைக் காட்டு"</string>
<string name="drawer_close" msgid="7602734368552123318">"வழிகளை மறை"</string>
@@ -54,22 +61,43 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"குறுக்குவழிகள்"</string>
<string name="root_type_device" msgid="7121342474653483538">"சாதனங்கள்"</string>
<string name="root_type_apps" msgid="8838065367985945189">"மேலும் பயன்பாடுகள்"</string>
- <string name="empty" msgid="7858882803708117596">"உருப்படிகள் இல்லை"</string>
+ <string name="empty" msgid="7858882803708117596">"எதுவும் இல்லை"</string>
<string name="toast_no_application" msgid="1339885974067891667">"கோப்பைத் திறக்க முடியவில்லை"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"சில ஆவணங்களை நீக்க முடியவில்லை"</string>
<string name="share_via" msgid="8966594246261344259">"இதன் வழியாகப் பகிர்"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"கோப்புகளை நகலெடுத்தல்"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"கோப்புகளை நகர்த்துதல்"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> மீதமுள்ளது"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்கிறது.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்கிறது.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகர்த்துகிறது.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகர்த்துகிறது.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்குகிறது.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்குகிறது.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"செயல்தவிர்"</string>
<string name="copy_preparing" msgid="3896202461003039386">"நகல் தயாராகிறது…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"நகர்த்துவதற்குத் தயார்படுத்துகிறது…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகலெடுக்க முடியவில்லை</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகலெடுக்க முடியவில்லை</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நகர்த்த முடியவில்லை</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நகர்த்த முடியவில்லை</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"விவரங்களைப் பார்க்க, தொடவும்"</string>
<string name="retry" msgid="7564024179122207376">"மீண்டும் முயற்சிக்கவும்"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"நகலெடுக்கப்படாத கோப்புகள்: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"இந்தக் கோப்புகள் நகர்த்தப்படவில்லை: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">கிளிப்போர்டிற்கு <xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகள் நகலெடுக்கப்பட்டன.</item>
+ <item quantity="one">கிளிப்போர்டிற்கு <xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பு நகலெடுக்கப்பட்டது.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"தேர்ந்தெடுத்த கோப்புகளை இங்கு ஒட்ட முடியாது."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-te-rIN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-te-rIN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-te-rIN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index cf13ec5..91d436a 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"పత్రాలు"</string>
+ <string name="files_label" msgid="6051402950202690279">"ఫైల్లు"</string>
<string name="title_open" msgid="4353228937663917801">"ఇక్కడి నుండి తెరువు"</string>
<string name="title_save" msgid="2433679664882857999">"ఇందులో సేవ్ చేయి"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"ఫోల్డర్ను సృష్టించు"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"కొత్త ఫోల్డర్"</string>
<string name="menu_grid" msgid="6878021334497835259">"గ్రిడ్ వీక్షణ"</string>
<string name="menu_list" msgid="7279285939892417279">"జాబితా వీక్షణ"</string>
<string name="menu_sort" msgid="7677740407158414452">"ఇలా క్రమబద్ధీకరించు"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"సేవ్ చేయి"</string>
<string name="menu_share" msgid="3075149983979628146">"భాగస్వామ్యం చేయి"</string>
<string name="menu_delete" msgid="8138799623850614177">"తొలగించు"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\"ని ఎంచుకోండి"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"అన్నీ ఎంచుకోండి"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"అన్నీ ఎంచుకోండి"</string>
<string name="menu_copy" msgid="3612326052677229148">"ఇక్కడికి కాపీ చేయి…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"దీనికి తరలించు..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"కొత్త విండో"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"కాపీ చేయి"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"అతికించు"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"అంతర్గత నిల్వను చూపు"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD కార్డ్ను చూపు"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"అంతర్గత నిల్వను దాచు"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD కార్డ్ను దాచు"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"ఫైల్ పరిమాణాన్ని చూపు"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ఫైల్ పరిమాణాన్ని దాచు"</string>
+ <string name="button_select" msgid="527196987259139214">"ఎంచుకోండి"</string>
<string name="button_copy" msgid="8706475544635021302">"కాపీ చేయి"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ఎంచుకోబడ్డాయి"</string>
+ <string name="button_move" msgid="2202666023104202232">"తరలించు"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"తీసివేయి"</string>
+ <string name="button_retry" msgid="4392027584153752797">"మళ్లీ ప్రయత్నించు"</string>
<string name="sort_name" msgid="9183560467917256779">"పేరు ద్వారా"</string>
<string name="sort_date" msgid="586080032956151448">"సవరించిన తేదీ ద్వారా"</string>
<string name="sort_size" msgid="3350681319735474741">"పరిమాణం ద్వారా"</string>
@@ -49,7 +56,7 @@
<string name="create_error" msgid="3735649141335444215">"ఫోల్డర్ను సృష్టించడంలో విఫలమైంది"</string>
<string name="query_error" msgid="1222448261663503501">"పత్రాల కోసం ప్రశ్నించడంలో విఫలమైంది"</string>
<string name="root_recent" msgid="4470053704320518133">"ఇటీవల"</string>
- <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ఉచితం"</string>
+ <string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> ఖాళీ"</string>
<string name="root_type_service" msgid="2178854894416775409">"నిల్వ పరికరాలు"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"సత్వరమార్గాలు"</string>
<string name="root_type_device" msgid="7121342474653483538">"పరికరాలు"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"కొన్ని పత్రాలను తొలగించడం సాధ్యపడలేదు"</string>
<string name="share_via" msgid="8966594246261344259">"దీని ద్వారా భాగస్వామ్యం చేయండి"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"ఫైల్లు కాపీ అవుతున్నాయి"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"ఫైల్లను తరలిస్తోంది"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> మిగిలి ఉంది"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను కాపీ చేస్తోంది.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను కాపీ చేస్తోంది.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను తరలిస్తోంది.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను తరలిస్తోంది.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను తొలగిస్తోంది.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను తొలగిస్తోంది.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"చర్య రద్దు చేయి"</string>
<string name="copy_preparing" msgid="3896202461003039386">"కాపీ చేయడానికి సిద్ధం చేస్తోంది…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"తరలించడానికి సిద్ధమవుతోంది…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను కాపీ చేయలేకపోయింది</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను కాపీ చేయలేకపోయింది</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను తరలించలేకపోయింది</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను తరలించలేకపోయింది</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"వివరాలను వీక్షించడానికి తాకండి"</string>
<string name="retry" msgid="7564024179122207376">"మళ్లీ ప్రయత్నించు"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ఈ ఫైల్లు కాపీ చేయబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ఈ ఫైల్లు తరలించబడలేదు: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">క్లిప్బోర్డ్కి <xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను కాపీ చేసారు.</item>
+ <item quantity="one">క్లిప్బోర్డ్కి <xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను కాపీ చేసారు.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ఎంచుకున్న ఫైల్లను ఈ స్థానంలోకి తీసుకురావడం సాధ్యపడదు."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-th/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-th/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-th/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index ac7bd5d..9d77561 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"เอกสาร"</string>
+ <string name="files_label" msgid="6051402950202690279">"ไฟล์"</string>
<string name="title_open" msgid="4353228937663917801">"เปิดจาก"</string>
<string name="title_save" msgid="2433679664882857999">"บันทึกไปยัง"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"สร้างโฟลเดอร์"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"โฟลเดอร์ใหม่"</string>
<string name="menu_grid" msgid="6878021334497835259">"มุมมองตาราง"</string>
<string name="menu_list" msgid="7279285939892417279">"มุมมองรายการ"</string>
<string name="menu_sort" msgid="7677740407158414452">"จัดเรียงตาม"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"บันทึก"</string>
<string name="menu_share" msgid="3075149983979628146">"แชร์"</string>
<string name="menu_delete" msgid="8138799623850614177">"ลบ"</string>
- <string name="menu_select" msgid="8711270657353563424">"เลือก \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"เลือกทั้งหมด"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"เลือกทั้งหมด"</string>
<string name="menu_copy" msgid="3612326052677229148">"คัดลอกไปยัง…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"ย้ายไปที่…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"หน้าต่างใหม่"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"คัดลอก"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"วาง"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"แสดงที่จัดเก็บภายใน"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"แสดงการ์ด SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"ซ่อนที่จัดเก็บภายใน"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"ซ่อนการ์ด SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"แสดงขนาดไฟล์"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"ซ่อนขนาดไฟล์"</string>
+ <string name="button_select" msgid="527196987259139214">"เลือก"</string>
<string name="button_copy" msgid="8706475544635021302">"คัดลอก"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"เลือกไว้ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"ย้าย"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"ปิด"</string>
+ <string name="button_retry" msgid="4392027584153752797">"ลองอีกครั้ง"</string>
<string name="sort_name" msgid="9183560467917256779">"ตามชื่อ"</string>
<string name="sort_date" msgid="586080032956151448">"ตามวันที่ที่ปรับเปลี่ยน"</string>
<string name="sort_size" msgid="3350681319735474741">"ตามขนาด"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"ไม่สามารถลบเอกสารบางรายการ"</string>
<string name="share_via" msgid="8966594246261344259">"แชร์ผ่าน"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"กำลังคัดลอกไฟล์"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"กำลังย้ายไฟล์"</string>
<string name="copy_remaining" msgid="6283790937387975095">"เหลือ <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">กำลังคัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
<item quantity="one">กำลังคัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">กำลังย้าย <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">กำลังย้าย <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">กำลังลบ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">กำลังลบ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"เลิกทำ"</string>
<string name="copy_preparing" msgid="3896202461003039386">"กำลังเตรียมการคัดลอก…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"กำลังเตรียมการย้าย…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">ไม่สามารถคัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
<item quantity="one">ไม่สามารถคัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">ไม่สามารถย้ายไฟล์ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์</item>
+ <item quantity="one">ไม่สามารถย้ายไฟล์ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"แตะเพื่อดูรายละเอียด"</string>
<string name="retry" msgid="7564024179122207376">"ลองอีกครั้ง"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"ไม่มีการคัดลอกไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"ไม่มีการย้ายไฟล์เหล่านี้: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">คัดลอก <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์ไปยังคลิปบอร์ดแล้ว</item>
+ <item quantity="one">คัดลอก <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์ไปยังคลิปบอร์ดแล้ว</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"ไม่สามารถวางไฟล์ที่เลือกในตำแหน่งนี้"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-tl/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-tl/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-tl/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 2d64ca9..9ae30aa 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -17,29 +17,36 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Mga Dokumento"</string>
+ <string name="files_label" msgid="6051402950202690279">"Mga File"</string>
<string name="title_open" msgid="4353228937663917801">"Buksan mula sa"</string>
<string name="title_save" msgid="2433679664882857999">"I-save sa"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Gumawa ng folder"</string>
- <string name="menu_grid" msgid="6878021334497835259">"View ng grid"</string>
- <string name="menu_list" msgid="7279285939892417279">"View ng listahan"</string>
- <string name="menu_sort" msgid="7677740407158414452">"Pag-uri-uriin ayon sa"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Bagong folder"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"View na grid"</string>
+ <string name="menu_list" msgid="7279285939892417279">"View na listahan"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Uriin ayon sa"</string>
<string name="menu_search" msgid="3816712084502856974">"Maghanap"</string>
<string name="menu_settings" msgid="6008033148948428823">"Mga Setting"</string>
<string name="menu_open" msgid="432922957274920903">"Buksan"</string>
<string name="menu_save" msgid="2394743337684426338">"I-save"</string>
<string name="menu_share" msgid="3075149983979628146">"Ibahagi"</string>
<string name="menu_delete" msgid="8138799623850614177">"Tanggalin"</string>
- <string name="menu_select" msgid="8711270657353563424">"Piliin ang \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Piliin Lahat"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Piliin lahat"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopyahin sa..."</string>
+ <string name="menu_move" msgid="1828090633118079817">"Ilipat sa…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Bagong window"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyahin"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"I-paste"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ipakita internal storage"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Ipakita ang SD card"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Itago internal storage"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Itago ang SD card"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Ipakita ang laki ng file"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Itago ang laki ng file"</string>
+ <string name="button_select" msgid="527196987259139214">"Pumili"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopyahin"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> ang pinili"</string>
+ <string name="button_move" msgid="2202666023104202232">"Ilipat"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"I-dismiss"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Subukang Muli"</string>
<string name="sort_name" msgid="9183560467917256779">"Ayon sa pangalan"</string>
<string name="sort_date" msgid="586080032956151448">"Ayon sa petsa ng pagbago"</string>
<string name="sort_size" msgid="3350681319735474741">"Ayon sa laki"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Hindi matanggal ang ilang dokumento"</string>
<string name="share_via" msgid="8966594246261344259">"Ibahagi sa pamamagitan ng"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Kinokopya ang mga file"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Inililipat ang mga file"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> na lang ang natitira"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
<item quantity="other">Kumokopya ng <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Inililipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="other">Inililipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Dine-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file.</item>
+ <item quantity="other">Dine-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"I-undo"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Naghahanda para sa pagkopya…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Naghahanda para sa paglilipat…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
<item quantity="other">Hindi makopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> file</item>
+ <item quantity="other">Hindi nailipat ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Pindutin upang tingnan ang mga detalye"</string>
<string name="retry" msgid="7564024179122207376">"Subukang muli"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Hindi nakopya ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Hindi nailipat ang mga file na ito: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Nakopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> file sa clipboard.</item>
+ <item quantity="other">Nakopya ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file sa clipboard.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Hindi mai-paste sa lokasyong ito ang mga piniling file."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-tr/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-tr/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-tr/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index bda4543..3c2e39c 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Dokümanlar"</string>
+ <string name="files_label" msgid="6051402950202690279">"Dosyalar"</string>
<string name="title_open" msgid="4353228937663917801">"Şuradan aç:"</string>
<string name="title_save" msgid="2433679664882857999">"Şuraya kaydet:"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Klasör oluştur"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Yeni klasör"</string>
<string name="menu_grid" msgid="6878021334497835259">"Tablo görünümü"</string>
<string name="menu_list" msgid="7279285939892417279">"Liste görünümü"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sıralama ölçütü"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Kaydet"</string>
<string name="menu_share" msgid="3075149983979628146">"Paylaş"</string>
<string name="menu_delete" msgid="8138799623850614177">"Sil"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" dizinini seç"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Tümünü Seç"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Tümünü seç"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopyala…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Taşı..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Yeni pencere"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopyala"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Yapıştır"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Dahili depolamayı göster"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD kartı göster"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Dahili depolamayı gizle"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD kartı gizle"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Dosya boyutunu göster"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Dosya boyutunu gizle"</string>
+ <string name="button_select" msgid="527196987259139214">"Seç"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopyala"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> tane seçildi"</string>
+ <string name="button_move" msgid="2202666023104202232">"Taşı"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Kapat"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Tekrar Dene"</string>
<string name="sort_name" msgid="9183560467917256779">"Ada göre"</string>
<string name="sort_date" msgid="586080032956151448">"Değişiklik tarihine göre"</string>
<string name="sort_size" msgid="3350681319735474741">"Boyuta göre"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Bazı dokümanlar silinemiyor"</string>
<string name="share_via" msgid="8966594246261344259">"Şunu kullanarak paylaş:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Dosyalar kopyalanıyor"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Dosyalar taşınıyor"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> kaldı"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanıyor.</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanıyor.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya taşınıyor.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya taşınıyor.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya siliniyor.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya siliniyor.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Geri al"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Kopyalanmak için hazırlanıyor…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Taşıma için hazırlanıyor…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya kopyalanamadı</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya kopyalanamadı</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya taşınamadı</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya taşınamadı</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Ayrıntıları görüntülemek için dokunun"</string>
<string name="retry" msgid="7564024179122207376">"Yeniden dene"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Şu dosyalar kopyalanmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Şu dosyalar taşınmadı: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya panoya kopyalandı.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya panoya kopyalandı.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Seçili dosyalar bu konuma yapıştırılamıyor."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-uk/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-uk/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-uk/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 999dc70..407f1aa 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Документи"</string>
+ <string name="files_label" msgid="6051402950202690279">"Файли"</string>
<string name="title_open" msgid="4353228937663917801">"Відкрити"</string>
<string name="title_save" msgid="2433679664882857999">"Зберегти в"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Створити папку"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Нова папка"</string>
<string name="menu_grid" msgid="6878021334497835259">"Режим таблиці"</string>
<string name="menu_list" msgid="7279285939892417279">"Режим списку"</string>
<string name="menu_sort" msgid="7677740407158414452">"Параметри сортування"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Зберегти"</string>
<string name="menu_share" msgid="3075149983979628146">"Поділитися"</string>
<string name="menu_delete" msgid="8138799623850614177">"Видалити"</string>
- <string name="menu_select" msgid="8711270657353563424">"Вибрати каталог \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Вибрати все"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Вибрати все"</string>
<string name="menu_copy" msgid="3612326052677229148">"Копіювати в…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Перемістити в…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Нове вікно"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Копіювати"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Вставити"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Показати внутр. пам’ять"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Показати карту SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Сховати внутр. пам’ять"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Сховати карту SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Показати розмір файлу"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Сховати розмір файлу"</string>
+ <string name="button_select" msgid="527196987259139214">"Вибрати"</string>
<string name="button_copy" msgid="8706475544635021302">"Копіювати"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Вибрано <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Перемістити"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Закрити"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Повторити спробу"</string>
<string name="sort_name" msgid="9183560467917256779">"За назвою"</string>
<string name="sort_date" msgid="586080032956151448">"За датою змінення"</string>
<string name="sort_size" msgid="3350681319735474741">"За розміром"</string>
@@ -54,11 +61,12 @@
<string name="root_type_shortcut" msgid="3318760609471618093">"Ярлики"</string>
<string name="root_type_device" msgid="7121342474653483538">"Пристрої"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Інші програми"</string>
- <string name="empty" msgid="7858882803708117596">"Немає елементів"</string>
+ <string name="empty" msgid="7858882803708117596">"Нічого немає"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Не вдалося відкрити файл"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Не вдалося видалити деякі документи"</string>
<string name="share_via" msgid="8966594246261344259">"Надіслати через"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Копіювання файлів"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Переміщення файлів"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Залишилося <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
@@ -66,14 +74,42 @@
<item quantity="many">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
<item quantity="other">Копіювання <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ <item quantity="few">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+ <item quantity="many">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+ <item quantity="other">Переміщення <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+ <item quantity="few">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+ <item quantity="many">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+ <item quantity="other">Видалення <xliff:g id="COUNT_1">%1$d</xliff:g> файлу.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Відмінити"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Підготовка до копіювання…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Підготовка до переміщення…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
<item quantity="few">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
<item quantity="many">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
<item quantity="other">Не вдалося скопіювати <xliff:g id="COUNT_1">%1$d</xliff:g> файлу</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файл</item>
+ <item quantity="few">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файли</item>
+ <item quantity="many">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файлів</item>
+ <item quantity="other">Не вдалося перемістити <xliff:g id="COUNT_1">%1$d</xliff:g> файлу</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Торкніться, щоб дізнатися більше"</string>
<string name="retry" msgid="7564024179122207376">"Повторити"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Ці файли не скопійовано: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Не переміщено ці файли: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файл.</item>
+ <item quantity="few">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файли.</item>
+ <item quantity="many">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файлів.</item>
+ <item quantity="other">У буфер обміну скопійовано <xliff:g id="COUNT_1">%1$d</xliff:g> файла.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Не вдається вставити вибрані файли в цю папку."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-ur-rPK/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-ur-rPK/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-ur-rPK/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 31c1909..845d2cb 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"دستاویزات"</string>
+ <string name="files_label" msgid="6051402950202690279">"فائلیں"</string>
<string name="title_open" msgid="4353228937663917801">"کھولیں از"</string>
<string name="title_save" msgid="2433679664882857999">"اس میں محفوظ کریں"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"فولڈر بنائیں"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"نیا فولڈر"</string>
<string name="menu_grid" msgid="6878021334497835259">"گرڈ منظر"</string>
<string name="menu_list" msgid="7279285939892417279">"فہرست منظر"</string>
<string name="menu_sort" msgid="7677740407158414452">"ترتیب دیں بلحاظ"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"محفوظ کریں"</string>
<string name="menu_share" msgid="3075149983979628146">"اشتراک کریں"</string>
<string name="menu_delete" msgid="8138799623850614177">"حذف کریں"</string>
- <string name="menu_select" msgid="8711270657353563424">"\"<xliff:g id="DIRECTORY">^1</xliff:g>\" منتخب کریں"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"سبھی منتخب کریں"</string>
- <string name="menu_copy" msgid="3612326052677229148">"اس پر کاپی ہو رہی ہے…"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"سبھی کو منتخب کریں"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"اس میں کاپی کریں…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"اس میں منتقل کریں…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"نئی ونڈو"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"کاپی کریں"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"پیسٹ کریں"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"داخلی اسٹوریج دکھائیں"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD کارڈ دکھائیں"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"داخلی اسٹوریج چھپائیں"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD کارڈ چھپائیں"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"فائل سائز دکھائیں"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"فائل سائز چھپائیں"</string>
+ <string name="button_select" msgid="527196987259139214">"منتخب کریں"</string>
<string name="button_copy" msgid="8706475544635021302">"کاپی کریں"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> کو منتخب کیا گیا"</string>
+ <string name="button_move" msgid="2202666023104202232">"منتقل کریں"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"برخاست کریں"</string>
+ <string name="button_retry" msgid="4392027584153752797">"دوبارہ کوشش کریں"</string>
<string name="sort_name" msgid="9183560467917256779">"نام کے لحاظ سے"</string>
<string name="sort_date" msgid="586080032956151448">"ترمیم کی تاریخ کے لحاظ سے"</string>
<string name="sort_size" msgid="3350681319735474741">"سائز کے لحاظ سے"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"کچھ دستاویزات کو حذف کرنے سے قاصر"</string>
<string name="share_via" msgid="8966594246261344259">"اشتراک کریں بذریعہ"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"فائلیں کاپی ہو رہی ہیں"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"فائلیں منتقل ہو رہی ہیں"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> باقی ہے"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں کاپی کی جا رہی ہیں۔</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی کی جا رہی ہے۔</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز منتقل کی جا رہی ہیں۔</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل منتقل کی جا رہی ہے۔</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف ہو رہی ہیں۔</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف ہو رہی ہے۔</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"کالعدم کریں"</string>
<string name="copy_preparing" msgid="3896202461003039386">"کاپی کیلئے تیار ہو رہا ہے…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"منتقلی کیلئے تیار ہو رہی ہیں…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز کاپی نہیں کی جا سکیں</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کاپی نہیں کی جا سکی</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز منتقل نہیں ہو سکیں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل منتقل نہیں ہو سکی</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"تفصیلات دیکھنے کیلئے ٹچ کریں"</string>
<string name="retry" msgid="7564024179122207376">"دوبارہ کوشش کریں"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"یہ فائلز کاپی نہیں کی گئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"یہ فائلیں منتقل نہیں ہوئیں: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلز کلپ بورڈ پر کاپی کی گئیں۔</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل کلپ بورڈ پر کاپی کی گئی۔</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"منتخب کردہ فائلز کو اس مقام پر پیسٹ نہیں کیا جا سکتا۔"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-uz-rUZ/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-uz-rUZ/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-uz-rUZ/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 1b15b9f..f3514db 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -17,29 +17,36 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Hujjatlar"</string>
+ <string name="files_label" msgid="6051402950202690279">"Fayllar"</string>
<string name="title_open" msgid="4353228937663917801">"Ochish"</string>
<string name="title_save" msgid="2433679664882857999">"Saqlash"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Jild yaratish"</string>
- <string name="menu_grid" msgid="6878021334497835259">"Katakchalar ko‘rinishida"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Yangi jild"</string>
+ <string name="menu_grid" msgid="6878021334497835259">"Katak ko‘rinishida"</string>
<string name="menu_list" msgid="7279285939892417279">"Ro‘yxat ko‘rinishida"</string>
- <string name="menu_sort" msgid="7677740407158414452">"Saralash:"</string>
- <string name="menu_search" msgid="3816712084502856974">"Izlash"</string>
+ <string name="menu_sort" msgid="7677740407158414452">"Saralash"</string>
+ <string name="menu_search" msgid="3816712084502856974">"Qidirish"</string>
<string name="menu_settings" msgid="6008033148948428823">"Sozlamalar"</string>
<string name="menu_open" msgid="432922957274920903">"Ochish"</string>
<string name="menu_save" msgid="2394743337684426338">"Saqlash"</string>
<string name="menu_share" msgid="3075149983979628146">"Ulashish"</string>
<string name="menu_delete" msgid="8138799623850614177">"O‘chirish"</string>
- <string name="menu_select" msgid="8711270657353563424">"“<xliff:g id="DIRECTORY">^1</xliff:g>” jildini tanlash"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Barchasini tanlash"</string>
- <string name="menu_copy" msgid="3612326052677229148">"...ga nusxalash"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Barchasini belgilash"</string>
+ <string name="menu_copy" msgid="3612326052677229148">"Nusxalash…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Ko‘chirib o‘tkazish…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Yangi oyna"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Nusxalash"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Joylash"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Ichki xotirani ko‘rsatish"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"SD kartani ko‘rsatish"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ichki xotirani berkitish"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"SD kartani berkitish"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Fayl hajmini ko‘rsatish"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Fayl hajmini berkitish"</string>
+ <string name="button_select" msgid="527196987259139214">"Tanlash"</string>
<string name="button_copy" msgid="8706475544635021302">"Nusxalash"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> belgilandi"</string>
+ <string name="button_move" msgid="2202666023104202232">"Ko‘chirib o‘tkazish"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"O‘chirish"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Qayta urinish"</string>
<string name="sort_name" msgid="9183560467917256779">"Nomi bo‘yicha"</string>
<string name="sort_date" msgid="586080032956151448">"Tahrir sanasi bo‘yicha"</string>
<string name="sort_size" msgid="3350681319735474741">"Hajmi bo‘yicha"</string>
@@ -48,28 +55,49 @@
<string name="save_error" msgid="6167009778003223664">"Hujjat saqlanmadi"</string>
<string name="create_error" msgid="3735649141335444215">"Jild yaratilmadi"</string>
<string name="query_error" msgid="1222448261663503501">"Hujjatlar so‘rovi jo‘natilmadi"</string>
- <string name="root_recent" msgid="4470053704320518133">"So‘nggi"</string>
+ <string name="root_recent" msgid="4470053704320518133">"Yaqinda"</string>
<string name="root_available_bytes" msgid="8568452858617033281">"<xliff:g id="SIZE">%1$s</xliff:g> bo‘sh"</string>
<string name="root_type_service" msgid="2178854894416775409">"Xotira xizmatlari"</string>
<string name="root_type_shortcut" msgid="3318760609471618093">"Yorliqlar"</string>
<string name="root_type_device" msgid="7121342474653483538">"Qurilmalar"</string>
<string name="root_type_apps" msgid="8838065367985945189">"Ko‘proq dasturlar"</string>
- <string name="empty" msgid="7858882803708117596">"Hech nima yo‘q"</string>
+ <string name="empty" msgid="7858882803708117596">"Hech narsa yo‘q"</string>
<string name="toast_no_application" msgid="1339885974067891667">"Fayl ochilmadi"</string>
<string name="toast_failed_delete" msgid="2180678019407244069">"Ba’zi hujjatlar o‘chirilmadi"</string>
<string name="share_via" msgid="8966594246261344259">"Quyidagi orqali ulashish"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Fayllar nusxalanmoqda"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Ko‘chirib o‘tkazilmoqda"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> qoldi"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
<item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl nusxalanmoqda</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmoqda.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmoqda.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl o‘chirilmoqda.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl o‘chirilmoqda.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Bekor qilish"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Nuxsa olishga tayyorgarlik..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Ko‘chirishga tayyorgarlik…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
<item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan nusxa olinmadi</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl ko‘chirib o‘tkazilmadi</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Batafsil ma’lumot olish uchun bosing"</string>
<string name="retry" msgid="7564024179122207376">"Qayta urinish"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Ushbu fayllardan nusxa olinmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Ushbu fayllar ko‘chirib o‘tkazilmadi: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayldan vaqtinchalik xotiraga nusxa olindi.</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayldan vaqtinchalik xotiraga nusxa olindi.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Tanlangan fayllarni bu yerga joylab bo‘lmadi."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-vi/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-vi/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-vi/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 3bd7d78..52a4e82 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Tài liệu"</string>
+ <string name="files_label" msgid="6051402950202690279">"Tệp"</string>
<string name="title_open" msgid="4353228937663917801">"Mở từ"</string>
<string name="title_save" msgid="2433679664882857999">"Lưu vào"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Tạo thư mục"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Thư mục mới"</string>
<string name="menu_grid" msgid="6878021334497835259">"Chế độ xem lưới"</string>
<string name="menu_list" msgid="7279285939892417279">"Chế độ xem danh sách"</string>
<string name="menu_sort" msgid="7677740407158414452">"Sắp xếp theo"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Lưu"</string>
<string name="menu_share" msgid="3075149983979628146">"Chia sẻ"</string>
<string name="menu_delete" msgid="8138799623850614177">"Xóa"</string>
- <string name="menu_select" msgid="8711270657353563424">"Chọn \"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Chọn tất cả"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Chọn tất cả"</string>
<string name="menu_copy" msgid="3612326052677229148">"Sao chép vào…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Chuyển tới..."</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Cửa sổ mới"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Sao chép"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Dán"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Hiển thị bộ nhớ trong"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Hiển thị thẻ SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Ẩn bộ nhớ trong"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Ẩn thẻ SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Hiển thị kích thước tệp"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Ẩn kích thước tệp"</string>
+ <string name="button_select" msgid="527196987259139214">"Chọn"</string>
<string name="button_copy" msgid="8706475544635021302">"Sao chép"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"Đã chọn <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="button_move" msgid="2202666023104202232">"Di chuyển"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Loại bỏ"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Thử lại"</string>
<string name="sort_name" msgid="9183560467917256779">"Theo tên"</string>
<string name="sort_date" msgid="586080032956151448">"Theo ngày sửa đổi"</string>
<string name="sort_size" msgid="3350681319735474741">"Theo kích thước"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Không thể xóa một số tài liệu"</string>
<string name="share_via" msgid="8966594246261344259">"Chia sẻ qua"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Đang sao chép tệp"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Đang di chuyển tệp"</string>
<string name="copy_remaining" msgid="6283790937387975095">"Còn <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">Đang sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
<item quantity="one">Đang sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">Đang di chuyển <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
+ <item quantity="one">Đang di chuyển <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp.</item>
+ <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Hoàn tác"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Đang chuẩn bị sao chép…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Đang chuẩn bị di chuyển…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">Không thể sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
<item quantity="one">Không thể sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">Không thể di chuyển <xliff:g id="COUNT_1">%1$d</xliff:g> tệp</item>
+ <item quantity="one">Không thể di chuyển <xliff:g id="COUNT_0">%1$d</xliff:g> tệp</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Chạm để xem chi tiết"</string>
<string name="retry" msgid="7564024179122207376">"Thử lại"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Những tệp này chưa được sao chép: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Những tệp này chưa được di chuyển: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">Đã sao chép <xliff:g id="COUNT_1">%1$d</xliff:g> tệp vào khay nhớ tạm.</item>
+ <item quantity="one">Đã sao chép <xliff:g id="COUNT_0">%1$d</xliff:g> tệp vào khay nhớ tạm.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Không thể dán các tệp đã chọn vào vị trí này."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-zh-rCN/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-zh-rCN/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-zh-rCN/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 96e3e3d..8ee90cc 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文档"</string>
+ <string name="files_label" msgid="6051402950202690279">"文件"</string>
<string name="title_open" msgid="4353228937663917801">"打开文件"</string>
<string name="title_save" msgid="2433679664882857999">"保存文件"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"新建文件夹"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"新建文件夹"</string>
<string name="menu_grid" msgid="6878021334497835259">"网格视图"</string>
<string name="menu_list" msgid="7279285939892417279">"列表视图"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序依据"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"保存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
<string name="menu_delete" msgid="8138799623850614177">"删除"</string>
- <string name="menu_select" msgid="8711270657353563424">"选择“<xliff:g id="DIRECTORY">^1</xliff:g>”"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"全选"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"全选"</string>
<string name="menu_copy" msgid="3612326052677229148">"复制到…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"移动到…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"新建窗口"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"复制"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"粘贴"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"显示内部存储设备"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"显示SD卡"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隐藏内部存储设备"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"隐藏SD卡"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"显示文件大小"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"隐藏文件大小"</string>
+ <string name="button_select" msgid="527196987259139214">"选择"</string>
<string name="button_copy" msgid="8706475544635021302">"复制"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"已选择<xliff:g id="COUNT">%1$d</xliff:g>项"</string>
+ <string name="button_move" msgid="2202666023104202232">"移动"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"关闭"</string>
+ <string name="button_retry" msgid="4392027584153752797">"重试"</string>
<string name="sort_name" msgid="9183560467917256779">"按名称"</string>
<string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
<string name="sort_size" msgid="3350681319735474741">"按大小"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"无法删除部分文档"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"正在复制文件"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"正在移动文件"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩余时间:<xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
<item quantity="one">正在复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">正在移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
+ <item quantity="one">正在移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">正在删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件。</item>
+ <item quantity="one">正在删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件。</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"撤消"</string>
<string name="copy_preparing" msgid="3896202461003039386">"正在准备复制…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"正在准备移动…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">无法复制 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
<item quantity="one">无法复制 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">无法移动 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件</item>
+ <item quantity="one">无法移动 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"触摸可查看详情"</string>
<string name="retry" msgid="7564024179122207376">"重试"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"以下文件无法复制:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"以下文件无法移动:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">已将 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件复制到剪贴板。</item>
+ <item quantity="one">已将 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件复制到剪贴板。</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"无法将所选文件粘贴到此位置。"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-zh-rHK/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-zh-rHK/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-zh-rHK/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 1fa402e..dadc029 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
+ <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"新增資料夾"</string>
<string name="menu_grid" msgid="6878021334497835259">"格狀檢視"</string>
<string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序方式"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"分享"</string>
<string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
- <string name="menu_select" msgid="8711270657353563424">"選取「<xliff:g id="DIRECTORY">^1</xliff:g>」"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"全部選取"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"全部選取"</string>
<string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"移至…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"新視窗"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"複製"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼上"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"顯示內部儲存空間"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"顯示 SD 卡"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隱藏內部儲存空間"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"隱藏 SD 卡"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"顯示檔案大小"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"隱藏檔案大小"</string>
+ <string name="button_select" msgid="527196987259139214">"選取"</string>
<string name="button_copy" msgid="8706475544635021302">"複製"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個"</string>
+ <string name="button_move" msgid="2202666023104202232">"移動"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"關閉"</string>
+ <string name="button_retry" msgid="4392027584153752797">"再試一次"</string>
<string name="sort_name" msgid="9183560467917256779">"按名稱"</string>
<string name="sort_date" msgid="586080032956151448">"按修改日期"</string>
<string name="sort_size" msgid="3350681319735474741">"按大小"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"正在複製檔案"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"正在移動檔案"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
<item quantity="one">正在複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">正在轉移 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+ <item quantity="one">正在轉移 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">正在刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+ <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"復原"</string>
<string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"正在準備移動…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">未能移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
+ <item quantity="one">未能移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"輕觸即可查看詳情"</string>
<string name="retry" msgid="7564024179122207376">"重試"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"以下檔案未能複製:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"這些檔案並未移動:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">已複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案到剪貼簿。</item>
+ <item quantity="one">已複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案到剪貼簿。</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法在此位置貼上選取檔案。"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-zh-rTW/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-zh-rTW/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-zh-rTW/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8de8402..cdd1288 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"文件"</string>
+ <string name="files_label" msgid="6051402950202690279">"檔案"</string>
<string name="title_open" msgid="4353228937663917801">"開啟檔案"</string>
<string name="title_save" msgid="2433679664882857999">"儲存至"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"建立資料夾"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"新增資料夾"</string>
<string name="menu_grid" msgid="6878021334497835259">"格狀檢視"</string>
<string name="menu_list" msgid="7279285939892417279">"清單檢視"</string>
<string name="menu_sort" msgid="7677740407158414452">"排序依據"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"儲存"</string>
<string name="menu_share" msgid="3075149983979628146">"共用"</string>
<string name="menu_delete" msgid="8138799623850614177">"刪除"</string>
- <string name="menu_select" msgid="8711270657353563424">"選取「<xliff:g id="DIRECTORY">^1</xliff:g>」"</string>
- <string name="menu_select_all" msgid="4320518282375109902">"全選"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"全選"</string>
<string name="menu_copy" msgid="3612326052677229148">"複製到…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"移至…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"新視窗"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"複製"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"貼上"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"顯示內部儲存空間"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"顯示 SD 卡"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"隱藏內部儲存空間"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"隱藏 SD 卡"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"顯示檔案大小"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"隱藏檔案大小"</string>
+ <string name="button_select" msgid="527196987259139214">"選取"</string>
<string name="button_copy" msgid="8706475544635021302">"複製"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"已選取 <xliff:g id="COUNT">%1$d</xliff:g> 個項目"</string>
+ <string name="button_move" msgid="2202666023104202232">"移動"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"關閉"</string>
+ <string name="button_retry" msgid="4392027584153752797">"再試一次"</string>
<string name="sort_name" msgid="9183560467917256779">"依名稱"</string>
<string name="sort_date" msgid="586080032956151448">"依修改日期"</string>
<string name="sort_size" msgid="3350681319735474741">"依大小"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"無法刪除部分文件"</string>
<string name="share_via" msgid="8966594246261344259">"分享方式:"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"複製檔案"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"正在移動檔案"</string>
<string name="copy_remaining" msgid="6283790937387975095">"剩餘 <xliff:g id="DURATION">%s</xliff:g>"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="other">正在複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
<item quantity="one">正在複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="other">正在移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+ <item quantity="one">正在移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="other">正在刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案。</item>
+ <item quantity="one">正在刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案。</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"復原"</string>
<string name="copy_preparing" msgid="3896202461003039386">"正在準備複製…"</string>
+ <string name="move_preparing" msgid="2772219441375531410">"準備移動…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="other">無法複製 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
<item quantity="one">無法複製 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="other">無法移動 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案</item>
+ <item quantity="one">無法移動 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案</item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"輕觸即可查看詳細資料"</string>
<string name="retry" msgid="7564024179122207376">"重試"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"未複製這些檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"未移動以下檔案:<xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="other">已將 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案複製到剪貼簿。</item>
+ <item quantity="one">已將 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案複製到剪貼簿。</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"無法將所選檔案貼到這個位置。"</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values-zu/config.xml
similarity index 63%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values-zu/config.xml
index 3f50fb9..843a8aa 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values-zu/config.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,9 +12,9 @@
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.
--->
+ -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="trusted_quick_viewer_package" msgid="3354383993907861267"></string>
+</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 78dd0a6..d6bb2b4 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -17,9 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_label" msgid="2783841764617238354">"Amadokhumenti"</string>
+ <string name="files_label" msgid="6051402950202690279">"Amafayela"</string>
<string name="title_open" msgid="4353228937663917801">"Vula kusuka ku-"</string>
<string name="title_save" msgid="2433679664882857999">"Londoloza ku-"</string>
- <string name="menu_create_dir" msgid="5947289605844398389">"Dala ifolda"</string>
+ <string name="menu_create_dir" msgid="2547620241173881754">"Ifolda entsha"</string>
<string name="menu_grid" msgid="6878021334497835259">"Ukubuka kwegridi"</string>
<string name="menu_list" msgid="7279285939892417279">"Ukubuka uhlu"</string>
<string name="menu_sort" msgid="7677740407158414452">"Hlunga nge-"</string>
@@ -29,17 +30,23 @@
<string name="menu_save" msgid="2394743337684426338">"Londoloza"</string>
<string name="menu_share" msgid="3075149983979628146">"Yabelana"</string>
<string name="menu_delete" msgid="8138799623850614177">"Susa"</string>
- <string name="menu_select" msgid="8711270657353563424">"Khetha i-\"<xliff:g id="DIRECTORY">^1</xliff:g>\""</string>
- <string name="menu_select_all" msgid="4320518282375109902">"Khetha konke"</string>
+ <string name="menu_select_all" msgid="8323579667348729928">"Khetha konke"</string>
<string name="menu_copy" msgid="3612326052677229148">"Kopishela ku…"</string>
+ <string name="menu_move" msgid="1828090633118079817">"Hambisa ku…"</string>
+ <string name="menu_new_window" msgid="1226032889278727538">"Iwindi elisha"</string>
+ <string name="menu_copy_to_clipboard" msgid="489311381979634291">"Kopisha"</string>
+ <string name="menu_paste_from_clipboard" msgid="2071583031180257091">"Namathisela"</string>
<string name="menu_advanced_show" product="nosdcard" msgid="4693652895715631401">"Bonisa isitoreji sangaphakathi"</string>
<string name="menu_advanced_show" product="default" msgid="5792182900084144261">"Bonisa ikhadi le-SD"</string>
<string name="menu_advanced_hide" product="nosdcard" msgid="4218809952721972589">"Fihla isitoreji sangaphakathi"</string>
<string name="menu_advanced_hide" product="default" msgid="4845869969015718848">"Fihla ikhadi le-SD"</string>
<string name="menu_file_size_show" msgid="3240323619260823076">"Bonisa usayizi wefayela"</string>
<string name="menu_file_size_hide" msgid="8881975928502581042">"Fihla usayizi wefayela"</string>
+ <string name="button_select" msgid="527196987259139214">"Khetha"</string>
<string name="button_copy" msgid="8706475544635021302">"Kopisha"</string>
- <string name="mode_selected_count" msgid="459111894725594625">"<xliff:g id="COUNT">%1$d</xliff:g> okukhethiwe"</string>
+ <string name="button_move" msgid="2202666023104202232">"Hambisa"</string>
+ <string name="button_dismiss" msgid="3714065566893946085">"Cashisa"</string>
+ <string name="button_retry" msgid="4392027584153752797">"Zama futhi"</string>
<string name="sort_name" msgid="9183560467917256779">"Ngegama"</string>
<string name="sort_date" msgid="586080032956151448">"Ngedethi yokuguqula"</string>
<string name="sort_size" msgid="3350681319735474741">"Ngosayizi"</string>
@@ -59,17 +66,38 @@
<string name="toast_failed_delete" msgid="2180678019407244069">"Ayikwazi ukususa amanye amadokhumenti"</string>
<string name="share_via" msgid="8966594246261344259">"Yabelana nge-"</string>
<string name="copy_notification_title" msgid="6374299806748219777">"Ikopisha amafayela"</string>
+ <string name="move_notification_title" msgid="6193835179777284805">"Ihambisa amafayela"</string>
<string name="copy_remaining" msgid="6283790937387975095">"<xliff:g id="DURATION">%s</xliff:g> okusele"</string>
<plurals name="copy_begin" formatted="false" msgid="9071199452634086365">
<item quantity="one">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
<item quantity="other">Ikopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
</plurals>
+ <plurals name="move_begin" formatted="false" msgid="8430330882138871643">
+ <item quantity="one">Ihambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ <item quantity="other">Ihambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ </plurals>
+ <plurals name="deleting" formatted="false" msgid="5054338566802559411">
+ <item quantity="one">Isusa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ <item quantity="other">Isusa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>.</item>
+ </plurals>
+ <string name="undo" msgid="7905788502491742328">"Hlehlisa"</string>
<string name="copy_preparing" msgid="3896202461003039386">"Ilungiselela ukukopisha..."</string>
+ <string name="move_preparing" msgid="2772219441375531410">"Ilungiselela ukuhambisa…"</string>
<plurals name="copy_error_notification_title" formatted="false" msgid="5267616889076217261">
<item quantity="one">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
<item quantity="other">Ayikwazanga ukukopisha amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
</plurals>
+ <plurals name="move_error_notification_title" formatted="false" msgid="2779299594174898891">
+ <item quantity="one">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Ayikwazanga ukuhambisa amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
<string name="notification_touch_for_details" msgid="4483108577842961665">"Thinta ukuze ubuke imininingwane"</string>
<string name="retry" msgid="7564024179122207376">"Zama futhi"</string>
<string name="copy_failure_alert_content" msgid="3715575000297709082">"Lawa mafayela awazange akopishwe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <string name="move_failure_alert_content" msgid="7151140279020481180">"Lawa mafayela awazange ahanjiswe: <xliff:g id="LIST">%1$s</xliff:g>"</string>
+ <plurals name="clipboard_files_clipped" formatted="false" msgid="855459017537058539">
+ <item quantity="one">Kukopishwe amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g> kubhodi lokunamathisela.</item>
+ <item quantity="other">Kukopishwe amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g> kubhodi lokunamathisela.</item>
+ </plurals>
+ <string name="clipboard_files_cannot_paste" msgid="2878324825602325706">"Ayikwazi ukunamathisela amafayela akhethiwe kule ndawo."</string>
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values/attrs.xml
similarity index 72%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values/attrs.xml
index 3f50fb9..0afc3a2 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values/attrs.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,8 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources>
+ <declare-styleable name="DocumentsBaseTheme">
+ <attr name="colorActionMode" format="color"/>
+ </declare-styleable>
+</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 2b839d4..153c673 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -15,8 +15,22 @@
-->
<resources>
- <color name="material_grey_300">#ffeeeeee</color>
+ <color name="material_grey_400">#ffbdbdbd</color>
- <color name="item_doc_grid_background">@color/material_grey_300</color>
- <color name="item_doc_grid_protect_background">#88000000</color>
+ <!-- This is the window background, but also the background for anything
+ else that needs to manually declare a background matching the "default"
+ app background (e.g. the drawer overlay). -->
+ <color name="window_background">#fff1f1f1</color>
+
+ <color name="primary_dark">@*android:color/primary_dark_material_dark</color>
+ <color name="primary">@*android:color/material_blue_grey_900</color>
+ <color name="accent">@*android:color/accent_material_light</color>
+ <color name="action_mode">@color/material_grey_400</color>
+
+ <color name="band_select_background">#88ffffff</color>
+ <color name="band_select_border">#44000000</color>
+
+ <color name="item_doc_background">#fffafafa</color>
+ <color name="item_doc_background_selected">#ffe0f2f1</color>
+
</resources>
diff --git a/res/color/item_doc_grid_overlay.xml b/res/values/config.xml
similarity index 62%
copy from res/color/item_doc_grid_overlay.xml
copy to res/values/config.xml
index 6959c65..ff28e15 100644
--- a/res/color/item_doc_grid_overlay.xml
+++ b/res/values/config.xml
@@ -14,14 +14,11 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_activated="true"
- android:color="?android:attr/colorControlHighlight" />
- <item
- android:state_enabled="false"
- android:color="?android:attr/colorBackground"
- android:alpha="0.5" />
- <item
- android:color="@android:color/transparent" />
-</selector>
\ No newline at end of file
+<resources>
+ <!-- Allow Advanced Devices default value to be customised -->
+ <bool name="config_defaultAdvancedDevices">false</bool>
+
+ <bool name="productivity_device">true</bool>
+ <!-- Intentionally unset. Vendors should set this in an overlay. -->
+ <string name="trusted_quick_viewer_package"></string>
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 06f65e2..f94a00e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -17,13 +17,14 @@
<resources>
<dimen name="icon_size">40dp</dimen>
<dimen name="root_icon_size">24dp</dimen>
+ <dimen name="root_icon_margin">0dp</dimen>
<dimen name="grid_width">152dp</dimen>
<dimen name="grid_height">176dp</dimen>
<dimen name="grid_item_width">152dp</dimen>
<dimen name="grid_item_height">176dp</dimen>
- <dimen name="grid_item_padding">4dp</dimen>
+ <dimen name="grid_item_margin">4dp</dimen>
<dimen name="grid_padding_horiz">4dp</dimen>
<dimen name="grid_padding_vert">4dp</dimen>
@@ -39,4 +40,6 @@
<dimen name="dir_elevation">8dp</dimen>
+ <dimen name="drag_shadow_size">120dp</dimen>
+
</resources>
diff --git a/res/drawable/item_doc_grid_overlay.xml b/res/values/layouts.xml
similarity index 65%
copy from res/drawable/item_doc_grid_overlay.xml
copy to res/values/layouts.xml
index 3f50fb9..8ac1ac2 100644
--- a/res/drawable/item_doc_grid_overlay.xml
+++ b/res/values/layouts.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="@color/item_doc_grid_overlay" />
-</shape>
+<resources>
+ <item name="docs_activity" type="layout">@layout/drawer_layout</item>
+ <item name="files_activity" type="layout">@layout/drawer_layout</item>
+ <item name="manage_roots_activity" type="layout">@layout/single_pane_layout</item>
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a4e6ce7..016657e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,13 +18,19 @@
<!-- Title of the documents application [CHAR LIMIT=32] -->
<string name="app_label">Documents</string>
+ <!-- Title of the standalone files activity. [CHAR LIMIT=32] -->
+ <string name="files_label">Files</string>
+
+ <!-- Title of the standalone downloads activity. [CHAR LIMIT=32] -->
+ <string name="downloads_label">Downloads</string>
+
<!-- Action bar title prompting user to choose a location to open a document from [CHAR LIMIT=32] -->
<string name="title_open">Open from</string>
<!-- Action bar title prompting user to choose a location to save a document to [CHAR LIMIT=32] -->
<string name="title_save">Save to</string>
<!-- Menu item that creates a new directory/folder at the current location [CHAR LIMIT=24] -->
- <string name="menu_create_dir">Create folder</string>
+ <string name="menu_create_dir">New folder</string>
<!-- Menu item that switches view to show documents as a large-format grid of thumbnails [CHAR LIMIT=24] -->
<string name="menu_grid">Grid view</string>
<!-- Menu item that switches view to show documents as a list [CHAR LIMIT=24] -->
@@ -48,6 +54,15 @@
<string name="menu_select_all">Select all</string>
<!-- Menu item title that copies the selected documents [CHAR LIMIT=24] -->
<string name="menu_copy">Copy to\u2026</string>
+ <!-- Menu item title that moves the selected documents [CHAR LIMIT=24] -->
+ <string name="menu_move">Move to\u2026</string>
+
+ <!-- Menu item title that creates a new window in the activity [CHAR LIMIT=24] -->
+ <string name="menu_new_window">New window</string>
+ <!-- Menu item title that copies the selected documents to clipboard [CHAR LIMIT=24] -->
+ <string name="menu_copy_to_clipboard">Copy</string>
+ <!-- Menu item title that pastes files from the clipboard [CHAR LIMIT=24] -->
+ <string name="menu_paste_from_clipboard">Paste</string>
<!-- Menu item that reveals internal storage built into the device [CHAR LIMIT=24] -->
<string name="menu_advanced_show" product="nosdcard">Show internal storage</string>
@@ -67,7 +82,12 @@
<string name="button_select">Select</string>
<!-- Button label that copies files to the current directory [CHAR LIMIT=24] -->
<string name="button_copy">Copy</string>
-
+ <!-- Button label that moves files to the current directory [CHAR LIMIT=24] -->
+ <string name="button_move">Move</string>
+ <!-- Button label that hides the error bar [CHAR LIMIT=24] -->
+ <string name="button_dismiss">Dismiss</string>
+ <string name="button_retry">Try Again</string>
+
<!-- Mode that sorts documents by their display name alphabetically [CHAR LIMIT=24] -->
<string name="sort_name">By name</string>
<!-- Mode that sorts documents by their last modified time in descending order; most recent first [CHAR LIMIT=24] -->
@@ -114,6 +134,8 @@
<!-- Title of the copy notification [CHAR LIMIT=24] -->
<string name="copy_notification_title">Copying files</string>
+ <!-- Title of the move notification [CHAR LIMIT=24] -->
+ <string name="move_notification_title">Moving files</string>
<!-- Text shown on the copy notification to indicate remaining time, in minutes [CHAR LIMIT=24] -->
<string name="copy_remaining"><xliff:g id="duration" example="3 minutes">%s</xliff:g> left</string>
<!-- Toast shown when a file copy is kicked off -->
@@ -121,17 +143,44 @@
<item quantity="one">Copying <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
<item quantity="other">Copying <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
</plurals>
- <!-- Text shown on the copy notification while DocumentsUI performs setup in preparation for copying files [CHAR LIMIT=32] -->
+ <plurals name="move_begin">
+ <item quantity="one">Moving <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
+ <item quantity="other">Moving <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
+ </plurals>
+ <!-- Text shown when files are deleted -->
+ <plurals name="deleting">
+ <item quantity="one">Deleting <xliff:g id="count" example="1">%1$d</xliff:g> file.</item>
+ <item quantity="other">Deleting <xliff:g id="count" example="3">%1$d</xliff:g> files.</item>
+ </plurals>
+ <!-- Text shown for the undo button -->
+ <string name="undo">Undo</string>
+ <!-- Text shown on the notification while DocumentsUI performs setup in preparation for copying files [CHAR LIMIT=32] -->
<string name="copy_preparing">Preparing for copy\u2026</string>
+ <!-- Text shown on the notification while DocumentsUI performs setup in preparation for moving files [CHAR LIMIT=32] -->
+ <string name="move_preparing">Preparing for move\u2026</string>
<!-- Title of the copy error notification [CHAR LIMIT=48] -->
<plurals name="copy_error_notification_title">
<item quantity="one">Couldn\'t copy <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
<item quantity="other">Couldn\'t copy <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
</plurals>
+ <!-- Title of the move error notification [CHAR LIMIT=48] -->
+ <plurals name="move_error_notification_title">
+ <item quantity="one">Couldn\'t move <xliff:g id="count" example="1">%1$d</xliff:g> file</item>
+ <item quantity="other">Couldn\'t move <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
+ </plurals>
<!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
<string name="notification_touch_for_details">Touch to view details</string>
<!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
<string name="retry">Retry</string>
<!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
<string name="copy_failure_alert_content">These files weren\'t copied: <xliff:g id="list">%1$s</xliff:g></string>
+ <!-- Contents of the moving failure alert dialog. [CHAR LIMIT=48] -->
+ <string name="move_failure_alert_content">These files weren\'t moved: <xliff:g id="list">%1$s</xliff:g></string>
+ <!-- Toast shown when a user copies files to clipboard. -->
+ <plurals name="clipboard_files_clipped">
+ <item quantity="one">Copied <xliff:g id="count" example="1">%1$d</xliff:g> file to clipboard.</item>
+ <item quantity="other">Copied <xliff:g id="count" example="3">%1$d</xliff:g> files to clipboard.</item>
+ </plurals>
+ <!-- Toast shown when a user tries to paste files into an unsupported location. -->
+ <string name="clipboard_files_cannot_paste">Cannot paste the selected files in this location.</string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8c4b777..6712e2d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -16,16 +16,20 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="DialogWhenReallyLarge" parent="@android:style/Theme.DeviceDefault.Light.DarkActionBar" />
+ <style name="DocumentsBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar" />
+ <style name="ActionBarTheme" parent="@*android:style/ThemeOverlay.Material.Dark.ActionBar" />
+ <style name="ActionBarPopupTheme" parent="@*android:style/ThemeOverlay.Material.Light" />
- <style name="DocumentsTheme" parent="@style/DialogWhenReallyLarge">
- <item name="android:actionBarWidgetTheme">@null</item>
- <item name="android:actionBarTheme">@*android:style/ThemeOverlay.Material.Dark.ActionBar</item>
- <item name="android:actionBarPopupTheme">@*android:style/ThemeOverlay.Material.Light</item>
+ <style name="DocumentsTheme" parent="@style/DocumentsBaseTheme">
+ <item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarTheme">@style/ActionBarTheme</item>
+ <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
- <item name="android:colorPrimaryDark">@*android:color/material_blue_grey_900</item>
- <item name="android:colorPrimary">@*android:color/material_blue_grey_800</item>
- <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
+ <item name="android:windowBackground">@color/window_background</item>
+ <item name="android:colorPrimaryDark">@color/primary_dark</item>
+ <item name="android:colorPrimary">@color/primary</item>
+ <item name="android:colorAccent">@color/accent</item>
+ <item name="colorActionMode">@color/action_mode</item>
<item name="android:listDivider">@*android:drawable/list_divider_material</item>
@@ -36,4 +40,30 @@
<item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
</style>
+ <style name="DocumentsFullScreenTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
+ <item name="actionBarWidgetTheme">@null</item>
+ <item name="actionBarTheme">@style/ActionBarTheme</item>
+ <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
+
+ <item name="android:windowBackground">@color/window_background</item>
+ <item name="android:colorPrimaryDark">@color/primary_dark</item>
+ <item name="android:colorPrimary">@color/primary</item>
+ <item name="android:colorAccent">@color/accent</item>
+ <item name="colorActionMode">@color/action_mode</item>
+
+ <item name="android:listDivider">@*android:drawable/list_divider_material</item>
+
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowActionModeOverlay">true</item>
+ <item name="android:windowNoTitle">true</item>
+
+ <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+ </style>
+
+ <style name="TrimmedHorizontalProgressBar" parent="android:Widget.Material.ProgressBar.Horizontal">
+ <item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material_trimmed</item>
+ <item name="android:minHeight">3dp</item>
+ <item name="android:maxHeight">3dp</item>
+ </style>
+
</resources>
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index fc46716..0f25016 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -16,19 +16,13 @@
package com.android.documentsui;
-import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
-import static com.android.documentsui.DirectoryFragment.ANIM_SIDE;
-import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_DOWN;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_SIDE;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_UP;
+import static com.android.internal.util.Preconditions.checkArgument;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-import libcore.io.IoUtils;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
@@ -40,12 +34,12 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.Nullable;
import android.util.Log;
-import android.util.SparseArray;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -61,54 +55,67 @@
import android.widget.TextView;
import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Maps;
-abstract class BaseActivity extends Activity {
+import libcore.io.IoUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public abstract class BaseActivity extends Activity {
static final String EXTRA_STATE = "state";
+ State mState;
RootsCache mRoots;
SearchManager mSearchManager;
+ DrawerController mDrawer;
+ boolean mProductivityDevice;
private final String mTag;
+ @LayoutRes
+ private int mLayoutId;
+ private DirectoryContainerView mDirectoryContainer;
- public abstract State getDisplayState();
- public abstract void onDocumentPicked(DocumentInfo doc);
+ public abstract void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings);
public abstract void onDocumentsPicked(List<DocumentInfo> docs);
+
abstract void onTaskFinished(Uri... uris);
abstract void onDirectoryChanged(int anim);
abstract void updateActionBar();
abstract void saveStackBlocking();
+ abstract State buildState();
- public BaseActivity(String tag) {
+ public BaseActivity(@LayoutRes int layoutId, String tag) {
+ mLayoutId = layoutId;
mTag = tag;
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
+
+ mProductivityDevice = getResources().getBoolean(R.bool.productivity_device);
+ mState = (icicle != null)
+ ? icicle.<State>getParcelable(EXTRA_STATE)
+ : buildState();
+
+ setContentView(mLayoutId);
+
mRoots = DocumentsApplication.getRootsCache(this);
+ mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
mSearchManager = new SearchManager();
- }
- @Override
- public void onResume() {
- super.onResume();
-
- final State state = getDisplayState();
- final RootInfo root = getCurrentRoot();
-
- // If we're browsing a specific root, and that root went away, then we
- // have no reason to hang around
- if (state.action == State.ACTION_BROWSE && root != null) {
- if (mRoots.getRootBlocking(root.authority, root.rootId) == null) {
- finish();
- }
- }
+ // Base classes must update result in their onCreate.
+ setResult(Activity.RESULT_CANCELED);
}
@Override
@@ -123,48 +130,70 @@
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
- boolean shown = super.onPrepareOptionsMenu(menu);
+ super.onPrepareOptionsMenu(menu);
final RootInfo root = getCurrentRoot();
- final DocumentInfo cwd = getCurrentDirectory();
+ final boolean inRecents = getCurrentDirectory() == null;
final MenuItem sort = menu.findItem(R.id.menu_sort);
final MenuItem sortSize = menu.findItem(R.id.menu_sort_size);
final MenuItem grid = menu.findItem(R.id.menu_grid);
final MenuItem list = menu.findItem(R.id.menu_list);
-
final MenuItem advanced = menu.findItem(R.id.menu_advanced);
final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
+ final MenuItem settings = menu.findItem(R.id.menu_settings);
- mSearchManager.update(root);
+ // I'm thinkin' this isn't necesary here. If it is...'cuz of a bug....
+ // then uncomment the linke and let's get a proper bug reference here.
+ // mSearchManager.update(root);
// Search uses backend ranking; no sorting
- sort.setVisible(cwd != null && !mSearchManager.isSearching());
+ sort.setVisible(!inRecents && !mSearchManager.isSearching());
- State state = getDisplayState();
- grid.setVisible(state.derivedMode != State.MODE_GRID);
- list.setVisible(state.derivedMode != State.MODE_LIST);
+ // grid/list is effectively a toggle.
+ grid.setVisible(mState.derivedMode != State.MODE_GRID);
+ list.setVisible(mState.derivedMode != State.MODE_LIST);
- // Only sort by size when visible
- sortSize.setVisible(state.showSize);
+ sortSize.setVisible(mState.showSize); // Only sort by size when visible
+ fileSize.setVisible(!mState.forceSize);
+ advanced.setVisible(!mState.forceAdvanced);
+ settings.setVisible((root.flags & Root.FLAG_HAS_SETTINGS) != 0);
advanced.setTitle(LocalPreferences.getDisplayAdvancedDevices(this)
? R.string.menu_advanced_hide : R.string.menu_advanced_show);
fileSize.setTitle(LocalPreferences.getDisplayFileSize(this)
? R.string.menu_file_size_hide : R.string.menu_file_size_show);
- return shown;
+ return true;
+ }
+
+ State buildDefaultState() {
+ State state = new State();
+
+ final Intent intent = getIntent();
+
+ state.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
+
+ state.forceSize = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_FILESIZE, false);
+ state.showSize = state.forceSize || LocalPreferences.getDisplayFileSize(this);
+
+ state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
+ state.showAdvanced = state.forceAdvanced
+ || LocalPreferences.getDisplayAdvancedDevices(this);
+
+ state.initAcceptMimes(intent);
+ state.excludedAuthorities = getExcludedAuthorities();
+
+ return state;
}
void onStackRestored(boolean restored, boolean external) {}
void onRootPicked(RootInfo root) {
- State state = getDisplayState();
-
// Clear entire backstack and start in new root
- state.stack.root = root;
- state.stack.clear();
- state.stackTouched = true;
+ mState.stack.root = root;
+ mState.stack.clear();
+ mState.stackTouched = true;
mSearchManager.update(root);
@@ -174,7 +203,7 @@
if (mRoots.isRecentsRoot(root)) {
onCurrentDirectoryChanged(ANIM_SIDE);
} else {
- new PickRootTask(root).executeOnExecutor(getCurrentExecutor());
+ new PickRootTask(root).executeOnExecutor(getExecutorForCurrentDirectory());
}
}
@@ -184,6 +213,7 @@
switch (item.getItemId()) {
case R.id.menu_advanced:
case R.id.menu_file_size:
+ case R.id.menu_new_window:
break;
default:
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
@@ -193,46 +223,90 @@
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- final int id = item.getItemId();
- if (id == android.R.id.home) {
- onBackPressed();
- return true;
- } else if (id == R.id.menu_create_dir) {
- CreateDirectoryFragment.show(getFragmentManager());
- return true;
- } else if (id == R.id.menu_search) {
- return false;
- } else if (id == R.id.menu_sort_name) {
- setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME);
- return true;
- } else if (id == R.id.menu_sort_date) {
- setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
- return true;
- } else if (id == R.id.menu_sort_size) {
- setUserSortOrder(State.SORT_ORDER_SIZE);
- return true;
- } else if (id == R.id.menu_grid) {
- setUserMode(State.MODE_GRID);
- return true;
- } else if (id == R.id.menu_list) {
- setUserMode(State.MODE_LIST);
- return true;
- } else if (id == R.id.menu_advanced) {
- setDisplayAdvancedDevices(!LocalPreferences.getDisplayAdvancedDevices(this));
- return true;
- } else if (id == R.id.menu_file_size) {
- setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
- return true;
- } else if (id == R.id.menu_settings) {
- final RootInfo root = getCurrentRoot();
- final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
- intent.setDataAndType(DocumentsContract.buildRootUri(root.authority, root.rootId),
- DocumentsContract.Root.MIME_TYPE_ITEM);
- startActivity(intent);
- return true;
- }
- return super.onOptionsItemSelected(item);
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+
+ case R.id.menu_create_dir:
+ showCreateDirectoryDialog();
+ return true;
+
+ case R.id.menu_search:
+ return false;
+
+ case R.id.menu_sort_name:
+ setUserSortOrder(State.SORT_ORDER_DISPLAY_NAME);
+ return true;
+
+ case R.id.menu_sort_date:
+ setUserSortOrder(State.SORT_ORDER_LAST_MODIFIED);
+ return true;
+ case R.id.menu_sort_size:
+ setUserSortOrder(State.SORT_ORDER_SIZE);
+ return true;
+
+ case R.id.menu_grid:
+ setUserMode(State.MODE_GRID);
+ return true;
+
+ case R.id.menu_list:
+ setUserMode(State.MODE_LIST);
+ return true;
+
+ case R.id.menu_paste_from_clipboard:
+ DirectoryFragment.get(getFragmentManager())
+ .pasteFromClipboard();
+ return true;
+
+ case R.id.menu_advanced:
+ setDisplayAdvancedDevices(!LocalPreferences.getDisplayAdvancedDevices(this));
+ return true;
+
+ case R.id.menu_file_size:
+ setDisplayFileSize(!LocalPreferences.getDisplayFileSize(this));
+ return true;
+
+ case R.id.menu_settings:
+ final RootInfo root = getCurrentRoot();
+ final Intent intent = new Intent(DocumentsContract.ACTION_DOCUMENT_ROOT_SETTINGS);
+ intent.setDataAndType(root.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
+ startActivity(intent);
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ void showCreateDirectoryDialog() {
+ CreateDirectoryFragment.show(getFragmentManager());
+ }
+
+ /**
+ * Returns true if a directory can be created in the current location.
+ * @return
+ */
+ boolean canCreateDirectory() {
+ final RootInfo root = getCurrentRoot();
+ final DocumentInfo cwd = getCurrentDirectory();
+ return cwd != null
+ && cwd.isCreateSupported()
+ && !mSearchManager.isSearching()
+ && !root.isRecents()
+ && !root.isDownloads();
+ }
+
+ void onDirectoryCreated(DocumentInfo doc) {
+ checkArgument(doc.isDirectory());
+ openDirectory(doc);
+ }
+
+ void openDirectory(DocumentInfo doc) {
+ mState.stack.push(doc);
+ mState.stackTouched = true;
+ onCurrentDirectoryChanged(ANIM_DOWN);
}
/**
@@ -241,6 +315,7 @@
* @param anim
*/
final void onCurrentDirectoryChanged(int anim) {
+ mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
onDirectoryChanged(anim);
final RootsFragment roots = RootsFragment.get(getFragmentManager());
@@ -290,144 +365,25 @@
return (BaseActivity) fragment.getActivity();
}
- public static abstract class DocumentsIntent {
- /** Intent action name to open copy destination. */
- public static String ACTION_OPEN_COPY_DESTINATION =
- "com.android.documentsui.OPEN_COPY_DESTINATION";
-
- /**
- * Extra boolean flag for ACTION_OPEN_COPY_DESTINATION_STRING, which
- * specifies if the destination directory needs to create new directory or not.
- */
- public static String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY";
- }
-
- public static class State implements android.os.Parcelable {
- public int action;
- public String[] acceptMimes;
-
- /** Explicit user choice */
- public int userMode = MODE_UNKNOWN;
- /** Derived after loader */
- public int derivedMode = MODE_LIST;
-
- /** Explicit user choice */
- public int userSortOrder = SORT_ORDER_UNKNOWN;
- /** Derived after loader */
- public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
-
- public boolean allowMultiple = false;
- public boolean showSize = false;
- public boolean localOnly = false;
- public boolean forceAdvanced = false;
- public boolean showAdvanced = false;
- public boolean stackTouched = false;
- public boolean restored = false;
- public boolean directoryCopy = false;
-
- /** Current user navigation stack; empty implies recents. */
- public DocumentStack stack = new DocumentStack();
- /** Currently active search, overriding any stack. */
- public String currentSearch;
-
- /** Instance state for every shown directory */
- public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
-
- /** Currently copying file */
- public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
-
- /** Name of the package that started DocsUI */
- public List<String> excludedAuthorities = new ArrayList<>();
-
- public static final int ACTION_OPEN = 1;
- public static final int ACTION_CREATE = 2;
- public static final int ACTION_GET_CONTENT = 3;
- public static final int ACTION_OPEN_TREE = 4;
- public static final int ACTION_MANAGE = 5;
- public static final int ACTION_BROWSE = 6;
- public static final int ACTION_BROWSE_ALL = 7;
- public static final int ACTION_OPEN_COPY_DESTINATION = 8;
-
- public static final int MODE_UNKNOWN = 0;
- public static final int MODE_LIST = 1;
- public static final int MODE_GRID = 2;
-
- public static final int SORT_ORDER_UNKNOWN = 0;
- public static final int SORT_ORDER_DISPLAY_NAME = 1;
- public static final int SORT_ORDER_LAST_MODIFIED = 2;
- public static final int SORT_ORDER_SIZE = 3;
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(action);
- out.writeInt(userMode);
- out.writeStringArray(acceptMimes);
- out.writeInt(userSortOrder);
- out.writeInt(allowMultiple ? 1 : 0);
- out.writeInt(showSize ? 1 : 0);
- out.writeInt(localOnly ? 1 : 0);
- out.writeInt(forceAdvanced ? 1 : 0);
- out.writeInt(showAdvanced ? 1 : 0);
- out.writeInt(stackTouched ? 1 : 0);
- out.writeInt(restored ? 1 : 0);
- DurableUtils.writeToParcel(out, stack);
- out.writeString(currentSearch);
- out.writeMap(dirState);
- out.writeList(selectedDocumentsForCopy);
- out.writeList(excludedAuthorities);
- }
-
- public static final Creator<State> CREATOR = new Creator<State>() {
- @Override
- public State createFromParcel(Parcel in) {
- final State state = new State();
- state.action = in.readInt();
- state.userMode = in.readInt();
- state.acceptMimes = in.readStringArray();
- state.userSortOrder = in.readInt();
- state.allowMultiple = in.readInt() != 0;
- state.showSize = in.readInt() != 0;
- state.localOnly = in.readInt() != 0;
- state.forceAdvanced = in.readInt() != 0;
- state.showAdvanced = in.readInt() != 0;
- state.stackTouched = in.readInt() != 0;
- state.restored = in.readInt() != 0;
- DurableUtils.readFromParcel(in, state.stack);
- state.currentSearch = in.readString();
- in.readMap(state.dirState, null);
- in.readList(state.selectedDocumentsForCopy, null);
- in.readList(state.excludedAuthorities, null);
- return state;
- }
-
- @Override
- public State[] newArray(int size) {
- return new State[size];
- }
- };
+ public State getDisplayState() {
+ return mState;
}
void setDisplayAdvancedDevices(boolean display) {
- State state = getDisplayState();
LocalPreferences.setDisplayAdvancedDevices(this, display);
- state.showAdvanced = state.forceAdvanced | display;
+ mState.showAdvanced = mState.forceAdvanced | display;
RootsFragment.get(getFragmentManager()).onDisplayStateChanged();
invalidateOptionsMenu();
}
void setDisplayFileSize(boolean display) {
LocalPreferences.setDisplayFileSize(this, display);
- getDisplayState().showSize = display;
+ mState.showSize = display;
DirectoryFragment.get(getFragmentManager()).onDisplayStateChanged();
invalidateOptionsMenu();
}
- void onStateChanged() {
+ public void onStateChanged() {
invalidateOptionsMenu();
}
@@ -435,7 +391,7 @@
* Set state sort order based on explicit user action.
*/
void setUserSortOrder(int sortOrder) {
- getDisplayState().userSortOrder = sortOrder;
+ mState.userSortOrder = sortOrder;
DirectoryFragment.get(getFragmentManager()).onUserSortOrderChanged();
}
@@ -443,7 +399,7 @@
* Set state mode based on explicit user action.
*/
void setUserMode(int mode) {
- getDisplayState().userMode = mode;
+ mState.userMode = mode;
DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
}
@@ -457,7 +413,7 @@
@Override
protected void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
- state.putParcelable(EXTRA_STATE, getDisplayState());
+ state.putParcelable(EXTRA_STATE, mState);
}
@Override
@@ -465,20 +421,19 @@
super.onRestoreInstanceState(state);
}
- RootInfo getCurrentRoot() {
- State state = getDisplayState();
- if (state.stack.root != null) {
- return state.stack.root;
+ public RootInfo getCurrentRoot() {
+ if (mState.stack.root != null) {
+ return mState.stack.root;
} else {
return mRoots.getRecentsRoot();
}
}
public DocumentInfo getCurrentDirectory() {
- return getDisplayState().stack.peek();
+ return mState.stack.peek();
}
- public Executor getCurrentExecutor() {
+ public Executor getExecutorForCurrentDirectory() {
final DocumentInfo cwd = getCurrentDirectory();
if (cwd != null && cwd.authority != null) {
return ProviderExecutor.forAuthority(cwd.authority);
@@ -487,14 +442,37 @@
}
}
+ @Override
+ public void onBackPressed() {
+ // While action bar is expanded, the state stack UI is hidden.
+ if (mSearchManager.cancelSearch()) {
+ return;
+ }
+
+ if (!mState.stackTouched) {
+ super.onBackPressed();
+ return;
+ }
+
+ final int size = mState.stack.size();
+
+ if (mDrawer.isOpen()) {
+ mDrawer.setOpen(false);
+ } else if (size > 1) {
+ mState.stack.pop();
+ onCurrentDirectoryChanged(ANIM_UP);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
public void onStackPicked(DocumentStack stack) {
try {
// Update the restored stack to ensure we have freshest data
stack.updateDocuments(getContentResolver());
- State state = getDisplayState();
- state.stack = stack;
- state.stackTouched = true;
+ mState.stack = stack;
+ mState.stackTouched = true;
onCurrentDirectoryChanged(ANIM_SIDE);
} catch (FileNotFoundException e) {
@@ -524,9 +502,8 @@
@Override
protected void onPostExecute(DocumentInfo result) {
if (result != null) {
- State state = getDisplayState();
- state.stack.push(result);
- state.stackTouched = true;
+ mState.stack.push(result);
+ mState.stackTouched = true;
onCurrentDirectoryChanged(ANIM_SIDE);
}
}
@@ -538,7 +515,9 @@
@Override
protected Void doInBackground(Void... params) {
- State state = getDisplayState();
+ if (DEBUG && !mState.stack.isEmpty()) {
+ Log.w(mTag, "Overwriting existing stack.");
+ }
RootsCache roots = DocumentsApplication.getRootsCache(BaseActivity.this);
// Restore last stack for calling package
@@ -550,7 +529,7 @@
mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0;
final byte[] rawStack = cursor.getBlob(
cursor.getColumnIndex(ResumeColumns.STACK));
- DurableUtils.readFromArray(rawStack, state.stack);
+ DurableUtils.readFromArray(rawStack, mState.stack);
mRestoredStack = true;
}
} catch (IOException e) {
@@ -561,13 +540,13 @@
if (mRestoredStack) {
// Update the restored stack to ensure we have freshest data
- final Collection<RootInfo> matchingRoots = roots.getMatchingRootsBlocking(state);
+ final Collection<RootInfo> matchingRoots = roots.getMatchingRootsBlocking(mState);
try {
- state.stack.updateRoot(matchingRoots);
- state.stack.updateDocuments(getContentResolver());
+ mState.stack.updateRoot(matchingRoots);
+ mState.stack.updateDocuments(getContentResolver());
} catch (FileNotFoundException e) {
Log.w(mTag, "Failed to restore stack: " + e);
- state.stack.reset();
+ mState.stack.reset();
mRestoredStack = false;
}
}
@@ -578,13 +557,36 @@
@Override
protected void onPostExecute(Void result) {
if (isDestroyed()) return;
- getDisplayState().restored = true;
+ mState.restored = true;
onCurrentDirectoryChanged(ANIM_NONE);
-
onStackRestored(mRestoredStack, mExternal);
+ }
+ }
- getDisplayState().restored = true;
- onCurrentDirectoryChanged(ANIM_NONE);
+ final class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> {
+ private Uri mRootUri;
+
+ public RestoreRootTask(Uri rootUri) {
+ mRootUri = rootUri;
+ }
+
+ @Override
+ protected RootInfo doInBackground(Void... params) {
+ final String rootId = DocumentsContract.getRootId(mRootUri);
+ return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId);
+ }
+
+ @Override
+ protected void onPostExecute(RootInfo root) {
+ if (isDestroyed()) return;
+ mState.restored = true;
+
+ if (root != null) {
+ onRootPicked(root);
+ } else {
+ Log.w(mTag, "Failed to find root: " + mRootUri);
+ finish();
+ }
}
}
@@ -599,10 +601,9 @@
return;
}
- State state = getDisplayState();
- while (state.stack.size() > position + 1) {
- state.stackTouched = true;
- state.stack.pop();
+ while (mState.stack.size() > position + 1) {
+ mState.stackTouched = true;
+ mState.stack.pop();
}
onCurrentDirectoryChanged(ANIM_UP);
}
@@ -619,13 +620,12 @@
final class StackAdapter extends BaseAdapter {
@Override
public int getCount() {
- return getDisplayState().stack.size();
+ return mState.stack.size();
}
@Override
public DocumentInfo getItem(int position) {
- State state = getDisplayState();
- return state.stack.get(state.stack.size() - position - 1);
+ return mState.stack.get(mState.stack.size() - position - 1);
}
@Override
@@ -713,13 +713,12 @@
return;
}
- State state = getDisplayState();
- if (state.currentSearch != null) {
+ if (mState.currentSearch != null) {
mMenu.expandActionView();
mView.setIconified(false);
mView.clearFocus();
- mView.setQuery(state.currentSearch, false);
+ mView.setQuery(mState.currentSearch, false);
} else {
mView.clearFocus();
if (!mView.isIconified()) {
@@ -745,7 +744,7 @@
mMenu.setVisible(visible);
if (!visible) {
- getDisplayState().currentSearch = null;
+ mState.currentSearch = null;
}
}
@@ -763,7 +762,7 @@
}
boolean isSearching() {
- return getDisplayState().currentSearch != null;
+ return mState.currentSearch != null;
}
boolean isExpanded() {
@@ -778,7 +777,7 @@
return false;
}
- getDisplayState().currentSearch = null;
+ mState.currentSearch = null;
onCurrentDirectoryChanged(ANIM_NONE);
return false;
}
@@ -797,7 +796,7 @@
mIgnoreNextCollapse = false;
return true;
}
- getDisplayState().currentSearch = null;
+ mState.currentSearch = null;
onCurrentDirectoryChanged(ANIM_NONE);
return true;
}
@@ -805,7 +804,7 @@
@Override
public boolean onQueryTextSubmit(String query) {
mSearchExpanded = true;
- getDisplayState().currentSearch = query;
+ mState.currentSearch = query;
mView.clearFocus();
onCurrentDirectoryChanged(ANIM_NONE);
return true;
@@ -821,4 +820,17 @@
updateActionBar();
}
}
+
+ /**
+ * Interface providing access to current view of documents
+ * even when all documents are not homed to the same parent.
+ */
+ public interface DocumentContext {
+ /**
+ * Returns the cursor for the selected document. The cursor can be used to retrieve
+ * details about a document and its siblings.
+ * @return
+ */
+ Cursor getCursor();
+ }
}
diff --git a/src/com/android/documentsui/ColumnAdapter.java b/src/com/android/documentsui/ColumnAdapter.java
deleted file mode 100644
index 092b5db..0000000
--- a/src/com/android/documentsui/ColumnAdapter.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * 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
- *
- * http://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.
- */
-
-package com.android.documentsui;
-
-import android.database.DataSetObserver;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.LinearLayout;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * Adapter that wraps an existing adapter, presenting its contents in multiple
- * equally-sized horizontal columns.
- */
-public class ColumnAdapter extends BaseAdapter {
- private final ListAdapter mWrapped;
- private final OnItemClickListener mListener;
-
- private int mColumns = 1;
-
- public interface OnItemClickListener {
- public void onItemClick(ListAdapter adapter, int position);
- }
-
- public ColumnAdapter(ListAdapter wrapped, OnItemClickListener listener) {
- mWrapped = Preconditions.checkNotNull(wrapped);
- mListener = Preconditions.checkNotNull(listener);
-
- if (!wrapped.areAllItemsEnabled()) {
- throw new IllegalStateException("All items must be enabled");
- }
- if (wrapped.getViewTypeCount() > 1) {
- throw new IllegalStateException("All items must be identical");
- }
- }
-
- public static void prepare(ListView list) {
- list.setItemsCanFocus(true);
- }
-
- public void setColumns(int columns) {
- mColumns = columns;
- notifyDataSetChanged();
- }
-
- private View.OnClickListener mItemListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final int position = (Integer) v.getTag();
- mListener.onItemClick(mWrapped, position);
- }
- };
-
- @Override
- public int getCount() {
- return (mWrapped.getCount() + mColumns - 1) / mColumns;
- }
-
- @Override
- public Object getItem(int position) {
- return position;
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null) {
- convertView = new LinearLayout(parent.getContext());
- }
-
- final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- 0, LinearLayout.LayoutParams.WRAP_CONTENT);
- params.weight = 1f / mColumns;
-
- final LinearLayout row = (LinearLayout) convertView;
- final int first = position * mColumns;
- final int last = mWrapped.getCount() - 1;
-
- for (int i = 0; i < mColumns; i++) {
- View convertItem = null;
- if (i < row.getChildCount()) {
- convertItem = row.getChildAt(i);
- }
-
- final int pos = first + i;
- final int validPos = Math.min(pos, last);
- final View item = mWrapped.getView(validPos, convertItem, row);
- item.setTag(validPos);
- item.setOnClickListener(mItemListener);
- item.setFocusable(true);
-
- if (pos == validPos) {
- item.setVisibility(View.VISIBLE);
- } else {
- item.setVisibility(View.INVISIBLE);
- }
-
- if (convertItem == null) {
- row.addView(item, params);
- }
- }
-
- return convertView;
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- super.registerDataSetObserver(observer);
- mWrapped.registerDataSetObserver(observer);
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- super.unregisterDataSetObserver(observer);
- mWrapped.unregisterDataSetObserver(observer);
- }
-}
diff --git a/src/com/android/documentsui/CopyService.java b/src/com/android/documentsui/CopyService.java
index 506ec58..b99c806 100644
--- a/src/com/android/documentsui/CopyService.java
+++ b/src/com/android/documentsui/CopyService.java
@@ -16,9 +16,11 @@
package com.android.documentsui;
+import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
+import android.app.Activity;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
@@ -32,16 +34,20 @@
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.design.widget.Snackbar;
import android.text.format.DateUtils;
import android.util.Log;
-import android.widget.Toast;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
import libcore.io.IoUtils;
@@ -59,21 +65,29 @@
private static final String EXTRA_CANCEL = "com.android.documentsui.CANCEL";
public static final String EXTRA_SRC_LIST = "com.android.documentsui.SRC_LIST";
- public static final String EXTRA_STACK = "com.android.documentsui.STACK";
public static final String EXTRA_FAILURE = "com.android.documentsui.FAILURE";
+ public static final String EXTRA_TRANSFER_MODE = "com.android.documentsui.TRANSFER_MODE";
+
+ public static final int TRANSFER_MODE_COPY = 1;
+ public static final int TRANSFER_MODE_MOVE = 2;
// TODO: Move it to a shared file when more operations are implemented.
public static final int FAILURE_COPY = 1;
+ // Parameters of the copy job. Requests to an IntentService are serialized so this code only
+ // needs to deal with one job at a time.
+ // NOTE: This must be declared by concrete type as the concrete type
+ // is required by putParcelableArrayListExtra.
+ private final ArrayList<DocumentInfo> mFailedFiles = new ArrayList<>();
+
+ private PowerManager mPowerManager;
+
private NotificationManager mNotificationManager;
private Notification.Builder mProgressBuilder;
// Jobs are serialized but a job ID is used, to avoid mixing up cancellation requests.
private String mJobId;
private volatile boolean mIsCancelled;
- // Parameters of the copy job. Requests to an IntentService are serialized so this code only
- // needs to deal with one job at a time.
- private final ArrayList<DocumentInfo> mFailedFiles;
private long mBatchSize;
private long mBytesCopied;
private long mStartTime;
@@ -88,10 +102,11 @@
private ContentProviderClient mSrcClient;
private ContentProviderClient mDstClient;
+ // For testing only.
+ @Nullable private TestOnlyListener mJobFinishedListener;
+
public CopyService() {
super("CopyService");
-
- mFailedFiles = new ArrayList<DocumentInfo>();
}
/**
@@ -101,17 +116,25 @@
* @param srcDocs A list of src files to copy.
* @param dstStack The copy destination stack.
*/
- public static void start(Context context, List<DocumentInfo> srcDocs, DocumentStack dstStack) {
- final Resources res = context.getResources();
- final Intent copyIntent = new Intent(context, CopyService.class);
+ public static void start(Activity activity, List<DocumentInfo> srcDocs, DocumentStack dstStack,
+ int mode) {
+ final Resources res = activity.getResources();
+ final Intent copyIntent = new Intent(activity, CopyService.class);
copyIntent.putParcelableArrayListExtra(
- EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(srcDocs));
- copyIntent.putExtra(EXTRA_STACK, (Parcelable) dstStack);
+ EXTRA_SRC_LIST,
+ // Don't create a copy unless absolutely necessary :)
+ srcDocs instanceof ArrayList
+ ? (ArrayList<DocumentInfo>) srcDocs
+ : new ArrayList<DocumentInfo>(srcDocs));
+ copyIntent.putExtra(Shared.EXTRA_STACK, (Parcelable) dstStack);
+ copyIntent.putExtra(EXTRA_TRANSFER_MODE, mode);
- Toast.makeText(context,
- res.getQuantityString(R.plurals.copy_begin, srcDocs.size(), srcDocs.size()),
- Toast.LENGTH_SHORT).show();
- context.startService(copyIntent);
+ int toastMessage = (mode == TRANSFER_MODE_COPY) ? R.plurals.copy_begin
+ : R.plurals.move_begin;
+ Snackbars.makeSnackbar(activity,
+ res.getQuantityString(toastMessage, srcDocs.size(), srcDocs.size()),
+ Snackbar.LENGTH_SHORT).show();
+ activity.startService(copyIntent);
}
@Override
@@ -129,42 +152,54 @@
return;
}
+ final PowerManager.WakeLock wakeLock = mPowerManager
+ .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
final ArrayList<DocumentInfo> srcs = intent.getParcelableArrayListExtra(EXTRA_SRC_LIST);
- final DocumentStack stack = intent.getParcelableExtra(EXTRA_STACK);
+ final DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+ // Copy by default.
+ final int transferMode = intent.getIntExtra(EXTRA_TRANSFER_MODE, TRANSFER_MODE_COPY);
try {
+ wakeLock.acquire();
+
// Acquire content providers.
mSrcClient = DocumentsApplication.acquireUnstableProviderOrThrow(getContentResolver(),
srcs.get(0).authority);
mDstClient = DocumentsApplication.acquireUnstableProviderOrThrow(getContentResolver(),
stack.peek().authority);
- setupCopyJob(srcs, stack);
+ setupCopyJob(srcs, stack, transferMode);
for (int i = 0; i < srcs.size() && !mIsCancelled; ++i) {
- copy(srcs.get(i), stack.peek());
+ copy(srcs.get(i), stack.peek(), transferMode);
}
} catch (Exception e) {
// Catch-all to prevent any copy errors from wedging the app.
Log.e(TAG, "Exceptions occurred during copying", e);
} finally {
+ if (DEBUG) Log.d(TAG, "Cleaning up after copy");
ContentProviderClient.releaseQuietly(mSrcClient);
ContentProviderClient.releaseQuietly(mDstClient);
+ wakeLock.release();
+
// Dismiss the ongoing copy notification when the copy is done.
mNotificationManager.cancel(mJobId, 0);
if (mFailedFiles.size() > 0) {
+ Log.e(TAG, mFailedFiles.size() + " files failed to copy");
final Context context = getApplicationContext();
- final Intent navigateIntent = new Intent(context, DocumentsActivity.class);
- navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
+ final Intent navigateIntent = buildNavigateIntent(context, stack);
navigateIntent.putExtra(EXTRA_FAILURE, FAILURE_COPY);
+ navigateIntent.putExtra(EXTRA_TRANSFER_MODE, transferMode);
navigateIntent.putParcelableArrayListExtra(EXTRA_SRC_LIST, mFailedFiles);
+ final int titleResourceId = (transferMode == TRANSFER_MODE_COPY ?
+ R.plurals.copy_error_notification_title :
+ R.plurals.move_error_notification_title);
final Notification.Builder errorBuilder = new Notification.Builder(this)
- .setContentTitle(context.getResources().
- getQuantityString(R.plurals.copy_error_notification_title,
- mFailedFiles.size(), mFailedFiles.size()))
+ .setContentTitle(context.getResources().getQuantityString(titleResourceId,
+ mFailedFiles.size(), mFailedFiles.size()))
.setContentText(getString(R.string.notification_touch_for_details))
.setContentIntent(PendingIntent.getActivity(context, 0, navigateIntent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT))
@@ -173,13 +208,20 @@
.setAutoCancel(true);
mNotificationManager.notify(mJobId, 0, errorBuilder.build());
}
+
+ if (mJobFinishedListener != null) {
+ mJobFinishedListener.onFinished(mFailedFiles);
+ }
+
+ if (DEBUG) Log.d(TAG, "Done cleaning up");
}
}
@Override
public void onCreate() {
super.onCreate();
- mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ mPowerManager = getSystemService(PowerManager.class);
+ mNotificationManager = getSystemService(NotificationManager.class);
}
/**
@@ -188,21 +230,24 @@
*
* @param srcs A list of src files to copy.
* @param stack The copy destination stack.
+ * @param transferMode The mode (i.e. copy, or move)
* @throws RemoteException
*/
- private void setupCopyJob(ArrayList<DocumentInfo> srcs, DocumentStack stack)
+ private void setupCopyJob(ArrayList<DocumentInfo> srcs, DocumentStack stack, int transferMode)
throws RemoteException {
+ final boolean copying = (transferMode == TRANSFER_MODE_COPY);
// Create an ID for this copy job. Use the timestamp.
mJobId = String.valueOf(SystemClock.elapsedRealtime());
// Reset the cancellation flag.
mIsCancelled = false;
final Context context = getApplicationContext();
- final Intent navigateIntent = new Intent(context, DocumentsActivity.class);
- navigateIntent.putExtra(EXTRA_STACK, (Parcelable) stack);
+ final Intent navigateIntent = buildNavigateIntent(context, stack);
+ final String contentTitle = getString(copying ? R.string.copy_notification_title
+ : R.string.move_notification_title);
mProgressBuilder = new Notification.Builder(this)
- .setContentTitle(getString(R.string.copy_notification_title))
+ .setContentTitle(contentTitle)
.setContentIntent(PendingIntent.getActivity(context, 0, navigateIntent, 0))
.setCategory(Notification.CATEGORY_PROGRESS)
.setSmallIcon(R.drawable.ic_menu_copy)
@@ -216,8 +261,10 @@
PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT));
// Send an initial progress notification.
+ final String contentText = getString(copying ? R.string.copy_preparing
+ : R.string.move_preparing);
mProgressBuilder.setProgress(0, 0, true); // Indeterminate progress while setting up.
- mProgressBuilder.setContentText(getString(R.string.copy_preparing));
+ mProgressBuilder.setContentText(contentText);
mNotificationManager.notify(mJobId, 0, mProgressBuilder.build());
// Reset batch parameters.
@@ -237,6 +284,26 @@
}
/**
+ * Sets a callback to be run when the next run job is finished.
+ * This is test ONLY instrumentation. The alternative is for us to add
+ * broadcast intents SOLELY for the purpose of testing.
+ * @param listener
+ */
+ @VisibleForTesting
+ void addFinishedListener(TestOnlyListener listener) {
+ this.mJobFinishedListener = listener;
+
+ }
+
+ /**
+ * Only used for testing. Is that obvious enough?
+ */
+ @VisibleForTesting
+ interface TestOnlyListener {
+ void onFinished(List<DocumentInfo> failed);
+ }
+
+ /**
* Calculates the cumulative size of all the documents in the list. Directories are recursed
* into and totaled up.
*
@@ -247,7 +314,7 @@
private long calculateFileSizes(List<DocumentInfo> srcs) throws RemoteException {
long result = 0;
for (DocumentInfo src : srcs) {
- if (Document.MIME_TYPE_DIR.equals(src.mimeType)) {
+ if (src.isDirectory()) {
// Directories need to be recursed into.
result += calculateFileSizesHelper(src.derivedUri);
} else {
@@ -375,23 +442,78 @@
*
* @param srcInfo DocumentInfos for the documents to copy.
* @param dstDirInfo The destination directory.
+ * @param mode The transfer mode (copy or move).
* @throws RemoteException
*/
- private void copy(DocumentInfo srcInfo, DocumentInfo dstDirInfo) throws RemoteException {
- final Uri dstUri = DocumentsContract.createDocument(mDstClient, dstDirInfo.derivedUri,
- srcInfo.mimeType, srcInfo.displayName);
- if (dstUri == null) {
- // If this is a directory, the entire subdir will not be copied over.
- Log.e(TAG, "Error while copying " + srcInfo.displayName);
+ private void copy(DocumentInfo srcInfo, DocumentInfo dstDirInfo, int mode)
+ throws RemoteException {
+
+ String opDesc = mode == TRANSFER_MODE_COPY ? "copy" : "move";
+
+ // Guard unsupported recursive operation.
+ if (dstDirInfo.equals(srcInfo) || isDescendentOf(srcInfo, dstDirInfo)) {
+ if (DEBUG) Log.d(TAG,
+ "Skipping recursive " + opDesc + " of directory " + dstDirInfo.derivedUri);
mFailedFiles.add(srcInfo);
return;
}
- if (Document.MIME_TYPE_DIR.equals(srcInfo.mimeType)) {
- copyDirectoryHelper(srcInfo.derivedUri, dstUri);
- } else {
- copyFileHelper(srcInfo.derivedUri, dstUri);
+ if (DEBUG) Log.d(TAG,
+ "Performing " + opDesc + " of " + srcInfo.displayName
+ + " (" + srcInfo.derivedUri + ")" + " to " + dstDirInfo.displayName
+ + " (" + dstDirInfo.derivedUri + ")");
+
+ // When copying within the same provider, try to use optimized copying and moving.
+ // If not supported, then fallback to byte-by-byte copy/move.
+ if (srcInfo.authority.equals(dstDirInfo.authority)) {
+ switch (mode) {
+ case TRANSFER_MODE_COPY:
+ if ((srcInfo.flags & Document.FLAG_SUPPORTS_COPY) != 0) {
+ if (DocumentsContract.copyDocument(mSrcClient, srcInfo.derivedUri,
+ dstDirInfo.derivedUri) == null) {
+ mFailedFiles.add(srcInfo);
+ }
+ return;
+ }
+ break;
+ case TRANSFER_MODE_MOVE:
+ if ((srcInfo.flags & Document.FLAG_SUPPORTS_MOVE) != 0) {
+ if (DocumentsContract.moveDocument(mSrcClient, srcInfo.derivedUri,
+ dstDirInfo.derivedUri) == null) {
+ mFailedFiles.add(srcInfo);
+ }
+ return;
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown transfer mode.");
+ }
}
+
+ final Uri dstUri = DocumentsContract.createDocument(mDstClient, dstDirInfo.derivedUri,
+ srcInfo.mimeType, srcInfo.displayName);
+ if (dstUri == null) {
+ // If this is a directory, the entire subdir will not be copied over.
+ mFailedFiles.add(srcInfo);
+ return;
+ }
+
+ if (srcInfo.isDirectory()) {
+ copyDirectoryHelper(srcInfo.derivedUri, dstUri, mode);
+ } else {
+ copyFileHelper(srcInfo.derivedUri, dstUri, mode);
+ }
+ }
+
+ /**
+ * Returns true if {@code doc} is a descendant of {@code parentDoc}.
+ */
+ boolean isDescendentOf(DocumentInfo doc, DocumentInfo parentDoc) throws RemoteException {
+ if (parentDoc.isDirectory() && doc.authority.equals(parentDoc.authority)) {
+ return DocumentsContract.isChildDocument(
+ mDstClient, doc.derivedUri, parentDoc.derivedUri);
+ }
+ return false;
}
/**
@@ -403,7 +525,8 @@
* @param dstDirUri URI of the directory to copy to. Must be created beforehand.
* @throws RemoteException
*/
- private void copyDirectoryHelper(Uri srcDirUri, Uri dstDirUri) throws RemoteException {
+ private void copyDirectoryHelper(Uri srcDirUri, Uri dstDirUri, int mode)
+ throws RemoteException {
// Recurse into directories. Copy children into the new subdirectory.
final String queryColumns[] = new String[] {
Document.COLUMN_DISPLAY_NAME,
@@ -424,9 +547,20 @@
final Uri childUri = DocumentsContract.buildDocumentUri(srcDirUri.getAuthority(),
getCursorString(cursor, Document.COLUMN_DOCUMENT_ID));
if (Document.MIME_TYPE_DIR.equals(childMimeType)) {
- copyDirectoryHelper(childUri, dstUri);
+ copyDirectoryHelper(childUri, dstUri, mode);
} else {
- copyFileHelper(childUri, dstUri);
+ copyFileHelper(childUri, dstUri, mode);
+ }
+ }
+ if (mode == TRANSFER_MODE_MOVE) {
+ try {
+ DocumentsContract.deleteDocument(mSrcClient, srcDirUri);
+ } catch (RemoteException e) {
+ // RemoteExceptions usually signal that the connection is dead, so there's no
+ // point attempting to continue. Propagate the exception up so the copy job is
+ // cancelled.
+ Log.w(TAG, "Failed to clean up after move: " + srcDirUri, e);
+ throw e;
}
}
} finally {
@@ -441,7 +575,8 @@
* @param dstUri URI of the *file* to copy to. Must be created beforehand.
* @throws RemoteException
*/
- private void copyFileHelper(Uri srcUri, Uri dstUri) throws RemoteException {
+ private void copyFileHelper(Uri srcUri, Uri dstUri, int mode)
+ throws RemoteException {
// Copy an individual file.
CancellationSignal canceller = new CancellationSignal();
ParcelFileDescriptor srcFile = null;
@@ -466,10 +601,25 @@
srcFile.checkError();
} catch (IOException e) {
copyError = e;
+
try {
- dstFile.closeWithError(copyError.getMessage());
- } catch (IOException closeError) {
- Log.e(TAG, "Error closing destination", closeError);
+ DocumentInfo info = DocumentInfo.fromUri(getContentResolver(), srcUri);
+ mFailedFiles.add(info);
+ } catch (FileNotFoundException ignore) {
+ // Generate a dummy DocumentInfo so an error still gets reflected in the UI for this
+ // file.
+ DocumentInfo info = new DocumentInfo();
+ info.derivedUri = srcUri;
+ info.displayName = "Unknown [" + srcUri + "]";
+ mFailedFiles.add(info);
+ }
+
+ if (dstFile != null) {
+ try {
+ dstFile.closeWithError(copyError.getMessage());
+ } catch (IOException closeError) {
+ Log.e(TAG, "Error closing destination", closeError);
+ }
}
} finally {
// This also ensures the file descriptors are closed.
@@ -477,16 +627,6 @@
IoUtils.closeQuietly(dst);
}
- if (copyError != null) {
- // Log errors.
- Log.e(TAG, "Error while copying " + srcUri.toString(), copyError);
- try {
- mFailedFiles.add(DocumentInfo.fromUri(getContentResolver(), srcUri));
- } catch (FileNotFoundException ignore) {
- Log.w(TAG, "Source file gone: " + srcUri, copyError);
- // The source file is gone.
- }
- }
if (copyError != null || mIsCancelled) {
// Clean up half-copied files.
@@ -494,11 +634,29 @@
try {
DocumentsContract.deleteDocument(mDstClient, dstUri);
} catch (RemoteException e) {
- Log.w(TAG, "Failed to clean up: " + srcUri, e);
+ Log.w(TAG, "Failed to clean up after copy error: " + dstUri, e);
// RemoteExceptions usually signal that the connection is dead, so there's no point
// attempting to continue. Propagate the exception up so the copy job is cancelled.
throw e;
}
+ } else if (mode == TRANSFER_MODE_MOVE) {
+ // Clean up src files after a successful move.
+ try {
+ DocumentsContract.deleteDocument(mSrcClient, srcUri);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to clean up after move: " + srcUri, e);
+ throw e;
+ }
}
}
+
+ /**
+ * Creates an intent for navigating back to the destination directory.
+ */
+ private Intent buildNavigateIntent(Context context, DocumentStack stack) {
+ Intent intent = new Intent(context, FilesActivity.class);
+ intent.setAction(DocumentsContract.ACTION_BROWSE);
+ intent.putExtra(Shared.EXTRA_STACK, (Parcelable) stack);
+ return intent;
+ }
}
diff --git a/src/com/android/documentsui/CreateDirectoryFragment.java b/src/com/android/documentsui/CreateDirectoryFragment.java
index 1f7b41e..f3c3f2f 100644
--- a/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -32,11 +32,15 @@
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
-import android.widget.Toast;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
import com.android.documentsui.model.DocumentInfo;
@@ -56,34 +60,53 @@
final Context context = getActivity();
final ContentResolver resolver = context.getContentResolver();
- // We need to specify android.R.style.Theme_DeviceDefault_Dialog explicitly,
- // because the application theme 'DialogWhenReallyLarge' has
- // fixed window size properties for large screen devices.
- final AlertDialog.Builder builder = new AlertDialog.Builder(
- context, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
- final EditText text1 = (EditText) view.findViewById(android.R.id.text1);
+ final EditText editText = (EditText) view.findViewById(android.R.id.text1);
builder.setTitle(R.string.menu_create_dir);
builder.setView(view);
- builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final String displayName = text1.getText().toString();
+ builder.setPositiveButton(
+ android.R.string.ok,
+ new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ createDirectory(editText.getText().toString());
+ }
+ });
- final BaseActivity activity = (BaseActivity) getActivity();
- final DocumentInfo cwd = activity.getCurrentDirectory();
-
- new CreateDirectoryTask(activity, cwd, displayName).executeOnExecutor(
- ProviderExecutor.forAuthority(cwd.authority));
- }
- });
builder.setNegativeButton(android.R.string.cancel, null);
+ final AlertDialog dialog = builder.create();
- return builder.create();
+ editText.setOnEditorActionListener(
+ new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(
+ TextView view, int actionId, @Nullable KeyEvent event) {
+ if (event != null
+ && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
+ && event.hasNoModifiers()) {
+ createDirectory(editText.getText().toString());
+ dialog.dismiss();
+ return true;
+ }
+ return false;
+ }
+ });
+
+
+ return dialog;
+ }
+
+ private void createDirectory(String name) {
+ final BaseActivity activity = (BaseActivity) getActivity();
+ final DocumentInfo cwd = activity.getCurrentDirectory();
+
+ new CreateDirectoryTask(activity, cwd, name).executeOnExecutor(
+ ProviderExecutor.forAuthority(cwd.authority));
}
private class CreateDirectoryTask extends AsyncTask<Void, Void, DocumentInfo> {
@@ -125,9 +148,9 @@
protected void onPostExecute(DocumentInfo result) {
if (result != null) {
// Navigate into newly created child
- mActivity.onDocumentPicked(result);
+ mActivity.onDirectoryCreated(result);
} else {
- Toast.makeText(mActivity, R.string.create_error, Toast.LENGTH_SHORT).show();
+ Snackbars.makeSnackbar(mActivity, R.string.create_error, Snackbar.LENGTH_SHORT).show();
}
mActivity.setPending(false);
diff --git a/src/com/android/documentsui/DirectoryFragment.java b/src/com/android/documentsui/DirectoryFragment.java
deleted file mode 100644
index f4be9c5..0000000
--- a/src/com/android/documentsui/DirectoryFragment.java
+++ /dev/null
@@ -1,1200 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * 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
- *
- * http://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.
- */
-
-package com.android.documentsui;
-
-import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
-import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE_ALL;
-import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
-import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
-import static com.android.documentsui.BaseActivity.State.MODE_GRID;
-import static com.android.documentsui.BaseActivity.State.MODE_LIST;
-import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
-import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.model.DocumentInfo.getCursorInt;
-import static com.android.documentsui.model.DocumentInfo.getCursorLong;
-import static com.android.documentsui.model.DocumentInfo.getCursorString;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.OperationCanceledException;
-import android.os.Parcelable;
-import android.provider.DocumentsContract;
-import android.provider.DocumentsContract.Document;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Formatter;
-import android.text.format.Time;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.view.ActionMode;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AbsListView.MultiChoiceModeListener;
-import android.widget.AbsListView.RecyclerListener;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.BaseAdapter;
-import android.widget.GridView;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.documentsui.BaseActivity.State;
-import com.android.documentsui.ProviderExecutor.Preemptable;
-import com.android.documentsui.RecentsProvider.StateColumns;
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Display the documents inside a single directory.
- */
-public class DirectoryFragment extends Fragment {
-
- private View mEmptyView;
- private ListView mListView;
- private GridView mGridView;
-
- private AbsListView mCurrentView;
-
- public static final int TYPE_NORMAL = 1;
- public static final int TYPE_SEARCH = 2;
- public static final int TYPE_RECENT_OPEN = 3;
-
- public static final int ANIM_NONE = 1;
- public static final int ANIM_SIDE = 2;
- public static final int ANIM_DOWN = 3;
- public static final int ANIM_UP = 4;
-
- public static final int REQUEST_COPY_DESTINATION = 1;
-
- private int mType = TYPE_NORMAL;
- private String mStateKey;
-
- private int mLastMode = MODE_UNKNOWN;
- private int mLastSortOrder = SORT_ORDER_UNKNOWN;
- private boolean mLastShowSize = false;
-
- private boolean mHideGridTitles = false;
-
- private boolean mSvelteRecents;
- private Point mThumbSize;
-
- private DocumentsAdapter mAdapter;
- private LoaderCallbacks<DirectoryResult> mCallbacks;
-
- private static final String EXTRA_TYPE = "type";
- private static final String EXTRA_ROOT = "root";
- private static final String EXTRA_DOC = "doc";
- private static final String EXTRA_QUERY = "query";
- private static final String EXTRA_IGNORE_STATE = "ignoreState";
-
- private final int mLoaderId = 42;
-
- public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
- show(fm, TYPE_NORMAL, root, doc, null, anim);
- }
-
- public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) {
- show(fm, TYPE_SEARCH, root, null, query, anim);
- }
-
- public static void showRecentsOpen(FragmentManager fm, int anim) {
- show(fm, TYPE_RECENT_OPEN, null, null, null, anim);
- }
-
- private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc,
- String query, int anim) {
- final Bundle args = new Bundle();
- args.putInt(EXTRA_TYPE, type);
- args.putParcelable(EXTRA_ROOT, root);
- args.putParcelable(EXTRA_DOC, doc);
- args.putString(EXTRA_QUERY, query);
-
- final FragmentTransaction ft = fm.beginTransaction();
- switch (anim) {
- case ANIM_SIDE:
- args.putBoolean(EXTRA_IGNORE_STATE, true);
- break;
- case ANIM_DOWN:
- args.putBoolean(EXTRA_IGNORE_STATE, true);
- ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen);
- break;
- case ANIM_UP:
- ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up);
- break;
- }
-
- final DirectoryFragment fragment = new DirectoryFragment();
- fragment.setArguments(args);
-
- ft.replace(R.id.container_directory, fragment);
- ft.commitAllowingStateLoss();
- }
-
- private static String buildStateKey(RootInfo root, DocumentInfo doc) {
- final StringBuilder builder = new StringBuilder();
- builder.append(root != null ? root.authority : "null").append(';');
- builder.append(root != null ? root.rootId : "null").append(';');
- builder.append(doc != null ? doc.documentId : "null");
- return builder.toString();
- }
-
- public static DirectoryFragment get(FragmentManager fm) {
- // TODO: deal with multiple directories shown at once
- return (DirectoryFragment) fm.findFragmentById(R.id.container_directory);
- }
-
- @Override
- public View onCreateView(
- LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- final Context context = inflater.getContext();
- final Resources res = context.getResources();
- final View view = inflater.inflate(R.layout.fragment_directory, container, false);
-
- mEmptyView = view.findViewById(android.R.id.empty);
-
- mListView = (ListView) view.findViewById(R.id.list);
- mListView.setOnItemClickListener(mItemListener);
- mListView.setMultiChoiceModeListener(mMultiListener);
- mListView.setRecyclerListener(mRecycleListener);
-
- // Indent our list divider to align with text
- final Drawable divider = mListView.getDivider();
- final boolean insetLeft = res.getBoolean(R.bool.list_divider_inset_left);
- final int insetSize = res.getDimensionPixelSize(R.dimen.list_divider_inset);
- if (insetLeft) {
- mListView.setDivider(new InsetDrawable(divider, insetSize, 0, 0, 0));
- } else {
- mListView.setDivider(new InsetDrawable(divider, 0, 0, insetSize, 0));
- }
-
- mGridView = (GridView) view.findViewById(R.id.grid);
- mGridView.setOnItemClickListener(mItemListener);
- mGridView.setMultiChoiceModeListener(mMultiListener);
- mGridView.setRecyclerListener(mRecycleListener);
-
- return view;
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
-
- // Cancel any outstanding thumbnail requests
- final ViewGroup target = (mListView.getAdapter() != null) ? mListView : mGridView;
- final int count = target.getChildCount();
- for (int i = 0; i < count; i++) {
- final View view = target.getChildAt(i);
- mRecycleListener.onMovedToScrapHeap(view);
- }
-
- // Tear down any selection in progress
- mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
- mGridView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
-
- final Context context = getActivity();
- final State state = getDisplayState(DirectoryFragment.this);
-
- final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
- final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
-
- mAdapter = new DocumentsAdapter();
- mType = getArguments().getInt(EXTRA_TYPE);
- mStateKey = buildStateKey(root, doc);
-
- if (mType == TYPE_RECENT_OPEN) {
- // Hide titles when showing recents for picking images/videos
- mHideGridTitles = MimePredicate.mimeMatches(
- MimePredicate.VISUAL_MIMES, state.acceptMimes);
- } else {
- mHideGridTitles = (doc != null) && doc.isGridTitlesHidden();
- }
-
- final ActivityManager am = (ActivityManager) context.getSystemService(
- Context.ACTIVITY_SERVICE);
- mSvelteRecents = am.isLowRamDevice() && (mType == TYPE_RECENT_OPEN);
-
- mCallbacks = new LoaderCallbacks<DirectoryResult>() {
- @Override
- public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
- final String query = getArguments().getString(EXTRA_QUERY);
-
- Uri contentsUri;
- switch (mType) {
- case TYPE_NORMAL:
- contentsUri = DocumentsContract.buildChildDocumentsUri(
- doc.authority, doc.documentId);
- if (state.action == ACTION_MANAGE) {
- contentsUri = DocumentsContract.setManageMode(contentsUri);
- }
- return new DirectoryLoader(
- context, mType, root, doc, contentsUri, state.userSortOrder);
- case TYPE_SEARCH:
- contentsUri = DocumentsContract.buildSearchDocumentsUri(
- root.authority, root.rootId, query);
- if (state.action == ACTION_MANAGE) {
- contentsUri = DocumentsContract.setManageMode(contentsUri);
- }
- return new DirectoryLoader(
- context, mType, root, doc, contentsUri, state.userSortOrder);
- case TYPE_RECENT_OPEN:
- final RootsCache roots = DocumentsApplication.getRootsCache(context);
- return new RecentLoader(context, roots, state);
- default:
- throw new IllegalStateException("Unknown type " + mType);
- }
- }
-
- @Override
- public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
- if (!isAdded()) return;
-
- mAdapter.swapResult(result);
-
- // Push latest state up to UI
- // TODO: if mode change was racing with us, don't overwrite it
- if (result.mode != MODE_UNKNOWN) {
- state.derivedMode = result.mode;
- }
- state.derivedSortOrder = result.sortOrder;
- ((BaseActivity) context).onStateChanged();
-
- updateDisplayState();
-
- // When launched into empty recents, show drawer
- if (mType == TYPE_RECENT_OPEN && mAdapter.isEmpty() && !state.stackTouched &&
- context instanceof DocumentsActivity) {
- ((DocumentsActivity) context).setRootsDrawerOpen(true);
- }
-
- // Restore any previous instance state
- final SparseArray<Parcelable> container = state.dirState.remove(mStateKey);
- if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) {
- getView().restoreHierarchyState(container);
- } else if (mLastSortOrder != state.derivedSortOrder) {
- mListView.smoothScrollToPosition(0);
- mGridView.smoothScrollToPosition(0);
- }
-
- mLastSortOrder = state.derivedSortOrder;
- }
-
- @Override
- public void onLoaderReset(Loader<DirectoryResult> loader) {
- mAdapter.swapResult(null);
- }
- };
-
- // Kick off loader at least once
- getLoaderManager().restartLoader(mLoaderId, null, mCallbacks);
-
- updateDisplayState();
- }
-
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- // There's only one request code right now. Replace this with a switch statement or
- // something more scalable when more codes are added.
- if (requestCode != REQUEST_COPY_DESTINATION) {
- return;
- }
- if (resultCode == Activity.RESULT_CANCELED || data == null) {
- // User pressed the back button or otherwise cancelled the destination pick. Don't
- // proceed with the copy.
- return;
- }
-
- CopyService.start(getActivity(), getDisplayState(this).selectedDocumentsForCopy,
- (DocumentStack) data.getParcelableExtra(CopyService.EXTRA_STACK));
- }
-
- @Override
- public void onStop() {
- super.onStop();
-
- // Remember last scroll location
- final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
- getView().saveHierarchyState(container);
- final State state = getDisplayState(this);
- state.dirState.put(mStateKey, container);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateDisplayState();
- }
-
- public void onDisplayStateChanged() {
- updateDisplayState();
- }
-
- public void onUserSortOrderChanged() {
- // Sort order change always triggers reload; we'll trigger state change
- // on the flip side.
- getLoaderManager().restartLoader(mLoaderId, null, mCallbacks);
- }
-
- public void onUserModeChanged() {
- final ContentResolver resolver = getActivity().getContentResolver();
- final State state = getDisplayState(this);
-
- final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
- final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
-
- if (root != null && doc != null) {
- final Uri stateUri = RecentsProvider.buildState(
- root.authority, root.rootId, doc.documentId);
- final ContentValues values = new ContentValues();
- values.put(StateColumns.MODE, state.userMode);
-
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- resolver.insert(stateUri, values);
- return null;
- }
- }.execute();
- }
-
- // Mode change is just visual change; no need to kick loader, and
- // deliver change event immediately.
- state.derivedMode = state.userMode;
- ((BaseActivity) getActivity()).onStateChanged();
-
- updateDisplayState();
- }
-
- private void updateDisplayState() {
- final State state = getDisplayState(this);
-
- if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return;
- mLastMode = state.derivedMode;
- mLastShowSize = state.showSize;
-
- mListView.setVisibility(state.derivedMode == MODE_LIST ? View.VISIBLE : View.GONE);
- mGridView.setVisibility(state.derivedMode == MODE_GRID ? View.VISIBLE : View.GONE);
-
- final int choiceMode;
- if (state.allowMultiple) {
- choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL;
- } else {
- choiceMode = ListView.CHOICE_MODE_NONE;
- }
-
- final int thumbSize;
- if (state.derivedMode == MODE_GRID) {
- thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
- mListView.setAdapter(null);
- mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
- mGridView.setAdapter(mAdapter);
- mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width));
- mGridView.setNumColumns(GridView.AUTO_FIT);
- mGridView.setChoiceMode(choiceMode);
- mCurrentView = mGridView;
- } else if (state.derivedMode == MODE_LIST) {
- thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
- mGridView.setAdapter(null);
- mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE);
- mListView.setAdapter(mAdapter);
- mListView.setChoiceMode(choiceMode);
- mCurrentView = mListView;
- } else {
- throw new IllegalStateException("Unknown state " + state.derivedMode);
- }
-
- mThumbSize = new Point(thumbSize, thumbSize);
- }
-
- private OnItemClickListener mItemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final Cursor cursor = mAdapter.getItem(position);
- if (cursor != null) {
- final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- if (isDocumentEnabled(docMimeType, docFlags)) {
- final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- ((BaseActivity) getActivity()).onDocumentPicked(doc);
- }
- }
- }
- };
-
- private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() {
- @Override
- public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- mode.getMenuInflater().inflate(R.menu.mode_directory, menu);
- mode.setTitle(TextUtils.formatSelectedCount(mCurrentView.getCheckedItemCount()));
- return true;
- }
-
- @Override
- public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
- final State state = getDisplayState(DirectoryFragment.this);
-
- final MenuItem open = menu.findItem(R.id.menu_open);
- final MenuItem share = menu.findItem(R.id.menu_share);
- final MenuItem delete = menu.findItem(R.id.menu_delete);
- final MenuItem copy = menu.findItem(R.id.menu_copy);
-
- final boolean manageOrBrowse = (state.action == ACTION_MANAGE
- || state.action == ACTION_BROWSE || state.action == ACTION_BROWSE_ALL);
-
- open.setVisible(!manageOrBrowse);
- share.setVisible(manageOrBrowse);
- delete.setVisible(manageOrBrowse);
- // Disable copying from the Recents view.
- copy.setVisible(manageOrBrowse && mType != TYPE_RECENT_OPEN);
-
- return true;
- }
-
- @Override
- public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions();
- final ArrayList<DocumentInfo> docs = Lists.newArrayList();
- final int size = checked.size();
- for (int i = 0; i < size; i++) {
- if (checked.valueAt(i)) {
- final Cursor cursor = mAdapter.getItem(checked.keyAt(i));
- final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
- docs.add(doc);
- }
- }
-
- final int id = item.getItemId();
- if (id == R.id.menu_open) {
- BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
- mode.finish();
- return true;
-
- } else if (id == R.id.menu_share) {
- onShareDocuments(docs);
- mode.finish();
- return true;
-
- } else if (id == R.id.menu_delete) {
- onDeleteDocuments(docs);
- mode.finish();
- return true;
-
- } else if (id == R.id.menu_copy) {
- onCopyDocuments(docs);
- mode.finish();
- return true;
-
- } else if (id == R.id.menu_select_all) {
- int count = mCurrentView.getCount();
- for (int i = 0; i < count; i++) {
- mCurrentView.setItemChecked(i, true);
- }
- updateDisplayState();
- return true;
-
- } else {
- return false;
- }
- }
-
- @Override
- public void onDestroyActionMode(ActionMode mode) {
- // ignored
- }
-
- @Override
- public void onItemCheckedStateChanged(
- ActionMode mode, int position, long id, boolean checked) {
- if (checked) {
- // Directories and footer items cannot be checked
- boolean valid = false;
-
- final Cursor cursor = mAdapter.getItem(position);
- if (cursor != null) {
- final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- valid = isDocumentEnabled(docMimeType, docFlags);
- }
-
- if (!valid) {
- mCurrentView.setItemChecked(position, false);
- }
- }
-
- mode.setTitle(TextUtils.formatSelectedCount(mCurrentView.getCheckedItemCount()));
- }
- };
-
- private RecyclerListener mRecycleListener = new RecyclerListener() {
- @Override
- public void onMovedToScrapHeap(View view) {
- final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb);
- if (iconThumb != null) {
- final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
- if (oldTask != null) {
- oldTask.preempt();
- iconThumb.setTag(null);
- }
- }
- }
- };
-
- private void onShareDocuments(List<DocumentInfo> docs) {
- Intent intent;
-
- // Filter out directories - those can't be shared.
- List<DocumentInfo> docsForSend = Lists.newArrayList();
- for (DocumentInfo doc: docs) {
- if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
- docsForSend.add(doc);
- }
- }
-
- if (docsForSend.size() == 1) {
- final DocumentInfo doc = docsForSend.get(0);
-
- intent = new Intent(Intent.ACTION_SEND);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
- intent.setType(doc.mimeType);
- intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
-
- } else if (docsForSend.size() > 1) {
- intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.addCategory(Intent.CATEGORY_DEFAULT);
-
- final ArrayList<String> mimeTypes = Lists.newArrayList();
- final ArrayList<Uri> uris = Lists.newArrayList();
- for (DocumentInfo doc : docsForSend) {
- mimeTypes.add(doc.mimeType);
- uris.add(doc.derivedUri);
- }
-
- intent.setType(findCommonMimeType(mimeTypes));
- intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
-
- } else {
- return;
- }
-
- intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via));
- startActivity(intent);
- }
-
- private void onDeleteDocuments(List<DocumentInfo> docs) {
- final Context context = getActivity();
- final ContentResolver resolver = context.getContentResolver();
-
- boolean hadTrouble = false;
- for (DocumentInfo doc : docs) {
- if (!doc.isDeleteSupported()) {
- Log.w(TAG, "Skipping " + doc);
- hadTrouble = true;
- continue;
- }
-
- ContentProviderClient client = null;
- try {
- client = DocumentsApplication.acquireUnstableProviderOrThrow(
- resolver, doc.derivedUri.getAuthority());
- DocumentsContract.deleteDocument(client, doc.derivedUri);
- } catch (Exception e) {
- Log.w(TAG, "Failed to delete " + doc);
- hadTrouble = true;
- } finally {
- ContentProviderClient.releaseQuietly(client);
- }
- }
-
- if (hadTrouble) {
- Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show();
- }
- }
-
- private void onCopyDocuments(List<DocumentInfo> docs) {
- getDisplayState(this).selectedDocumentsForCopy = docs;
-
- // Pop up a dialog to pick a destination. This is inadequate but works for now.
- // TODO: Implement a picker that is to spec.
- final Intent intent = new Intent(
- BaseActivity.DocumentsIntent.ACTION_OPEN_COPY_DESTINATION,
- Uri.EMPTY,
- getActivity(),
- DocumentsActivity.class);
- boolean directoryCopy = false;
- for (DocumentInfo info : docs) {
- if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
- directoryCopy = true;
- break;
- }
- }
- intent.putExtra(BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, directoryCopy);
- startActivityForResult(intent, REQUEST_COPY_DESTINATION);
- }
-
- private static State getDisplayState(Fragment fragment) {
- return ((BaseActivity) fragment.getActivity()).getDisplayState();
- }
-
- private static abstract class Footer {
- private final int mItemViewType;
-
- public Footer(int itemViewType) {
- mItemViewType = itemViewType;
- }
-
- public abstract View getView(View convertView, ViewGroup parent);
-
- public int getItemViewType() {
- return mItemViewType;
- }
- }
-
- private class LoadingFooter extends Footer {
- public LoadingFooter() {
- super(1);
- }
-
- @Override
- public View getView(View convertView, ViewGroup parent) {
- final Context context = parent.getContext();
- final State state = getDisplayState(DirectoryFragment.this);
-
- if (convertView == null) {
- final LayoutInflater inflater = LayoutInflater.from(context);
- if (state.derivedMode == MODE_LIST) {
- convertView = inflater.inflate(R.layout.item_loading_list, parent, false);
- } else if (state.derivedMode == MODE_GRID) {
- convertView = inflater.inflate(R.layout.item_loading_grid, parent, false);
- } else {
- throw new IllegalStateException();
- }
- }
-
- return convertView;
- }
- }
-
- private class MessageFooter extends Footer {
- private final int mIcon;
- private final String mMessage;
-
- public MessageFooter(int itemViewType, int icon, String message) {
- super(itemViewType);
- mIcon = icon;
- mMessage = message;
- }
-
- @Override
- public View getView(View convertView, ViewGroup parent) {
- final Context context = parent.getContext();
- final State state = getDisplayState(DirectoryFragment.this);
-
- if (convertView == null) {
- final LayoutInflater inflater = LayoutInflater.from(context);
- if (state.derivedMode == MODE_LIST) {
- convertView = inflater.inflate(R.layout.item_message_list, parent, false);
- } else if (state.derivedMode == MODE_GRID) {
- convertView = inflater.inflate(R.layout.item_message_grid, parent, false);
- } else {
- throw new IllegalStateException();
- }
- }
-
- final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon);
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- icon.setImageResource(mIcon);
- title.setText(mMessage);
- return convertView;
- }
- }
-
- private class DocumentsAdapter extends BaseAdapter {
- private Cursor mCursor;
- private int mCursorCount;
-
- private List<Footer> mFooters = Lists.newArrayList();
-
- public void swapResult(DirectoryResult result) {
- mCursor = result != null ? result.cursor : null;
- mCursorCount = mCursor != null ? mCursor.getCount() : 0;
-
- mFooters.clear();
-
- final Bundle extras = mCursor != null ? mCursor.getExtras() : null;
- if (extras != null) {
- final String info = extras.getString(DocumentsContract.EXTRA_INFO);
- if (info != null) {
- mFooters.add(new MessageFooter(2, R.drawable.ic_dialog_info, info));
- }
- final String error = extras.getString(DocumentsContract.EXTRA_ERROR);
- if (error != null) {
- mFooters.add(new MessageFooter(3, R.drawable.ic_dialog_alert, error));
- }
- if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) {
- mFooters.add(new LoadingFooter());
- }
- }
-
- if (result != null && result.exception != null) {
- mFooters.add(new MessageFooter(
- 3, R.drawable.ic_dialog_alert, getString(R.string.query_error)));
- }
-
- if (isEmpty()) {
- mEmptyView.setVisibility(View.VISIBLE);
- } else {
- mEmptyView.setVisibility(View.GONE);
- }
-
- notifyDataSetChanged();
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (position < mCursorCount) {
- return getDocumentView(position, convertView, parent);
- } else {
- position -= mCursorCount;
- convertView = mFooters.get(position).getView(convertView, parent);
- // Only the view itself is disabled; contents inside shouldn't
- // be dimmed.
- convertView.setEnabled(false);
- return convertView;
- }
- }
-
- private View getDocumentView(int position, View convertView, ViewGroup parent) {
- final Context context = parent.getContext();
- final State state = getDisplayState(DirectoryFragment.this);
-
- final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
-
- final RootsCache roots = DocumentsApplication.getRootsCache(context);
- final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
- context, mThumbSize);
-
- if (convertView == null) {
- final LayoutInflater inflater = LayoutInflater.from(context);
- if (state.derivedMode == MODE_LIST) {
- convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
- } else if (state.derivedMode == MODE_GRID) {
- convertView = inflater.inflate(R.layout.item_doc_grid, parent, false);
- } else {
- throw new IllegalStateException();
- }
- }
-
- final Cursor cursor = getItem(position);
-
- final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
- final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID);
- final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
- final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
- final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
- final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
- final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON);
- final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY);
- final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE);
-
- final View line1 = convertView.findViewById(R.id.line1);
- final View line2 = convertView.findViewById(R.id.line2);
-
- final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
- final ImageView iconThumb = (ImageView) convertView.findViewById(R.id.icon_thumb);
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1);
- final ImageView icon2 = (ImageView) convertView.findViewById(android.R.id.icon2);
- final TextView summary = (TextView) convertView.findViewById(android.R.id.summary);
- final TextView date = (TextView) convertView.findViewById(R.id.date);
- final TextView size = (TextView) convertView.findViewById(R.id.size);
-
- final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
- if (oldTask != null) {
- oldTask.preempt();
- iconThumb.setTag(null);
- }
-
- iconMime.animate().cancel();
- iconThumb.animate().cancel();
-
- final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
- final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
- || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType);
- final boolean showThumbnail = supportsThumbnail && allowThumbnail && !mSvelteRecents;
-
- final boolean enabled = isDocumentEnabled(docMimeType, docFlags);
- final float iconAlpha = (state.derivedMode == MODE_LIST && !enabled) ? 0.5f : 1f;
-
- boolean cacheHit = false;
- if (showThumbnail) {
- final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
- final Bitmap cachedResult = thumbs.get(uri);
- if (cachedResult != null) {
- iconThumb.setImageBitmap(cachedResult);
- cacheHit = true;
- } else {
- iconThumb.setImageDrawable(null);
- final ThumbnailAsyncTask task = new ThumbnailAsyncTask(
- uri, iconMime, iconThumb, mThumbSize, iconAlpha);
- iconThumb.setTag(task);
- ProviderExecutor.forAuthority(docAuthority).execute(task);
- }
- }
-
- // Always throw MIME icon into place, even when a thumbnail is being
- // loaded in background.
- if (cacheHit) {
- iconMime.setAlpha(0f);
- iconMime.setImageDrawable(null);
- iconThumb.setAlpha(1f);
- } else {
- iconMime.setAlpha(1f);
- iconThumb.setAlpha(0f);
- iconThumb.setImageDrawable(null);
- if (docIcon != 0) {
- iconMime.setImageDrawable(
- IconUtils.loadPackageIcon(context, docAuthority, docIcon));
- } else {
- iconMime.setImageDrawable(IconUtils.loadMimeIcon(
- context, docMimeType, docAuthority, docId, state.derivedMode));
- }
- }
-
- boolean hasLine1 = false;
- boolean hasLine2 = false;
-
- final boolean hideTitle = (state.derivedMode == MODE_GRID) && mHideGridTitles;
- if (!hideTitle) {
- title.setText(docDisplayName);
- hasLine1 = true;
- }
-
- Drawable iconDrawable = null;
- if (mType == TYPE_RECENT_OPEN) {
- // We've already had to enumerate roots before any results can
- // be shown, so this will never block.
- final RootInfo root = roots.getRootBlocking(docAuthority, docRootId);
- if (state.derivedMode == MODE_GRID) {
- iconDrawable = root.loadGridIcon(context);
- } else {
- iconDrawable = root.loadIcon(context);
- }
-
- if (summary != null) {
- final boolean alwaysShowSummary = getResources()
- .getBoolean(R.bool.always_show_summary);
- if (alwaysShowSummary) {
- summary.setText(root.getDirectoryString());
- summary.setVisibility(View.VISIBLE);
- hasLine2 = true;
- } else {
- if (iconDrawable != null && roots.isIconUniqueBlocking(root)) {
- // No summary needed if icon speaks for itself
- summary.setVisibility(View.INVISIBLE);
- } else {
- summary.setText(root.getDirectoryString());
- summary.setVisibility(View.VISIBLE);
- summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
- hasLine2 = true;
- }
- }
- }
- } else {
- // Directories showing thumbnails in grid mode get a little icon
- // hint to remind user they're a directory.
- if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID
- && showThumbnail) {
- iconDrawable = IconUtils.applyTintAttr(context, R.drawable.ic_doc_folder,
- android.R.attr.textColorPrimaryInverse);
- }
-
- if (summary != null) {
- if (docSummary != null) {
- summary.setText(docSummary);
- summary.setVisibility(View.VISIBLE);
- hasLine2 = true;
- } else {
- summary.setVisibility(View.INVISIBLE);
- }
- }
- }
-
- if (icon1 != null) icon1.setVisibility(View.GONE);
- if (icon2 != null) icon2.setVisibility(View.GONE);
-
- if (iconDrawable != null) {
- if (hasLine1) {
- icon1.setVisibility(View.VISIBLE);
- icon1.setImageDrawable(iconDrawable);
- } else {
- icon2.setVisibility(View.VISIBLE);
- icon2.setImageDrawable(iconDrawable);
- }
- }
-
- if (docLastModified == -1) {
- date.setText(null);
- } else {
- date.setText(formatTime(context, docLastModified));
- hasLine2 = true;
- }
-
- if (state.showSize) {
- size.setVisibility(View.VISIBLE);
- if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) {
- size.setText(null);
- } else {
- size.setText(Formatter.formatFileSize(context, docSize));
- hasLine2 = true;
- }
- } else {
- size.setVisibility(View.GONE);
- }
-
- if (line1 != null) {
- line1.setVisibility(hasLine1 ? View.VISIBLE : View.GONE);
- }
- if (line2 != null) {
- line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE);
- }
-
- setEnabledRecursive(convertView, enabled);
-
- iconMime.setAlpha(iconAlpha);
- iconThumb.setAlpha(iconAlpha);
- if (icon1 != null) icon1.setAlpha(iconAlpha);
- if (icon2 != null) icon2.setAlpha(iconAlpha);
-
- return convertView;
- }
-
- @Override
- public int getCount() {
- return mCursorCount + mFooters.size();
- }
-
- @Override
- public Cursor getItem(int position) {
- if (position < mCursorCount) {
- mCursor.moveToPosition(position);
- return mCursor;
- } else {
- return null;
- }
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public int getViewTypeCount() {
- return 4;
- }
-
- @Override
- public int getItemViewType(int position) {
- if (position < mCursorCount) {
- return 0;
- } else {
- position -= mCursorCount;
- return mFooters.get(position).getItemViewType();
- }
- }
- }
-
- private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap>
- implements Preemptable {
- private final Uri mUri;
- private final ImageView mIconMime;
- private final ImageView mIconThumb;
- private final Point mThumbSize;
- private final float mTargetAlpha;
- private final CancellationSignal mSignal;
-
- public ThumbnailAsyncTask(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize,
- float targetAlpha) {
- mUri = uri;
- mIconMime = iconMime;
- mIconThumb = iconThumb;
- mThumbSize = thumbSize;
- mTargetAlpha = targetAlpha;
- mSignal = new CancellationSignal();
- }
-
- @Override
- public void preempt() {
- cancel(false);
- mSignal.cancel();
- }
-
- @Override
- protected Bitmap doInBackground(Uri... params) {
- if (isCancelled()) return null;
-
- final Context context = mIconThumb.getContext();
- final ContentResolver resolver = context.getContentResolver();
-
- ContentProviderClient client = null;
- Bitmap result = null;
- try {
- client = DocumentsApplication.acquireUnstableProviderOrThrow(
- resolver, mUri.getAuthority());
- result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal);
- if (result != null) {
- final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
- context, mThumbSize);
- thumbs.put(mUri, result);
- }
- } catch (Exception e) {
- if (!(e instanceof OperationCanceledException)) {
- Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e);
- }
- } finally {
- ContentProviderClient.releaseQuietly(client);
- }
- return result;
- }
-
- @Override
- protected void onPostExecute(Bitmap result) {
- if (mIconThumb.getTag() == this && result != null) {
- mIconThumb.setTag(null);
- mIconThumb.setImageBitmap(result);
-
- mIconMime.setAlpha(mTargetAlpha);
- mIconMime.animate().alpha(0f).start();
- mIconThumb.setAlpha(0f);
- mIconThumb.animate().alpha(mTargetAlpha).start();
- }
- }
- }
-
- private static String formatTime(Context context, long when) {
- // TODO: DateUtils should make this easier
- Time then = new Time();
- then.set(when);
- Time now = new Time();
- now.setToNow();
-
- int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
- | DateUtils.FORMAT_ABBREV_ALL;
-
- if (then.year != now.year) {
- flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
- } else if (then.yearDay != now.yearDay) {
- flags |= DateUtils.FORMAT_SHOW_DATE;
- } else {
- flags |= DateUtils.FORMAT_SHOW_TIME;
- }
-
- return DateUtils.formatDateTime(context, when, flags);
- }
-
- private String findCommonMimeType(List<String> mimeTypes) {
- String[] commonType = mimeTypes.get(0).split("/");
- if (commonType.length != 2) {
- return "*/*";
- }
-
- for (int i = 1; i < mimeTypes.size(); i++) {
- String[] type = mimeTypes.get(i).split("/");
- if (type.length != 2) continue;
-
- if (!commonType[1].equals(type[1])) {
- commonType[1] = "*";
- }
-
- if (!commonType[0].equals(type[0])) {
- commonType[0] = "*";
- commonType[1] = "*";
- break;
- }
- }
-
- return commonType[0] + "/" + commonType[1];
- }
-
- private void setEnabledRecursive(View v, boolean enabled) {
- if (v == null) return;
- if (v.isEnabled() == enabled) return;
- v.setEnabled(enabled);
-
- if (v instanceof ViewGroup) {
- final ViewGroup vg = (ViewGroup) v;
- for (int i = vg.getChildCount() - 1; i >= 0; i--) {
- setEnabledRecursive(vg.getChildAt(i), enabled);
- }
- }
- }
-
- private boolean isDocumentEnabled(String docMimeType, int docFlags) {
- final State state = getDisplayState(DirectoryFragment.this);
-
- // Directories are always enabled
- if (Document.MIME_TYPE_DIR.equals(docMimeType)) {
- return true;
- }
-
- // Read-only files are disabled when creating
- if (state.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
- return false;
- }
-
- return MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
- }
-}
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index 8e4ec8c..b0bbec3 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -16,12 +16,10 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.Shared.TAG;
+import static com.android.documentsui.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.State.SORT_ORDER_SIZE;
import static com.android.documentsui.model.DocumentInfo.getCursorInt;
import android.content.AsyncTaskLoader;
@@ -32,12 +30,13 @@
import android.net.Uri;
import android.os.CancellationSignal;
import android.os.OperationCanceledException;
+import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
@@ -45,23 +44,6 @@
import java.io.FileNotFoundException;
-class DirectoryResult implements AutoCloseable {
- ContentProviderClient client;
- Cursor cursor;
- Exception exception;
-
- int mode = MODE_UNKNOWN;
- int sortOrder = SORT_ORDER_UNKNOWN;
-
- @Override
- public void close() {
- IoUtils.closeQuietly(cursor);
- ContentProviderClient.releaseQuietly(client);
- cursor = null;
- client = null;
- }
-}
-
public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
private static final String[] SEARCH_REJECT_MIMES = new String[] { Document.MIME_TYPE_DIR };
@@ -163,6 +145,10 @@
cursor = client.query(
mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal);
+ if (cursor == null) {
+ throw new RemoteException("Provider returned null");
+ }
+
cursor.registerContentObserver(mObserver);
cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
diff --git a/src/com/android/documentsui/DirectoryResult.java b/src/com/android/documentsui/DirectoryResult.java
new file mode 100644
index 0000000..e7e4f73
--- /dev/null
+++ b/src/com/android/documentsui/DirectoryResult.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.State.MODE_UNKNOWN;
+import static com.android.documentsui.State.SORT_ORDER_UNKNOWN;
+
+import android.content.ContentProviderClient;
+import android.database.Cursor;
+
+import libcore.io.IoUtils;
+
+public class DirectoryResult implements AutoCloseable {
+ ContentProviderClient client;
+ public Cursor cursor;
+ public Exception exception;
+
+ public int mode = MODE_UNKNOWN;
+ public int sortOrder = SORT_ORDER_UNKNOWN;
+
+ @Override
+ public void close() {
+ IoUtils.closeQuietly(cursor);
+ ContentProviderClient.releaseQuietly(client);
+ cursor = null;
+ client = null;
+ }
+}
diff --git a/src/com/android/documentsui/DirectoryView.java b/src/com/android/documentsui/DirectoryView.java
index 4893652..000b92a 100644
--- a/src/com/android/documentsui/DirectoryView.java
+++ b/src/com/android/documentsui/DirectoryView.java
@@ -18,9 +18,9 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.widget.FrameLayout;
+import android.widget.LinearLayout;
-public class DirectoryView extends FrameLayout {
+public class DirectoryView extends LinearLayout {
private float mPosition = 0f;
private int mWidth;
diff --git a/src/com/android/documentsui/DocumentClipper.java b/src/com/android/documentsui/DocumentClipper.java
new file mode 100644
index 0000000..b3c2846
--- /dev/null
+++ b/src/com/android/documentsui/DocumentClipper.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.internal.util.Preconditions;
+
+import libcore.io.IoUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ClipboardManager wrapper class providing higher level logical
+ * support for dealing with Documents.
+ */
+public final class DocumentClipper {
+
+ private static final String TAG = "DocumentClipper";
+
+ private Context mContext;
+ private ClipboardManager mClipboard;
+
+ public DocumentClipper(Context context) {
+ mContext = context;
+ mClipboard = context.getSystemService(ClipboardManager.class);
+ }
+
+ public boolean hasItemsToPaste() {
+ if (mClipboard.hasPrimaryClip()) {
+ ClipData clipData = mClipboard.getPrimaryClip();
+ int count = clipData.getItemCount();
+ if (count > 0) {
+ for (int i = 0; i < count; ++i) {
+ ClipData.Item item = clipData.getItemAt(i);
+ Uri uri = item.getUri();
+ if (isDocumentUri(uri)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isDocumentUri(@Nullable Uri uri) {
+ return uri != null && DocumentsContract.isDocumentUri(mContext, uri);
+ }
+
+ /**
+ * Returns a list of Documents as decoded from Clipboard primary clipdata.
+ * This should be run from inside an AsyncTask.
+ */
+ public List<DocumentInfo> getClippedDocuments() {
+ return getDocumentsFromClipData(mClipboard.getPrimaryClip());
+ }
+
+ /**
+ * Returns a list of Documents as decoded in clipData.
+ * This should be run from inside an AsyncTask.
+ */
+ public List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
+ Preconditions.checkNotNull(clipData);
+ final List<DocumentInfo> srcDocs = new ArrayList<>();
+
+ int count = clipData.getItemCount();
+ if (count == 0) {
+ return srcDocs;
+ }
+
+ ContentResolver resolver = mContext.getContentResolver();
+ for (int i = 0; i < count; ++i) {
+ ClipData.Item item = clipData.getItemAt(i);
+ Uri itemUri = item.getUri();
+ if (itemUri != null && DocumentsContract.isDocumentUri(mContext, itemUri)) {
+ ContentProviderClient client = null;
+ Cursor cursor = null;
+ try {
+ client = DocumentsApplication.acquireUnstableProviderOrThrow(
+ resolver, itemUri.getAuthority());
+ cursor = client.query(itemUri, null, null, null, null);
+ cursor.moveToPosition(0);
+ srcDocs.add(DocumentInfo.fromCursor(cursor, itemUri.getAuthority()));
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ } finally {
+ IoUtils.closeQuietly(cursor);
+ ContentProviderClient.releaseQuietly(client);
+ }
+ }
+ }
+
+ return srcDocs;
+ }
+
+ /**
+ * Returns ClipData representing the list of docs, or null if docs is empty,
+ * or docs cannot be converted.
+ */
+ public @Nullable ClipData getClipDataForDocuments(List<DocumentInfo> docs) {
+ final ContentResolver resolver = mContext.getContentResolver();
+ ClipData clipData = null;
+ for (DocumentInfo doc : docs) {
+ final Uri uri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId);
+ if (clipData == null) {
+ // TODO: figure out what this string should be.
+ // Currently it is not displayed anywhere in the UI, but this might change.
+ final String label = "";
+ clipData = ClipData.newUri(resolver, label, uri);
+ } else {
+ // TODO: update list of mime types in ClipData.
+ clipData.addItem(new ClipData.Item(uri));
+ }
+ }
+ return clipData;
+ }
+
+ public void clipDocuments(List<DocumentInfo> docs) {
+ ClipData data = getClipDataForDocuments(docs);
+ mClipboard.setPrimaryClip(data);
+ }
+}
diff --git a/src/com/android/documentsui/DocumentsActivity.java b/src/com/android/documentsui/DocumentsActivity.java
index c541bca..4f4649c 100644
--- a/src/com/android/documentsui/DocumentsActivity.java
+++ b/src/com/android/documentsui/DocumentsActivity.java
@@ -16,26 +16,16 @@
package com.android.documentsui;
-import static com.android.documentsui.BaseActivity.State.ACTION_BROWSE;
-import static com.android.documentsui.BaseActivity.State.ACTION_CREATE;
-import static com.android.documentsui.BaseActivity.State.ACTION_GET_CONTENT;
-import static com.android.documentsui.BaseActivity.State.ACTION_MANAGE;
-import static com.android.documentsui.BaseActivity.State.ACTION_OPEN;
-import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_COPY_DESTINATION;
-import static com.android.documentsui.BaseActivity.State.ACTION_OPEN_TREE;
-import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
-import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
-import static com.android.documentsui.DirectoryFragment.ANIM_UP;
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.State.ACTION_OPEN;
+import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION;
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
-import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.ContentProviderClient;
@@ -51,10 +41,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.DocumentsContract;
-import android.provider.DocumentsContract.Root;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.support.design.widget.Snackbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -62,19 +49,21 @@
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Spinner;
-import android.widget.Toast;
import android.widget.Toolbar;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.dirlist.DirectoryFragment;
import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
+import java.util.Arrays;
+import java.util.List;
+
public class DocumentsActivity extends BaseActivity {
private static final int CODE_FORWARD = 42;
- public static final String TAG = "Documents";
+ private static final String TAG = "DocumentsActivity";
private boolean mShowAsDialog;
@@ -83,33 +72,27 @@
private Toolbar mRootsToolbar;
- private DrawerLayout mDrawerLayout;
- private ActionBarDrawerToggle mDrawerToggle;
- private View mRootsDrawer;
-
- private DirectoryContainerView mDirectoryContainer;
-
- private State mState;
-
private ItemSelectedListener mStackListener;
private BaseAdapter mStackAdapter;
public DocumentsActivity() {
- super(TAG);
+ super(R.layout.docs_activity, TAG);
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setResult(Activity.RESULT_CANCELED);
- setContentView(R.layout.activity);
-
- final Context context = this;
final Resources res = getResources();
mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
+ if (!mShowAsDialog) {
+ setTheme(R.style.DocumentsFullScreenTheme);
+ }
+
if (mShowAsDialog) {
+ mDrawer = DrawerController.createDummy();
+
// Strongly define our horizontal dimension; we leave vertical as
// WRAP_CONTENT so that system resizes us when IME is showing.
final WindowManager.LayoutParams a = getWindow().getAttributes();
@@ -121,26 +104,10 @@
getWindow().setAttributes(a);
} else {
- // Non-dialog means we have a drawer
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-
- mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
- R.drawable.ic_hamburger, R.string.drawer_open, R.string.drawer_close);
-
- mDrawerLayout.setDrawerListener(mDrawerListener);
-
- mRootsDrawer = findViewById(R.id.drawer_roots);
+ mDrawer = DrawerController.create(this);
}
- mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
-
- mState = (icicle != null)
- ? icicle.<State>getParcelable(EXTRA_STATE)
- : buildDefaultState();
-
mToolbar = (Toolbar) findViewById(R.id.toolbar);
- mToolbar.setTitleTextAppearance(context,
- android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
mStackAdapter = new StackAdapter();
mStackListener = new ItemSelectedListener();
@@ -148,28 +115,15 @@
mToolbarStack.setOnItemSelectedListener(mStackListener);
mRootsToolbar = (Toolbar) findViewById(R.id.roots_toolbar);
- if (mRootsToolbar != null) {
- mRootsToolbar.setTitleTextAppearance(context,
- android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
- }
setActionBar(mToolbar);
- // Hide roots when we're managing a specific root
- if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
- if (mShowAsDialog) {
- findViewById(R.id.container_roots).setVisibility(View.GONE);
- } else {
- mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
- }
- }
-
if (mState.action == ACTION_CREATE) {
final String mimeType = getIntent().getType();
final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE);
SaveFragment.show(getFragmentManager(), mimeType, title);
} else if (mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
PickFragment.show(getFragmentManager());
}
@@ -181,7 +135,7 @@
} else if (mState.action == ACTION_OPEN ||
mState.action == ACTION_CREATE ||
mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
RootsFragment.show(getFragmentManager(), null);
}
@@ -189,29 +143,15 @@
// In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent
// talkback from reading aloud the default title, we clear it here.
setTitle("");
- if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
- final Uri rootUri = getIntent().getData();
- new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor());
- } else {
- new RestoreStackTask().execute();
- }
-
- // Show a failure dialog if there was a failed operation.
- final Intent intent = getIntent();
- final DocumentStack dstStack = intent.getParcelableExtra(CopyService.EXTRA_STACK);
- final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
- if (failure != 0) {
- final ArrayList<DocumentInfo> failedSrcList =
- intent.getParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST);
- FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList, dstStack);
- }
+ new RestoreStackTask().execute();
} else {
onCurrentDirectoryChanged(ANIM_NONE);
}
}
- private State buildDefaultState() {
- State state = new State();
+ @Override
+ State buildState() {
+ State state = buildDefaultState();
final Intent intent = getIntent();
final String action = intent.getAction();
@@ -223,12 +163,8 @@
state.action = ACTION_GET_CONTENT;
} else if (Intent.ACTION_OPEN_DOCUMENT_TREE.equals(action)) {
state.action = ACTION_OPEN_TREE;
- } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
- state.action = ACTION_MANAGE;
- } else if (DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT.equals(action)) {
- state.action = ACTION_BROWSE;
- } else if (DocumentsIntent.ACTION_OPEN_COPY_DESTINATION.equals(action)) {
- state.action = ACTION_OPEN_COPY_DESTINATION;
+ } else if (Shared.ACTION_PICK_COPY_DESTINATION.equals(action)) {
+ state.action = ACTION_PICK_COPY_DESTINATION;
}
if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT) {
@@ -236,62 +172,21 @@
Intent.EXTRA_ALLOW_MULTIPLE, false);
}
- if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) {
- state.acceptMimes = new String[] { "*/*" };
- state.allowMultiple = true;
- } else if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
- state.acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
- } else {
- state.acceptMimes = new String[] { intent.getType() };
+ if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT
+ || state.action == ACTION_CREATE) {
+ state.openableOnly = intent.hasCategory(Intent.CATEGORY_OPENABLE);
}
- state.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false);
- state.forceAdvanced = intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
- state.showAdvanced = state.forceAdvanced
- | LocalPreferences.getDisplayAdvancedDevices(this);
-
- if (state.action == ACTION_MANAGE || state.action == ACTION_BROWSE) {
- state.showSize = true;
- } else {
- state.showSize = LocalPreferences.getDisplayFileSize(this);
- }
- if (state.action == ACTION_OPEN_COPY_DESTINATION) {
+ if (state.action == ACTION_PICK_COPY_DESTINATION) {
state.directoryCopy = intent.getBooleanExtra(
- BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
+ Shared.EXTRA_DIRECTORY_COPY, false);
+ state.transferMode = intent.getIntExtra(CopyService.EXTRA_TRANSFER_MODE,
+ CopyService.TRANSFER_MODE_COPY);
}
- state.excludedAuthorities = getExcludedAuthorities();
-
return state;
}
- private class RestoreRootTask extends AsyncTask<Void, Void, RootInfo> {
- private Uri mRootUri;
-
- public RestoreRootTask(Uri rootUri) {
- mRootUri = rootUri;
- }
-
- @Override
- protected RootInfo doInBackground(Void... params) {
- final String rootId = DocumentsContract.getRootId(mRootUri);
- return mRoots.getRootOneshot(mRootUri.getAuthority(), rootId);
- }
-
- @Override
- protected void onPostExecute(RootInfo root) {
- if (isDestroyed()) return;
- mState.restored = true;
-
- if (root != null) {
- onRootPicked(root);
- } else {
- Log.w(TAG, "Failed to find root: " + mRootUri);
- finish();
- }
- }
- }
-
@Override
void onStackRestored(boolean restored, boolean external) {
// Show drawer when no stack restored, but only when requesting
@@ -344,53 +239,15 @@
}
}
- private DrawerListener mDrawerListener = new DrawerListener() {
- @Override
- public void onDrawerSlide(View drawerView, float slideOffset) {
- mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
- }
-
- @Override
- public void onDrawerOpened(View drawerView) {
- mDrawerToggle.onDrawerOpened(drawerView);
- }
-
- @Override
- public void onDrawerClosed(View drawerView) {
- mDrawerToggle.onDrawerClosed(drawerView);
- }
-
- @Override
- public void onDrawerStateChanged(int newState) {
- mDrawerToggle.onDrawerStateChanged(newState);
- }
- };
-
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- if (mDrawerToggle != null) {
- mDrawerToggle.syncState();
- }
+ mDrawer.syncState();
updateActionBar();
}
public void setRootsDrawerOpen(boolean open) {
- if (!mShowAsDialog) {
- if (open) {
- mDrawerLayout.openDrawer(mRootsDrawer);
- } else {
- mDrawerLayout.closeDrawer(mRootsDrawer);
- }
- }
- }
-
- private boolean isRootsDrawerOpen() {
- if (mShowAsDialog) {
- return false;
- } else {
- return mDrawerLayout.isDrawerOpen(mRootsDrawer);
- }
+ mDrawer.setOpen(open);
}
@Override
@@ -405,14 +262,13 @@
mState.action == ACTION_OPEN_TREE) {
mRootsToolbar.setTitle(R.string.title_open);
} else if (mState.action == ACTION_CREATE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
mRootsToolbar.setTitle(R.string.title_save);
}
}
}
- if (!mShowAsDialog && mDrawerLayout.getDrawerLockMode(mRootsDrawer) ==
- DrawerLayout.LOCK_MODE_UNLOCKED) {
+ if (!mShowAsDialog && mDrawer.isUnlocked()) {
mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
mToolbar.setNavigationContentDescription(R.string.drawer_open);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@@ -462,83 +318,42 @@
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
final MenuItem grid = menu.findItem(R.id.menu_grid);
final MenuItem list = menu.findItem(R.id.menu_list);
- final MenuItem advanced = menu.findItem(R.id.menu_advanced);
final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
final MenuItem settings = menu.findItem(R.id.menu_settings);
- boolean fileSizeVisible = !(mState.action == ACTION_MANAGE
- || mState.action == ACTION_BROWSE);
- if (mState.action == ACTION_CREATE
+ boolean recents = cwd == null;
+ boolean picking = mState.action == ACTION_CREATE
|| mState.action == ACTION_OPEN_TREE
- || mState.action == ACTION_OPEN_COPY_DESTINATION) {
- createDir.setVisible(cwd != null && cwd.isCreateSupported());
- mSearchManager.showMenu(false);
+ || mState.action == ACTION_PICK_COPY_DESTINATION;
- // No display options in recent directories
- if (cwd == null) {
- grid.setVisible(false);
- list.setVisible(false);
- fileSizeVisible = false;
- }
+ createDir.setVisible(picking && !recents && cwd.isCreateSupported());
+ mSearchManager.showMenu(!picking);
- if (mState.action == ACTION_CREATE) {
- final FragmentManager fm = getFragmentManager();
- SaveFragment.get(fm).setSaveEnabled(cwd != null && cwd.isCreateSupported());
- }
- } else {
- createDir.setVisible(false);
+ // No display options in recent directories
+ grid.setVisible(!(picking && recents));
+ list.setVisible(!(picking && recents));
+
+ fileSize.setVisible(fileSize.isVisible() && !picking);
+ settings.setVisible(false);
+
+ if (mState.action == ACTION_CREATE) {
+ final FragmentManager fm = getFragmentManager();
+ SaveFragment.get(fm).prepareForDirectory(cwd);
}
- advanced.setVisible(!(mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE));
- fileSize.setVisible(fileSizeVisible);
-
- settings.setVisible((mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE)
- && (root.flags & Root.FLAG_HAS_SETTINGS) != 0);
+ Menus.disableHiddenItems(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- public void onBackPressed() {
- // While action bar is expanded, the state stack UI is hidden.
- if (mSearchManager.cancelSearch()) {
- return;
- }
-
- if (!mState.stackTouched) {
- super.onBackPressed();
- return;
- }
-
- final int size = mState.stack.size();
- if (size > 1) {
- mState.stack.pop();
- onCurrentDirectoryChanged(ANIM_UP);
- } else if (size == 1 && !isRootsDrawerOpen()) {
- // TODO: open root drawer once we can capture back key
- super.onBackPressed();
- } else {
- super.onBackPressed();
- }
- }
-
- @Override
- public State getDisplayState() {
- return mState;
+ return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
}
@Override
@@ -547,13 +362,11 @@
final RootInfo root = getCurrentRoot();
final DocumentInfo cwd = getCurrentDirectory();
- mDirectoryContainer.setDrawDisappearingFirst(anim == ANIM_DOWN);
-
if (cwd == null) {
// No directory means recents
if (mState.action == ACTION_CREATE ||
mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
RecentsCreateFragment.show(fm);
} else {
DirectoryFragment.showRecentsOpen(fm, anim);
@@ -583,20 +396,20 @@
}
if (mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
final PickFragment pick = PickFragment.get(fm);
if (pick != null) {
- pick.setPickTarget(mState.action, cwd);
+ pick.setPickTarget(mState.action, mState.transferMode, cwd);
}
}
}
void onSaveRequested(DocumentInfo replaceTarget) {
- new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getCurrentExecutor());
+ new ExistingFinishTask(replaceTarget.derivedUri).executeOnExecutor(getExecutorForCurrentDirectory());
}
void onSaveRequested(String mimeType, String displayName) {
- new CreateFinishTask(mimeType, displayName).executeOnExecutor(getCurrentExecutor());
+ new CreateFinishTask(mimeType, displayName).executeOnExecutor(getExecutorForCurrentDirectory());
}
@Override
@@ -606,49 +419,16 @@
}
@Override
- public void onDocumentPicked(DocumentInfo doc) {
+ public void onDocumentPicked(DocumentInfo doc, DocumentContext context) {
final FragmentManager fm = getFragmentManager();
if (doc.isDirectory()) {
- mState.stack.push(doc);
- mState.stackTouched = true;
- onCurrentDirectoryChanged(ANIM_DOWN);
+ openDirectory(doc);
} else if (mState.action == ACTION_OPEN || mState.action == ACTION_GET_CONTENT) {
// Explicit file picked, return
- new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getCurrentExecutor());
+ new ExistingFinishTask(doc.derivedUri).executeOnExecutor(getExecutorForCurrentDirectory());
} else if (mState.action == ACTION_CREATE) {
// Replace selected file
SaveFragment.get(fm).setReplaceTarget(doc);
- } else if (mState.action == ACTION_MANAGE) {
- // First try managing the document; we expect manager to filter
- // based on authority, so we don't grant.
- final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
- manage.setData(doc.derivedUri);
-
- try {
- startActivity(manage);
- } catch (ActivityNotFoundException ex) {
- // Fall back to viewing
- final Intent view = new Intent(Intent.ACTION_VIEW);
- view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- view.setData(doc.derivedUri);
-
- try {
- startActivity(view);
- } catch (ActivityNotFoundException ex2) {
- Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
- }
- }
- } else if (mState.action == ACTION_BROWSE) {
- // Go straight to viewing
- final Intent view = new Intent(Intent.ACTION_VIEW);
- view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- view.setData(doc.derivedUri);
-
- try {
- startActivity(view);
- } catch (ActivityNotFoundException ex) {
- Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
- }
}
}
@@ -660,7 +440,7 @@
for (int i = 0; i < size; i++) {
uris[i] = docs.get(i).derivedUri;
}
- new ExistingFinishTask(uris).executeOnExecutor(getCurrentExecutor());
+ new ExistingFinishTask(uris).executeOnExecutor(getExecutorForCurrentDirectory());
}
}
@@ -669,13 +449,13 @@
if (mState.action == ACTION_OPEN_TREE) {
result = DocumentsContract.buildTreeDocumentUri(
pickTarget.authority, pickTarget.documentId);
- } else if (mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ } else if (mState.action == ACTION_PICK_COPY_DESTINATION) {
result = pickTarget.derivedUri;
} else {
// Should not be reached.
throw new IllegalStateException("Invalid mState.action.");
}
- new PickFinishTask(result).executeOnExecutor(getCurrentExecutor());
+ new PickFinishTask(result).executeOnExecutor(getExecutorForCurrentDirectory());
}
@Override
@@ -686,7 +466,7 @@
final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
if (mState.action == ACTION_CREATE ||
mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ mState.action == ACTION_PICK_COPY_DESTINATION) {
// Remember stack for last create
values.clear();
values.put(RecentColumns.KEY, mState.stack.buildKey());
@@ -720,14 +500,16 @@
if (mState.action == ACTION_GET_CONTENT) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- } else if (mState.action == ACTION_OPEN_TREE ||
- mState.action == ACTION_OPEN_COPY_DESTINATION) {
+ } else if (mState.action == ACTION_OPEN_TREE) {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
| Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
- // TODO: Move passing the stack to the separate ACTION_COPY action once it's implemented.
- intent.putExtra(CopyService.EXTRA_STACK, (Parcelable)mState.stack);
+ } else if (mState.action == ACTION_PICK_COPY_DESTINATION) {
+ // Picking a copy destination is only used internally by us, so we
+ // don't need to extend permissions to the caller.
+ intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
+ intent.putExtra(CopyService.EXTRA_TRANSFER_MODE, mState.transferMode);
} else {
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
@@ -827,8 +609,8 @@
if (result != null) {
onTaskFinished(result);
} else {
- Toast.makeText(DocumentsActivity.this, R.string.save_error, Toast.LENGTH_SHORT)
- .show();
+ Snackbars.makeSnackbar(
+ DocumentsActivity.this, R.string.save_error, Snackbar.LENGTH_SHORT).show();
}
setPending(false);
diff --git a/src/com/android/documentsui/DownloadsActivity.java b/src/com/android/documentsui/DownloadsActivity.java
new file mode 100644
index 0000000..f224343
--- /dev/null
+++ b/src/com/android/documentsui/DownloadsActivity.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.State.ACTION_MANAGE;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.BaseAdapter;
+import android.widget.Spinner;
+import android.widget.Toolbar;
+
+import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DurableUtils;
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.List;
+
+// Let's face it. MANAGE_ROOT is used almost exclusively
+// for downloads, and is specialized for this purpose.
+// So it is now thusly christened.
+public class DownloadsActivity extends BaseActivity {
+ private static final String TAG = "DownloadsActivity";
+
+ private Toolbar mToolbar;
+ private Spinner mToolbarStack;
+
+ private ItemSelectedListener mStackListener;
+ private BaseAdapter mStackAdapter;
+
+ public DownloadsActivity() {
+ super(R.layout.manage_roots_activity, TAG);
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final Context context = this;
+
+ mDrawer = DrawerController.createDummy();
+
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ mToolbar.setTitleTextAppearance(context,
+ android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title);
+
+ mStackAdapter = new StackAdapter();
+ mStackListener = new ItemSelectedListener();
+ mToolbarStack = (Spinner) findViewById(R.id.stack);
+ mToolbarStack.setOnItemSelectedListener(mStackListener);
+
+ setActionBar(mToolbar);
+
+ if (!mState.restored) {
+ // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent
+ // talkback from reading aloud the default title, we clear it here.
+ setTitle("");
+ final Uri rootUri = getIntent().getData();
+ new RestoreRootTask(rootUri).executeOnExecutor(getExecutorForCurrentDirectory());
+ } else {
+ onCurrentDirectoryChanged(ANIM_NONE);
+ }
+ }
+
+ @Override
+ State buildState() {
+ State state = buildDefaultState();
+
+ state.action = ACTION_MANAGE;
+ state.acceptMimes = new String[] { "*/*" };
+ state.allowMultiple = true;
+ state.showSize = true;
+ state.excludedAuthorities = getExcludedAuthorities();
+
+ return state;
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ updateActionBar();
+ }
+
+ @Override
+ public void updateActionBar() {
+ // No navigation in manage root mode.
+ mToolbar.setNavigationIcon(null);
+ mToolbar.setNavigationOnClickListener(null);
+
+ if (mSearchManager.isExpanded()) {
+ mToolbar.setTitle(null);
+ mToolbarStack.setVisibility(View.GONE);
+ mToolbarStack.setAdapter(null);
+ } else {
+ if (mState.stack.size() <= 1) {
+ mToolbar.setTitle(getCurrentRoot().title);
+ mToolbarStack.setVisibility(View.GONE);
+ mToolbarStack.setAdapter(null);
+ } else {
+ mToolbar.setTitle(null);
+ mToolbarStack.setVisibility(View.VISIBLE);
+ mToolbarStack.setAdapter(mStackAdapter);
+
+ mStackListener.mIgnoreNextNavigation = true;
+ mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+
+ final MenuItem advanced = menu.findItem(R.id.menu_advanced);
+ final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+ final MenuItem newWindow = menu.findItem(R.id.menu_new_window);
+ final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
+ final MenuItem fileSize = menu.findItem(R.id.menu_file_size);
+ final MenuItem search = menu.findItem(R.id.menu_search);
+
+ advanced.setVisible(false);
+ createDir.setVisible(false);
+ pasteFromCb.setEnabled(false);
+ newWindow.setEnabled(false);
+ fileSize.setVisible(false);
+ search.setVisible(false);
+
+ Menus.disableHiddenItems(menu);
+ return true;
+ }
+
+ @Override
+ void onDirectoryChanged(int anim) {
+ final FragmentManager fm = getFragmentManager();
+ final RootInfo root = getCurrentRoot();
+ final DocumentInfo cwd = getCurrentDirectory();
+
+ // If started in manage roots mode, there has to be a cwd (i.e. the root dir of the managed
+ // root).
+ Preconditions.checkNotNull(cwd);
+
+ if (mState.currentSearch != null) {
+ // Ongoing search
+ DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
+ } else {
+ // Normal boring directory
+ DirectoryFragment.showNormal(fm, root, cwd, anim);
+ }
+ }
+
+ @Override
+ public void onDocumentPicked(DocumentInfo doc, DocumentContext context) {
+ final FragmentManager fm = getFragmentManager();
+ if (doc.isDirectory()) {
+ openDirectory(doc);
+ } else {
+ // First try managing the document; we expect manager to filter
+ // based on authority, so we don't grant.
+ final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
+ manage.setData(doc.derivedUri);
+
+ try {
+ startActivity(manage);
+ } catch (ActivityNotFoundException ex) {
+ // Fall back to viewing
+ final Intent view = new Intent(Intent.ACTION_VIEW);
+ view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ view.setData(doc.derivedUri);
+
+ try {
+ startActivity(view);
+ } catch (ActivityNotFoundException ex2) {
+ Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT)
+ .show();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onDocumentsPicked(List<DocumentInfo> docs) {}
+
+ @Override
+ void saveStackBlocking() {
+ final ContentResolver resolver = getContentResolver();
+ final ContentValues values = new ContentValues();
+
+ final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
+
+ // Remember location for next app launch
+ final String packageName = getCallingPackageMaybeExtra();
+ values.clear();
+ values.put(ResumeColumns.STACK, rawStack);
+ values.put(ResumeColumns.EXTERNAL, 0);
+ resolver.insert(RecentsProvider.buildResume(packageName), values);
+ }
+
+ @Override
+ void onTaskFinished(Uri... uris) {
+ Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+
+ final Intent intent = new Intent();
+ if (uris.length == 1) {
+ intent.setData(uris[0]);
+ } else if (uris.length > 1) {
+ final ClipData clipData = new ClipData(
+ null, mState.acceptMimes, new ClipData.Item(uris[0]));
+ for (int i = 1; i < uris.length; i++) {
+ clipData.addItem(new ClipData.Item(uris[i]));
+ }
+ intent.setClipData(clipData);
+ }
+
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ }
+
+ public static DownloadsActivity get(Fragment fragment) {
+ return (DownloadsActivity) fragment.getActivity();
+ }
+}
diff --git a/src/com/android/documentsui/DrawerController.java b/src/com/android/documentsui/DrawerController.java
new file mode 100644
index 0000000..df3ac1b
--- /dev/null
+++ b/src/com/android/documentsui/DrawerController.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.Activity;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * A facade over the various pieces comprising "roots fragment in a Drawer".
+ *
+ * @see DrawerController#create(DrawerLayout)
+ */
+abstract class DrawerController implements DrawerListener {
+
+ abstract void setOpen(boolean open);
+ abstract void lockOpen();
+ abstract void lockClosed();
+ abstract boolean isPresent();
+ abstract boolean isOpen();
+ abstract boolean isUnlocked();
+ abstract void syncState();
+ abstract boolean onOptionsItemSelected(MenuItem item);
+
+ /**
+ * Returns a controller suitable for {@code Layout}.
+ */
+ static DrawerController create(Activity activity) {
+
+ DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
+
+ if (layout == null) {
+ return new DummyDrawerController();
+ }
+
+ View drawer = activity.findViewById(R.id.drawer_roots);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ activity,
+ layout,
+ R.drawable.ic_hamburger,
+ R.string.drawer_open,
+ R.string.drawer_close);
+
+ return new RuntimeDrawerController(layout, drawer, toggle);
+ }
+
+ /**
+ * Returns a controller suitable for {@code Layout}.
+ */
+ static DrawerController createDummy() {
+ return new DummyDrawerController();
+ }
+
+ /**
+ * Runtime controller that manages a real drawer.
+ */
+ private static final class RuntimeDrawerController extends DrawerController {
+
+ private final ActionBarDrawerToggle mToggle;
+ private DrawerLayout mLayout;
+ private View mDrawer;
+
+ public RuntimeDrawerController(
+ DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle) {
+ checkArgument(layout != null);
+
+ mLayout = layout;
+ mDrawer = drawer;
+ mToggle = toggle;
+
+ mLayout.setDrawerListener(this);
+ }
+
+ @Override
+ void setOpen(boolean open) {
+ if (open) {
+ mLayout.openDrawer(mDrawer);
+ } else {
+ mLayout.closeDrawer(mDrawer);
+ }
+ }
+
+ @Override
+ boolean isOpen() {
+ return mLayout.isDrawerOpen(mDrawer);
+ }
+
+ @Override
+ boolean isPresent() {
+ return true;
+ }
+
+ @Override
+ void syncState() {
+ mToggle.syncState();
+ }
+
+ @Override
+ boolean isUnlocked() {
+ return mLayout.getDrawerLockMode(mDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED;
+ }
+
+ @Override
+ void lockOpen() {
+ mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
+ }
+
+ @Override
+ void lockClosed() {
+ mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+ }
+
+ @Override
+ boolean onOptionsItemSelected(MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {
+ mToggle.onDrawerSlide(drawerView, slideOffset);
+ }
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ mToggle.onDrawerOpened(drawerView);
+ }
+
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ mToggle.onDrawerClosed(drawerView);
+ }
+
+ @Override
+ public void onDrawerStateChanged(int newState) {
+ mToggle.onDrawerStateChanged(newState);
+ }
+ }
+
+ /*
+ * Dummy controller useful with clients that don't host a real drawer.
+ */
+ private static final class DummyDrawerController extends DrawerController {
+
+ @Override
+ void setOpen(boolean open) {}
+
+ @Override
+ void syncState() {}
+
+ @Override
+ void lockOpen() {}
+
+ @Override
+ void lockClosed() {}
+
+ @Override
+ boolean isOpen() {
+ return false;
+ }
+
+ @Override
+ boolean isUnlocked() {
+ return true;
+ }
+
+ @Override
+ boolean isPresent() {
+ return false;
+ }
+
+ @Override
+ boolean onOptionsItemSelected(MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onDrawerSlide(View drawerView, float slideOffset) {}
+
+ @Override
+ public void onDrawerOpened(View drawerView) {}
+
+ @Override
+ public void onDrawerClosed(View drawerView) {}
+
+ @Override
+ public void onDrawerStateChanged(int newState) {}
+ }
+}
diff --git a/src/com/android/documentsui/Events.java b/src/com/android/documentsui/Events.java
new file mode 100644
index 0000000..1b5b60d
--- /dev/null
+++ b/src/com/android/documentsui/Events.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.graphics.Point;
+import android.support.v7.widget.RecyclerView;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * Utility code for dealing with MotionEvents.
+ */
+public final class Events {
+
+ /**
+ * Returns true if event was triggered by a mouse.
+ */
+ public static boolean isMouseEvent(MotionEvent e) {
+ return isMouseType(e.getToolType(0));
+ }
+
+ /**
+ * Returns true if event was triggered by a finger or stylus touch.
+ */
+ public static boolean isTouchEvent(MotionEvent e) {
+ return isTouchType(e.getToolType(0));
+ }
+
+ /**
+ * Returns true if event was triggered by a mouse.
+ */
+ public static boolean isMouseType(int toolType) {
+ return toolType == MotionEvent.TOOL_TYPE_MOUSE;
+ }
+
+ /**
+ * Returns true if event was triggered by a finger or stylus touch.
+ */
+ public static boolean isTouchType(int toolType) {
+ return toolType == MotionEvent.TOOL_TYPE_FINGER
+ || toolType == MotionEvent.TOOL_TYPE_STYLUS;
+ }
+
+ /**
+ * Returns true if event was triggered by a finger or stylus touch.
+ */
+ public static boolean isActionDown(MotionEvent e) {
+ return e.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ /**
+ * Returns true if event was triggered by a finger or stylus touch.
+ */
+ public static boolean isActionUp(MotionEvent e) {
+ return e.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ /**
+ * Returns true if the shift is pressed.
+ */
+ public boolean isShiftPressed(MotionEvent e) {
+ return hasShiftBit(e.getMetaState());
+ }
+
+ /**
+ * Returns true if the "SHIFT" bit is set.
+ */
+ public static boolean hasShiftBit(int metaState) {
+ return (metaState & KeyEvent.META_SHIFT_ON) != 0;
+ }
+
+ /**
+ * A facade over MotionEvent primarily designed to permit for unit testing
+ * of related code.
+ */
+ public interface InputEvent {
+ boolean isMouseEvent();
+ boolean isPrimaryButtonPressed();
+ boolean isSecondaryButtonPressed();
+ boolean isShiftKeyDown();
+
+ /** Returns true if the action is the initial press of a mouse or touch. */
+ boolean isActionDown();
+
+ /** Returns true if the action is the final release of a mouse or touch. */
+ boolean isActionUp();
+
+ Point getOrigin();
+
+ /** Returns true if the there is an item under the finger/cursor. */
+ boolean isOverItem();
+
+ /** Returns the adapter position of the item under the finger/cursor. */
+ int getItemPosition();
+ }
+
+ public static final class MotionInputEvent implements InputEvent {
+ private final MotionEvent mEvent;
+ private final RecyclerView mView;
+ private final int mPosition;
+
+ public MotionInputEvent(MotionEvent event, RecyclerView view) {
+ mEvent = event;
+ mView = view;
+
+ // Consider determining position lazily as an optimization.
+ View child = mView.findChildViewUnder(mEvent.getX(), mEvent.getY());
+ mPosition = (child != null)
+ ? mView.getChildAdapterPosition(child)
+ : RecyclerView.NO_POSITION;
+ }
+
+ @Override
+ public boolean isMouseEvent() {
+ return Events.isMouseEvent(mEvent);
+ }
+
+ @Override
+ public boolean isPrimaryButtonPressed() {
+ return mEvent.isButtonPressed(MotionEvent.BUTTON_PRIMARY);
+ }
+
+ @Override
+ public boolean isSecondaryButtonPressed() {
+ return mEvent.isButtonPressed(MotionEvent.BUTTON_SECONDARY);
+ }
+
+ @Override
+ public boolean isShiftKeyDown() {
+ return Events.hasShiftBit(mEvent.getMetaState());
+ }
+
+ @Override
+ public boolean isActionDown() {
+ return mEvent.getActionMasked() == MotionEvent.ACTION_DOWN;
+ }
+
+ @Override
+ public boolean isActionUp() {
+ return mEvent.getActionMasked() == MotionEvent.ACTION_UP;
+ }
+
+ @Override
+ public Point getOrigin() {
+ return new Point((int) mEvent.getX(), (int) mEvent.getY());
+ }
+
+ @Override
+ public boolean isOverItem() {
+ return getItemPosition() != RecyclerView.NO_POSITION;
+ }
+
+ @Override
+ public int getItemPosition() {
+ return mPosition;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("MotionInputEvent {")
+ .append("isMouseEvent=").append(isMouseEvent())
+ .append(" isPrimaryButtonPressed=").append(isPrimaryButtonPressed())
+ .append(" isSecondaryButtonPressed=").append(isSecondaryButtonPressed())
+ .append(" isShiftKeyDown=").append(isShiftKeyDown())
+ .append(" isActionDown=").append(isActionDown())
+ .append(" isActionUp=").append(isActionUp())
+ .append(" getOrigin=").append(getOrigin())
+ .append(" isOverItem=").append(isOverItem())
+ .append(" getItemPosition=").append(getItemPosition())
+ .append("}")
+ .toString();
+ }
+ }
+}
diff --git a/src/com/android/documentsui/FailureDialogFragment.java b/src/com/android/documentsui/FailureDialogFragment.java
index 00b0f78..23074f0 100644
--- a/src/com/android/documentsui/FailureDialogFragment.java
+++ b/src/com/android/documentsui/FailureDialogFragment.java
@@ -16,23 +16,18 @@
package com.android.documentsui;
-import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
-import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
-import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
-import com.android.documentsui.CopyService;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
-import java.io.FileNotFoundException;
import java.util.ArrayList;
/**
@@ -42,11 +37,11 @@
implements DialogInterface.OnClickListener {
private static final String TAG = "FailureDialogFragment";
- private int mFailure;
+ private int mTransferMode;
private ArrayList<DocumentInfo> mFailedSrcList;
public static void show(FragmentManager fm, int failure,
- ArrayList<DocumentInfo> failedSrcList, DocumentStack dstStack) {
+ ArrayList<DocumentInfo> failedSrcList, DocumentStack dstStack, int transferMode) {
// TODO: Add support for other failures than copy.
if (failure != CopyService.FAILURE_COPY) {
return;
@@ -54,6 +49,7 @@
final Bundle args = new Bundle();
args.putInt(CopyService.EXTRA_FAILURE, failure);
+ args.putInt(CopyService.EXTRA_TRANSFER_MODE, transferMode);
args.putParcelableArrayList(CopyService.EXTRA_SRC_LIST, failedSrcList);
final FragmentTransaction ft = fm.beginTransaction();
@@ -66,18 +62,19 @@
@Override
public void onClick(DialogInterface dialog, int whichButton) {
- if (whichButton == DialogInterface.BUTTON_POSITIVE) {
- CopyService.start(getActivity(), mFailedSrcList,
- (DocumentStack) getActivity().getIntent().getParcelableExtra(
- CopyService.EXTRA_STACK));
- }
+ if (whichButton == DialogInterface.BUTTON_POSITIVE) {
+ CopyService.start(getActivity(), mFailedSrcList,
+ (DocumentStack) getActivity().getIntent().getParcelableExtra(
+ Shared.EXTRA_STACK),
+ mTransferMode);
+ }
}
@Override
public Dialog onCreateDialog(Bundle inState) {
super.onCreate(inState);
- mFailure = getArguments().getInt(CopyService.EXTRA_FAILURE);
+ mTransferMode = getArguments().getInt(CopyService.EXTRA_TRANSFER_MODE);
mFailedSrcList = getArguments().getParcelableArrayList(CopyService.EXTRA_SRC_LIST);
final StringBuilder list = new StringBuilder("<p>");
@@ -85,13 +82,14 @@
list.append(String.format("• %s<br>", documentInfo.displayName));
}
list.append("</p>");
- final String message = String.format(getString(R.string.copy_failure_alert_content),
- list.toString());
+ final String messageFormat = getString(mTransferMode == CopyService.TRANSFER_MODE_COPY ?
+ R.string.copy_failure_alert_content : R.string.move_failure_alert_content);
+ final String message = String.format(messageFormat, list.toString());
return new AlertDialog.Builder(getActivity())
- .setMessage(Html.fromHtml(message))
- .setPositiveButton(R.string.retry, this)
- .setNegativeButton(android.R.string.cancel, this)
- .create();
+ .setMessage(Html.fromHtml(message))
+ .setPositiveButton(R.string.retry, this)
+ .setNegativeButton(android.R.string.cancel, this)
+ .create();
}
}
diff --git a/src/com/android/documentsui/FilesActivity.java b/src/com/android/documentsui/FilesActivity.java
new file mode 100644
index 0000000..99d0cf4
--- /dev/null
+++ b/src/com/android/documentsui/FilesActivity.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE;
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.app.Activity;
+import android.app.FragmentManager;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.BaseAdapter;
+import android.widget.Spinner;
+import android.widget.Toolbar;
+
+import com.android.documentsui.RecentsProvider.ResumeColumns;
+import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.DurableUtils;
+import com.android.documentsui.model.RootInfo;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Standalone file management activity.
+ */
+public class FilesActivity extends BaseActivity {
+
+ public static final String TAG = "FilesActivity";
+
+ private Toolbar mToolbar;
+ private Spinner mToolbarStack;
+ private ItemSelectedListener mStackListener;
+ private BaseAdapter mStackAdapter;
+ private DocumentClipper mClipper;
+
+ public FilesActivity() {
+ super(R.layout.files_activity, TAG);
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+
+ mStackAdapter = new StackAdapter();
+ mStackListener = new ItemSelectedListener();
+ mToolbarStack = (Spinner) findViewById(R.id.stack);
+ mToolbarStack.setOnItemSelectedListener(mStackListener);
+
+ setActionBar(mToolbar);
+
+ mClipper = new DocumentClipper(this);
+ mDrawer = DrawerController.create(this);
+
+ RootsFragment.show(getFragmentManager(), null);
+
+ if (mState.restored) {
+ if (DEBUG) Log.d(TAG, "Restored instance for uri: " + getIntent().getData());
+ onCurrentDirectoryChanged(ANIM_NONE);
+ } else {
+ Intent intent = getIntent();
+ Uri uri = intent.getData();
+
+ if (DEBUG) Log.d(TAG, "Creating new instance for uri: " + uri);
+ // If a non-empty stack is present in our state it was read (presumably)
+ // from EXTRA_STACK intent extra. In this case, we'll skip other means of
+ // loading or restoring the stack.
+ if (!mState.stack.isEmpty()) {
+ // When restoring from a stack, if a URI is present, it should only ever
+ // be a launch URI. Launch URIs support sensible activity management, but
+ // don't specify an real content target.
+ if (uri != null) {
+ checkState(LauncherActivity.isLaunchUri(uri));
+ }
+ onCurrentDirectoryChanged(ANIM_NONE);
+ } else if (DocumentsContract.isRootUri(this, uri)) {
+ // If we've got a specific root to display, restore that root using a dedicated
+ // authority. That way a misbehaving provider won't result in an ANR.
+ new RestoreRootTask(uri).executeOnExecutor(
+ ProviderExecutor.forAuthority(uri.getAuthority()));
+ } else {
+ // Finally, we try to restore a stack from recents.
+ new RestoreStackTask().execute();
+ }
+
+ // TODO: Ensure we're handling CopyService errors correctly across all activities.
+ // Show a failure dialog if there was a failed operation.
+ final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
+ final int transferMode = intent.getIntExtra(CopyService.EXTRA_TRANSFER_MODE,
+ CopyService.TRANSFER_MODE_COPY);
+ if (failure != 0) {
+ final ArrayList<DocumentInfo> failedSrcList =
+ intent.getParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST);
+ FailureDialogFragment.show(
+ getFragmentManager(),
+ failure,
+ failedSrcList,
+ mState.stack,
+ transferMode);
+ }
+ }
+ }
+
+ @Override
+ State buildState() {
+ State state = buildDefaultState();
+
+ final Intent intent = getIntent();
+
+ state.action = State.ACTION_BROWSE;
+ state.allowMultiple = true;
+
+ // Options specific to the DocumentsActivity.
+ checkArgument(!intent.hasExtra(Intent.EXTRA_LOCAL_ONLY));
+
+ final DocumentStack stack = intent.getParcelableExtra(Shared.EXTRA_STACK);
+ if (stack != null) {
+ state.stack = stack;
+ }
+
+ return state;
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ updateActionBar();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ final RootInfo root = getCurrentRoot();
+
+ // If we're browsing a specific root, and that root went away, then we
+ // have no reason to hang around.
+ // TODO: Rather than just disappearing, maybe we should inform
+ // the user what has happened, let them close us. Less surprising.
+ if (mRoots.getRootBlocking(root.authority, root.rootId) == null) {
+ finish();
+ }
+ }
+
+ @Override
+ public void updateActionBar() {
+ final RootInfo root = getCurrentRoot();
+
+ if (mDrawer.isPresent()) {
+ mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
+ mToolbar.setNavigationOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mDrawer.setOpen(true);
+ }
+ });
+ } else {
+ mToolbar.setNavigationIcon(
+ root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
+ mToolbar.setNavigationContentDescription(R.string.drawer_open);
+ mToolbar.setNavigationOnClickListener(null);
+ }
+
+ if (mSearchManager.isExpanded()) {
+ mToolbar.setTitle(null);
+ mToolbarStack.setVisibility(View.GONE);
+ mToolbarStack.setAdapter(null);
+ } else {
+ if (mState.stack.size() <= 1) {
+ mToolbar.setTitle(root.title);
+ mToolbarStack.setVisibility(View.GONE);
+ mToolbarStack.setAdapter(null);
+ } else {
+ mToolbar.setTitle(null);
+ mToolbarStack.setVisibility(View.VISIBLE);
+ mToolbarStack.setAdapter(mStackAdapter);
+
+ mStackListener.mIgnoreNextNavigation = true;
+ mToolbarStack.setSelection(mStackAdapter.getCount() - 1);
+ }
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ boolean showMenu = super.onCreateOptionsMenu(menu);
+
+ expandMenus(menu);
+ return showMenu;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+
+ final MenuItem createDir = menu.findItem(R.id.menu_create_dir);
+ final MenuItem newWindow = menu.findItem(R.id.menu_new_window);
+ final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard);
+
+ createDir.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ createDir.setVisible(true);
+ createDir.setEnabled(canCreateDirectory());
+
+ pasteFromCb.setEnabled(mClipper.hasItemsToPaste());
+
+ newWindow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+ newWindow.setVisible(mProductivityDevice);
+
+ Menus.disableHiddenItems(menu, pasteFromCb);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_create_dir:
+ checkState(canCreateDirectory());
+ showCreateDirectoryDialog();
+ return true;
+ case R.id.menu_new_window:
+ createNewWindow();
+ return true;
+ case R.id.menu_paste_from_clipboard:
+ DirectoryFragment dir = DirectoryFragment.get(getFragmentManager());
+ dir = DirectoryFragment.get(getFragmentManager());
+ dir.pasteFromClipboard();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void createNewWindow() {
+ Intent intent = LauncherActivity.createLaunchIntent(this);
+ intent.putExtra(Shared.EXTRA_STACK, (Parcelable) mState.stack);
+ startActivity(intent);
+ }
+
+ @Override
+ void onDirectoryChanged(int anim) {
+ final FragmentManager fm = getFragmentManager();
+ final RootInfo root = getCurrentRoot();
+ final DocumentInfo cwd = getCurrentDirectory();
+
+ if (cwd == null) {
+ DirectoryFragment.showRecentsOpen(fm, anim);
+
+ // Start recents in grid when requesting visual things
+ final boolean visualMimes = MimePredicate.mimeMatches(
+ MimePredicate.VISUAL_MIMES, mState.acceptMimes);
+ mState.userMode = visualMimes ? State.MODE_GRID : State.MODE_LIST;
+ mState.derivedMode = mState.userMode;
+ } else {
+ if (mState.currentSearch != null) {
+ // Ongoing search
+ DirectoryFragment.showSearch(fm, root, mState.currentSearch, anim);
+ } else {
+ // Normal boring directory
+ DirectoryFragment.showNormal(fm, root, cwd, anim);
+ }
+ }
+ }
+
+ @Override
+ void onRootPicked(RootInfo root) {
+ super.onRootPicked(root);
+ mDrawer.setOpen(false);
+ }
+
+ @Override
+ public void onDocumentsPicked(List<DocumentInfo> docs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void onDocumentPicked(DocumentInfo doc, @Nullable DocumentContext siblings) {
+ if (doc.isDirectory()) {
+ openDirectory(doc);
+ } else {
+ openDocument(doc, siblings);
+ }
+ }
+
+ /**
+ * Launches an intent to view the specified document.
+ */
+ private void openDocument(DocumentInfo doc, @Nullable DocumentContext siblings) {
+ Intent intent = null;
+ if (siblings != null) {
+ QuickViewIntentBuilder builder = new QuickViewIntentBuilder(
+ getPackageManager(), getResources(), doc, siblings);
+ intent = builder.build();
+ }
+
+ if (intent != null) {
+ // TODO: un-work around issue b/24963914. Should be fixed soon.
+ try {
+ startActivity(intent);
+ return;
+ } catch (SecurityException e) {
+ // Carry on to regular view mode.
+ Log.e(TAG, "Caught security error: " + e.getLocalizedMessage());
+ }
+ }
+
+ // Fallback to traditional VIEW action...
+ intent = new Intent(Intent.ACTION_VIEW);
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setData(doc.derivedUri);
+
+ if (DEBUG && intent.getClipData() != null) {
+ Log.d(TAG, "Starting intent w/ clip data: " + intent.getClipData());
+ }
+
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Snackbars.makeSnackbar(
+ this, R.string.toast_no_application, Snackbar.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ DirectoryFragment dir;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_A:
+ dir = DirectoryFragment.get(getFragmentManager());
+ dir.selectAllFiles();
+ return true;
+ case KeyEvent.KEYCODE_C:
+ // TODO: Should be statically bound using alphabeticShortcut. See b/21330356.
+ dir = DirectoryFragment.get(getFragmentManager());
+ dir.copySelectedToClipboard();
+ return true;
+ case KeyEvent.KEYCODE_V:
+ // TODO: Should be statically bound using alphabeticShortcut. See b/21330356.
+ dir = DirectoryFragment.get(getFragmentManager());
+ dir.pasteFromClipboard();
+ return true;
+ default:
+ return super.onKeyShortcut(keyCode, event);
+ }
+ }
+
+ @Override
+ void saveStackBlocking() {
+ final ContentResolver resolver = getContentResolver();
+ final ContentValues values = new ContentValues();
+
+ final byte[] rawStack = DurableUtils.writeToArrayOrNull(
+ getDisplayState().stack);
+
+ // Remember location for next app launch
+ final String packageName = getCallingPackageMaybeExtra();
+ values.clear();
+ values.put(ResumeColumns.STACK, rawStack);
+ values.put(ResumeColumns.EXTERNAL, 0);
+ resolver.insert(RecentsProvider.buildResume(packageName), values);
+ }
+
+ @Override
+ void onTaskFinished(Uri... uris) {
+ Log.d(TAG, "onFinished() " + Arrays.toString(uris));
+
+ final Intent intent = new Intent();
+ if (uris.length == 1) {
+ intent.setData(uris[0]);
+ } else if (uris.length > 1) {
+ final ClipData clipData = new ClipData(
+ null, mState.acceptMimes, new ClipData.Item(uris[0]));
+ for (int i = 1; i < uris.length; i++) {
+ clipData.addItem(new ClipData.Item(uris[i]));
+ }
+ intent.setClipData(clipData);
+ }
+
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+
+ setResult(Activity.RESULT_OK, intent);
+ finish();
+ }
+}
diff --git a/src/com/android/documentsui/FilteringCursorWrapper.java b/src/com/android/documentsui/FilteringCursorWrapper.java
index 1cbc221..7426af5 100644
--- a/src/com/android/documentsui/FilteringCursorWrapper.java
+++ b/src/com/android/documentsui/FilteringCursorWrapper.java
@@ -16,7 +16,8 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Shared.TAG;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
@@ -65,7 +66,9 @@
}
}
- Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount);
+ if (DEBUG && mCount != cursor.getCount()) {
+ Log.d(TAG, "Before filtering " + cursor.getCount() + ", after " + mCount);
+ }
}
@Override
diff --git a/src/com/android/documentsui/GridItemThumbnail.java b/src/com/android/documentsui/GridItemThumbnail.java
new file mode 100644
index 0000000..38d6d72
--- /dev/null
+++ b/src/com/android/documentsui/GridItemThumbnail.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * Ensures that grid thumbnails are always square.
+ */
+public class GridItemThumbnail extends ImageView {
+ public GridItemThumbnail(Context context) {
+ super(context);
+ }
+
+ public GridItemThumbnail(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public GridItemThumbnail(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // Grid layout uses item width to figure out the number of columns, then dynamically fits
+ // rows into the view. The upshot of this is that changing the item width will mess up the
+ // grid layout - so to make the items square, throw out the height and use the width for
+ // both dimensions. The grid layout will correctly adjust the row height.
+ //
+ // Note that this code will need to be changed if the layout manager's orientation is
+ // changed from VERTICAL to HORIZONTAL.
+ super.onMeasure(widthMeasureSpec, widthMeasureSpec);
+ }
+}
diff --git a/src/com/android/documentsui/IconUtils.java b/src/com/android/documentsui/IconUtils.java
index b43fedf..a1213d2 100644
--- a/src/com/android/documentsui/IconUtils.java
+++ b/src/com/android/documentsui/IconUtils.java
@@ -23,13 +23,11 @@
import android.provider.DocumentsContract.Document;
import android.util.TypedValue;
-import com.google.android.collect.Maps;
-
import java.util.HashMap;
public class IconUtils {
- private static HashMap<String, Integer> sMimeIcons = Maps.newHashMap();
+ private static HashMap<String, Integer> sMimeIcons = new HashMap<>();
private static void add(String mimeType, int resId) {
if (sMimeIcons.put(mimeType, resId) != null) {
@@ -224,7 +222,7 @@
return context.getDrawable(R.drawable.ic_doc_album);
}
- if (mode == DocumentsActivity.State.MODE_GRID) {
+ if (mode == State.MODE_GRID) {
return context.getDrawable(R.drawable.ic_grid_folder);
} else {
return context.getDrawable(R.drawable.ic_doc_folder);
diff --git a/src/com/android/documentsui/LauncherActivity.java b/src/com/android/documentsui/LauncherActivity.java
new file mode 100644
index 0000000..b3d0cf3
--- /dev/null
+++ b/src/com/android/documentsui/LauncherActivity.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.Shared.DEBUG;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.AppTask;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Provides FilesActivity task grouping support. This allows multiple FilesActivities to be
+ * launched (a behavior imparted by way of {@code documentLaunchMode="intoExisting"} and
+ * our use of pseudo document {@link Uri}s. This also lets us move an existing task
+ * to the foreground when a suitable task exists.
+ *
+ * Requires that {@code documentLaunchMode="intoExisting"} be set on target activity.
+ *
+ */
+public class LauncherActivity extends Activity {
+
+ private static final String LAUNCH_CONTROL_AUTHORITY = "com.android.documentsui.launchControl";
+ private static final String TAG = "LauncherActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActivityManager activities = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+
+ Intent intent = findTask(activities);
+ if (intent != null) {
+ restoreTask(intent);
+ } else {
+ startTask();
+ }
+
+ finish();
+ }
+
+ private @Nullable Intent findTask(ActivityManager activities) {
+ List<AppTask> tasks = activities.getAppTasks();
+ for (AppTask task : tasks) {
+ Intent intent = task.getTaskInfo().baseIntent;
+ Uri uri = intent.getData();
+ if (isLaunchUri(uri)) {
+ return intent;
+ }
+ }
+ return null;
+ }
+
+ private void startTask() {
+ Intent intent = createLaunchIntent(this);
+ if (DEBUG) Log.d(TAG, "Starting new task > " + intent.getData());
+ startActivity(intent);
+ }
+
+ private void restoreTask(Intent intent) {
+ if (DEBUG) Log.d(TAG, "Restoring existing task > " + intent.getData());
+ // TODO: This doesn't appear to restore a task once it has stopped running.
+ startActivity(intent);
+ }
+
+ static Intent createLaunchIntent(Context context) {
+ Intent intent = new Intent(context, FilesActivity.class);
+ intent.setData(buildLaunchUri());
+ return intent;
+ }
+
+ private static Uri buildLaunchUri() {
+ return new Uri.Builder()
+ .authority(LAUNCH_CONTROL_AUTHORITY)
+ .fragment(String.valueOf(System.currentTimeMillis()))
+ .build();
+ }
+
+ static boolean isLaunchUri(@Nullable Uri uri) {
+ boolean result = uri != null && LAUNCH_CONTROL_AUTHORITY.equals(uri.getAuthority());
+ return result;
+ }
+}
diff --git a/src/com/android/documentsui/ListItem.java b/src/com/android/documentsui/ListItem.java
new file mode 100644
index 0000000..5c40f1b
--- /dev/null
+++ b/src/com/android/documentsui/ListItem.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+/**
+ * Layout for a single item in List mode. This class overrides the default focus listener in order
+ * to light up a focus indicator when it is focused.
+ */
+public class ListItem extends LinearLayout
+{
+ public ListItem(Context context) {
+ super(context);
+ }
+
+ public ListItem(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+ View indicator = findViewById(R.id.focus_indicator);
+ if (gainFocus) {
+ TypedValue color = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, color, true);
+ indicator.setBackgroundColor(color.data);
+ } else {
+ indicator.setBackgroundColor(android.R.color.transparent);
+ }
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ }
+}
diff --git a/src/com/android/documentsui/LocalPreferences.java b/src/com/android/documentsui/LocalPreferences.java
index e6c5ae2..113e9d7 100644
--- a/src/com/android/documentsui/LocalPreferences.java
+++ b/src/com/android/documentsui/LocalPreferences.java
@@ -24,8 +24,10 @@
private static final String KEY_FILE_SIZE = "fileSize";
public static boolean getDisplayAdvancedDevices(Context context) {
+ boolean defaultAdvanced = context.getResources()
+ .getBoolean(R.bool.config_defaultAdvancedDevices);
return PreferenceManager.getDefaultSharedPreferences(context)
- .getBoolean(KEY_ADVANCED_DEVICES, false);
+ .getBoolean(KEY_ADVANCED_DEVICES, defaultAdvanced);
}
public static boolean getDisplayFileSize(Context context) {
diff --git a/src/com/android/documentsui/Menus.java b/src/com/android/documentsui/Menus.java
new file mode 100644
index 0000000..5277d2b
--- /dev/null
+++ b/src/com/android/documentsui/Menus.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.view.Menu;
+import android.view.MenuItem;
+
+public final class Menus {
+
+ private Menus() {}
+
+ /**
+ * Disables hidden menu items so that they are not invokable via command shortcuts
+ */
+ public static void disableHiddenItems(Menu menu, MenuItem... exclusions) {
+ for (int i = 0; i < menu.size(); i++) {
+ MenuItem item = menu.getItem(i);
+ if (item.isVisible()) {
+ continue;
+ }
+ if (contains(exclusions, item)) {
+ continue;
+ }
+ item.setEnabled(false);
+ }
+ }
+
+ private static boolean contains(MenuItem[] exclusions, MenuItem item) {
+ for (int x = 0; x < exclusions.length; x++) {
+ if (exclusions[x] == item) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/documentsui/MessageBar.java b/src/com/android/documentsui/MessageBar.java
new file mode 100644
index 0000000..5c6213f
--- /dev/null
+++ b/src/com/android/documentsui/MessageBar.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.annotation.Nullable;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * A message bar displaying some info/error messages and a Dismiss button.
+ */
+public class MessageBar extends Fragment {
+ private View mView;
+ private ViewGroup mContainer;
+
+ /**
+ * Creates an instance of a MessageBar. Note that the new MessagBar is not visible by default,
+ * and has to be shown by calling MessageBar.show.
+ */
+ public static MessageBar create(FragmentManager fm) {
+ final MessageBar fragment = new MessageBar();
+
+ final FragmentTransaction ft = fm.beginTransaction();
+ ft.replace(R.id.container_message_bar, fragment);
+ ft.commitAllowingStateLoss();
+
+ return fragment;
+ }
+
+ /**
+ * Sets the info message. Can be null, in which case no info message will be displayed. The
+ * message bar layout will be adjusted accordingly.
+ */
+ public void setInfo(@Nullable String info) {
+ View infoContainer = mView.findViewById(R.id.container_info);
+ if (info != null) {
+ TextView infoText = (TextView) mView.findViewById(R.id.textview_info);
+ infoText.setText(info);
+ infoContainer.setVisibility(View.VISIBLE);
+ } else {
+ infoContainer.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Sets the error message. Can be null, in which case no error message will be displayed. The
+ * message bar layout will be adjusted accordingly.
+ */
+ public void setError(@Nullable String error) {
+ View errorView = mView.findViewById(R.id.container_error);
+ if (error != null) {
+ TextView errorText = (TextView) mView.findViewById(R.id.textview_error);
+ errorText.setText(error);
+ errorView.setVisibility(View.VISIBLE);
+ } else {
+ errorView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+ mView = inflater.inflate(R.layout.fragment_message_bar, container, false);
+
+ ImageView infoIcon = (ImageView) mView.findViewById(R.id.icon_info);
+ infoIcon.setImageResource(R.drawable.ic_dialog_info);
+
+ ImageView errorIcon = (ImageView) mView.findViewById(R.id.icon_error);
+ errorIcon.setImageResource(R.drawable.ic_dialog_alert);
+
+ Button dismiss = (Button) mView.findViewById(R.id.button_dismiss);
+ dismiss.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hide();
+ }
+ });
+
+ mContainer = container;
+
+ return mView;
+ }
+
+ public void hide() {
+ // The container view is used to show/hide the error bar. If a container is not provided,
+ // fall back to showing/hiding the error bar View, which also works, but does not provide
+ // the same animated transition.
+ if (mContainer != null) {
+ mContainer.setVisibility(View.GONE);
+ } else {
+ mView.setVisibility(View.GONE);
+ }
+ }
+
+ public void show() {
+ // The container view is used to show/hide the error bar. If a container is not provided,
+ // fall back to showing/hiding the error bar View, which also works, but does not provide
+ // the same animated transition.
+ if (mContainer != null) {
+ mContainer.setVisibility(View.VISIBLE);
+ } else {
+ mView.setVisibility(View.VISIBLE);
+ }
+ }
+}
diff --git a/src/com/android/documentsui/PickFragment.java b/src/com/android/documentsui/PickFragment.java
index d9b8568..bbf4682 100644
--- a/src/com/android/documentsui/PickFragment.java
+++ b/src/com/android/documentsui/PickFragment.java
@@ -16,13 +16,11 @@
package com.android.documentsui;
-import android.R.string;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
-import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,8 +28,6 @@
import com.android.documentsui.model.DocumentInfo;
-import java.util.Locale;
-
/**
* Display pick confirmation bar, usually for selecting a directory.
*/
@@ -39,6 +35,7 @@
public static final String TAG = "PickFragment";
private int mAction;
+ private int mTransferMode;
private DocumentInfo mPickTarget;
private View mContainer;
private Button mPick;
@@ -93,10 +90,11 @@
};
/**
- * @param action Which action defined in BaseActivity.State is the picker shown for.
+ * @param action Which action defined in State is the picker shown for.
*/
- public void setPickTarget(int action, DocumentInfo pickTarget) {
+ public void setPickTarget(int action, int transferMode, DocumentInfo pickTarget) {
mAction = action;
+ mTransferMode = transferMode;
mPickTarget = pickTarget;
if (mContainer != null) {
updateView();
@@ -108,11 +106,11 @@
*/
private void updateView() {
switch (mAction) {
- case BaseActivity.State.ACTION_OPEN_TREE:
+ case State.ACTION_OPEN_TREE:
mPick.setText(R.string.button_select);
mCancel.setVisibility(View.GONE);
break;
- case BaseActivity.State.ACTION_OPEN_COPY_DESTINATION:
+ case State.ACTION_PICK_COPY_DESTINATION:
mPick.setText(R.string.button_copy);
mCancel.setVisibility(View.VISIBLE);
break;
@@ -122,7 +120,7 @@
}
if (mPickTarget != null && (
- mAction == BaseActivity.State.ACTION_OPEN_TREE ||
+ mAction == State.ACTION_OPEN_TREE ||
mPickTarget.isCreateSupported())) {
mContainer.setVisibility(View.VISIBLE);
} else {
diff --git a/src/com/android/documentsui/ProviderExecutor.java b/src/com/android/documentsui/ProviderExecutor.java
index f94aebd..b0e332f 100644
--- a/src/com/android/documentsui/ProviderExecutor.java
+++ b/src/com/android/documentsui/ProviderExecutor.java
@@ -20,8 +20,6 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -32,7 +30,7 @@
public class ProviderExecutor extends Thread implements Executor {
@GuardedBy("sExecutors")
- private static HashMap<String, ProviderExecutor> sExecutors = Maps.newHashMap();
+ private static HashMap<String, ProviderExecutor> sExecutors = new HashMap<>();
public static ProviderExecutor forAuthority(String authority) {
synchronized (sExecutors) {
@@ -53,7 +51,7 @@
private final LinkedBlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
- private final ArrayList<WeakReference<Preemptable>> mPreemptable = Lists.newArrayList();
+ private final ArrayList<WeakReference<Preemptable>> mPreemptable = new ArrayList<>();
private void preempt() {
synchronized (mPreemptable) {
diff --git a/src/com/android/documentsui/QuickViewIntentBuilder.java b/src/com/android/documentsui/QuickViewIntentBuilder.java
new file mode 100644
index 0000000..605c530
--- /dev/null
+++ b/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Shared.TAG;
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.documentsui.BaseActivity.DocumentContext;
+import com.android.documentsui.model.DocumentInfo;
+
+/**
+ * Provides support for gather a list of quick-viewable files into a quick view intent.
+ */
+final class QuickViewIntentBuilder {
+
+ private final DocumentInfo mDocument;
+ private final DocumentContext mContext;
+
+ private final PackageManager mPkgManager;
+ private final Resources mResources;
+
+ private ClipData mClipData;
+ private int mDocumentLocation;
+
+ public QuickViewIntentBuilder(
+ PackageManager pkgManager,
+ Resources resources,
+ DocumentInfo doc,
+ DocumentContext context) {
+
+ mPkgManager = pkgManager;
+ mResources = resources;
+ mDocument = doc;
+ mContext = context;
+ }
+
+ /**
+ * Builds the intent for quick viewing. Short circuits building if a handler cannot
+ * be resolved; in this case {@code null} is returned.
+ */
+ @Nullable Intent build() {
+ if (DEBUG) Log.d(TAG, "Preparing intent for doc:" + mDocument.documentId);
+
+ String trustedPkg = mResources.getString(R.string.trusted_quick_viewer_package);
+
+ Intent intent = new Intent(Intent.ACTION_QUICK_VIEW);
+ intent.setDataAndType(mDocument.derivedUri, mDocument.mimeType);
+ intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ if (TextUtils.isEmpty(trustedPkg)) {
+ if (hasRegisteredHandler(intent)) {
+ return intent;
+ }
+ } else {
+ intent.setPackage(trustedPkg);
+ if (hasRegisteredHandler(intent)) {
+ // We have a trusted handler. Load all of the docs into the intent.
+ Cursor cursor = mContext.getCursor();
+ for (int i = 0; i < cursor.getCount(); i++) {
+ onNextItem(i, cursor);
+ }
+ intent.putExtra(Intent.EXTRA_INDEX, mDocumentLocation);
+ intent.setClipData(mClipData);
+
+ return intent;
+ } else {
+ Log.e(TAG, "Can't resolve trusted quick view package: " + trustedPkg);
+ }
+ }
+
+ return null;
+ }
+
+ private boolean hasRegisteredHandler(Intent intent) {
+ // Try to resolve the intent. If a matching app isn't installed, it won't resolve.
+ return intent.resolveActivity(mPkgManager) != null;
+ }
+
+ private void onNextItem(int index, Cursor cursor) {
+ cursor.moveToPosition(index);
+
+ String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ if (Document.MIME_TYPE_DIR.equals(mimeType)) {
+ return;
+ }
+
+ String id = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ String authority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+ Uri uri = DocumentsContract.buildDocumentUri(authority, id);
+ if (DEBUG) Log.d(TAG, "Including file[" + id + "] @ " + uri);
+
+ if (id.equals(mDocument.documentId)) {
+ if (DEBUG) Log.d(TAG, "Found starting point for QV. " + index);
+ mDocumentLocation = index;
+ }
+
+ ClipData.Item item = new ClipData.Item(uri);
+ if (mClipData == null) {
+ mClipData = new ClipData(
+ "URIs", new String[]{ClipDescription.MIMETYPE_TEXT_URILIST}, item);
+ } else {
+ mClipData.addItem(item);
+ }
+ }
+}
diff --git a/src/com/android/documentsui/RecentLoader.java b/src/com/android/documentsui/RecentLoader.java
index f5908c5..4bd6ae6 100644
--- a/src/com/android/documentsui/RecentLoader.java
+++ b/src/com/android/documentsui/RecentLoader.java
@@ -16,8 +16,9 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Shared.TAG;
+import static com.android.documentsui.State.SORT_ORDER_LAST_MODIFIED;
import android.app.ActivityManager;
import android.content.AsyncTaskLoader;
@@ -34,16 +35,15 @@
import android.text.format.DateUtils;
import android.util.Log;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Maps;
-import com.google.common.collect.Lists;
+import com.android.internal.annotations.GuardedBy;
import com.google.common.util.concurrent.AbstractFuture;
import libcore.io.IoUtils;
import java.io.Closeable;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -53,8 +53,6 @@
import java.util.concurrent.TimeUnit;
public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
- private static final boolean LOGD = true;
-
// TODO: clean up cursor ownership so background thread doesn't traverse
// previously returned cursors for filtering/sorting; this currently races
// with the UI thread.
@@ -81,7 +79,8 @@
private final RootsCache mRoots;
private final State mState;
- private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();
+ @GuardedBy("mTasks")
+ private final HashMap<RootInfo, RecentTask> mTasks = new HashMap<>();
private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
@@ -167,6 +166,12 @@
@Override
public DirectoryResult loadInBackground() {
+ synchronized (mTasks) {
+ return loadInBackgroundLocked();
+ }
+ }
+
+ private DirectoryResult loadInBackgroundLocked() {
if (mFirstPassLatch == null) {
// First time through we kick off all the recent tasks, and wait
// around to see if everyone finishes quickly.
@@ -196,7 +201,7 @@
// Collect all finished tasks
boolean allDone = true;
- List<Cursor> cursors = Lists.newArrayList();
+ List<Cursor> cursors = new ArrayList<>();
for (RecentTask task : mTasks.values()) {
if (task.isDone()) {
try {
@@ -221,7 +226,7 @@
}
}
- if (LOGD) {
+ if (DEBUG) {
Log.d(TAG, "Found " + cursors.size() + " of " + mTasks.size() + " recent queries done");
}
@@ -304,8 +309,10 @@
// Ensure the loader is stopped
onStopLoading();
- for (RecentTask task : mTasks.values()) {
- IoUtils.closeQuietly(task);
+ synchronized (mTasks) {
+ for (RecentTask task : mTasks.values()) {
+ IoUtils.closeQuietly(task);
+ }
}
IoUtils.closeQuietly(mResult);
diff --git a/src/com/android/documentsui/RecentsCreateFragment.java b/src/com/android/documentsui/RecentsCreateFragment.java
index e11d7d9..bb6c3b5 100644
--- a/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/src/com/android/documentsui/RecentsCreateFragment.java
@@ -16,7 +16,7 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -30,27 +30,25 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils.TruncateAt;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.BaseAdapter;
import android.widget.ImageView;
-import android.widget.ListView;
import android.widget.TextView;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
import libcore.io.IoUtils;
@@ -65,8 +63,7 @@
public class RecentsCreateFragment extends Fragment {
private View mEmptyView;
- private ListView mListView;
-
+ private RecyclerView mRecView;
private DocumentStackAdapter mAdapter;
private LoaderCallbacks<List<DocumentStack>> mCallbacks;
@@ -86,13 +83,14 @@
final View view = inflater.inflate(R.layout.fragment_directory, container, false);
+ mRecView = (RecyclerView) view.findViewById(R.id.list);
+ mRecView.setLayoutManager(new LinearLayoutManager(getContext()));
+ mRecView.addOnItemTouchListener(mItemListener);
+
mEmptyView = view.findViewById(android.R.id.empty);
- mListView = (ListView) view.findViewById(R.id.list);
- mListView.setOnItemClickListener(mItemListener);
-
mAdapter = new DocumentStackAdapter();
- mListView.setAdapter(mAdapter);
+ mRecView.setAdapter(mAdapter);
final RootsCache roots = DocumentsApplication.getRootsCache(context);
final State state = ((BaseActivity) getActivity()).getDisplayState();
@@ -106,7 +104,7 @@
@Override
public void onLoadFinished(
Loader<List<DocumentStack>> loader, List<DocumentStack> data) {
- mAdapter.swapStacks(data);
+ mAdapter.update(data);
// When launched into empty recents, show drawer
if (mAdapter.isEmpty() && !state.stackTouched &&
@@ -117,7 +115,7 @@
@Override
public void onLoaderReset(Loader<List<DocumentStack>> loader) {
- mAdapter.swapStacks(null);
+ mAdapter.update(null);
}
};
@@ -136,13 +134,24 @@
getLoaderManager().destroyLoader(LOADER_RECENTS);
}
- private OnItemClickListener mItemListener = new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final DocumentStack stack = mAdapter.getItem(position);
- ((BaseActivity) getActivity()).onStackPicked(stack);
- }
- };
+ private RecyclerView.OnItemTouchListener mItemListener =
+ new RecyclerView.OnItemTouchListener() {
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ Events.MotionInputEvent event = new Events.MotionInputEvent(e, mRecView);
+ if (event.isOverItem() && event.isActionUp()) {
+ final DocumentStack stack = mAdapter.getItem(event.getItemPosition());
+ ((BaseActivity) getActivity()).onStackPicked(stack);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {}
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+ };
public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> {
private final RootsCache mRoots;
@@ -157,7 +166,7 @@
@Override
public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
- final ArrayList<DocumentStack> result = Lists.newArrayList();
+ final ArrayList<DocumentStack> result = new ArrayList<>();
final ContentResolver resolver = getContext().getContentResolver();
final Cursor cursor = resolver.query(
@@ -188,14 +197,32 @@
}
}
- private class DocumentStackAdapter extends BaseAdapter {
- private List<DocumentStack> mStacks;
+ private static final class StackHolder extends RecyclerView.ViewHolder {
+ public View view;
+ public StackHolder(View view) {
+ super(view);
+ this.view = view;
+ }
+ }
- public DocumentStackAdapter() {
+ private class DocumentStackAdapter extends RecyclerView.Adapter<StackHolder> {
+ @Nullable private List<DocumentStack> mItems;
+
+ DocumentStack getItem(int position) {
+ return mItems.get(position);
}
- public void swapStacks(List<DocumentStack> stacks) {
- mStacks = stacks;
+ @Override
+ public int getItemCount() {
+ return mItems == null ? 0 : mItems.size();
+ }
+
+ boolean isEmpty() {
+ return mItems == null ? true : mItems.isEmpty();
+ }
+
+ void update(@Nullable List<DocumentStack> items) {
+ mItems = items;
if (isEmpty()) {
mEmptyView.setVisibility(View.VISIBLE);
@@ -207,17 +234,22 @@
}
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final Context context = parent.getContext();
+ public StackHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final Context context = parent.getContext();
- if (convertView == null) {
- final LayoutInflater inflater = LayoutInflater.from(context);
- convertView = inflater.inflate(R.layout.item_doc_list, parent, false);
- }
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ return new StackHolder(
+ (View) inflater.inflate(R.layout.item_doc_list, parent, false));
+ }
- final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime);
- final TextView title = (TextView) convertView.findViewById(android.R.id.title);
- final View line2 = convertView.findViewById(R.id.line2);
+ @Override
+ public void onBindViewHolder(StackHolder holder, int position) {
+ Context context = getContext();
+ View view = holder.view;
+
+ final ImageView iconMime = (ImageView) view.findViewById(R.id.icon_mime);
+ final TextView title = (TextView) view.findViewById(android.R.id.title);
+ final View line2 = view.findViewById(R.id.line2);
final DocumentStack stack = getItem(position);
iconMime.setImageDrawable(stack.root.loadIcon(context));
@@ -235,23 +267,6 @@
title.setEllipsize(TruncateAt.MIDDLE);
if (line2 != null) line2.setVisibility(View.GONE);
-
- return convertView;
- }
-
- @Override
- public int getCount() {
- return mStacks != null ? mStacks.size() : 0;
- }
-
- @Override
- public DocumentStack getItem(int position) {
- return mStacks.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return getItem(position).hashCode();
}
}
diff --git a/src/com/android/documentsui/RecentsProvider.java b/src/com/android/documentsui/RecentsProvider.java
index f6e4349..82eb732 100644
--- a/src/com/android/documentsui/RecentsProvider.java
+++ b/src/com/android/documentsui/RecentsProvider.java
@@ -39,6 +39,7 @@
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
import com.android.internal.util.Predicate;
+
import com.google.android.collect.Sets;
import libcore.io.IoUtils;
diff --git a/src/com/android/documentsui/RootsCache.java b/src/com/android/documentsui/RootsCache.java
index fbcb938..72ee6cb 100644
--- a/src/com/android/documentsui/RootsCache.java
+++ b/src/com/android/documentsui/RootsCache.java
@@ -16,7 +16,8 @@
package com.android.documentsui;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.Shared.TAG;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
@@ -34,19 +35,18 @@
import android.os.SystemClock;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
+import android.support.annotation.VisibleForTesting;
import android.util.Log;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
+
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import libcore.io.IoUtils;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -58,8 +58,6 @@
* Cache of known storage backends and their roots.
*/
public class RootsCache {
- private static final boolean LOGD = false;
-
public static final Uri sNotificationUri = Uri.parse(
"content://com.android.documentsui.roots/");
@@ -74,10 +72,10 @@
@GuardedBy("mLock")
private Multimap<String, RootInfo> mRoots = ArrayListMultimap.create();
@GuardedBy("mLock")
- private HashSet<String> mStoppedAuthorities = Sets.newHashSet();
+ private HashSet<String> mStoppedAuthorities = new HashSet<>();
@GuardedBy("mObservedAuthorities")
- private final HashSet<String> mObservedAuthorities = Sets.newHashSet();
+ private final HashSet<String> mObservedAuthorities = new HashSet<>();
public RootsCache(Context context) {
mContext = context;
@@ -91,7 +89,7 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- if (LOGD) Log.d(TAG, "Updating roots due to change at " + uri);
+ if (DEBUG) Log.d(TAG, "Updating roots due to change at " + uri);
updateAuthorityAsync(uri.getAuthority());
}
}
@@ -104,6 +102,7 @@
mRecentsRoot.authority = null;
mRecentsRoot.rootId = null;
mRecentsRoot.derivedIcon = R.drawable.ic_root_recent;
+ mRecentsRoot.derivedType = RootInfo.TYPE_RECENTS;
mRecentsRoot.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE
| Root.FLAG_SUPPORTS_IS_CHILD;
mRecentsRoot.title = mContext.getString(R.string.root_recent);
@@ -148,7 +147,7 @@
final ContentResolver resolver = mContext.getContentResolver();
synchronized (mLock) {
for (String authority : mStoppedAuthorities) {
- if (LOGD) Log.d(TAG, "Loading stopped authority " + authority);
+ if (DEBUG) Log.d(TAG, "Loading stopped authority " + authority);
mRoots.putAll(authority, loadRootsForAuthority(resolver, authority));
}
mStoppedAuthorities.clear();
@@ -159,7 +158,7 @@
private final String mFilterPackage;
private final Multimap<String, RootInfo> mTaskRoots = ArrayListMultimap.create();
- private final HashSet<String> mTaskStoppedAuthorities = Sets.newHashSet();
+ private final HashSet<String> mTaskStoppedAuthorities = new HashSet<>();
/**
* Update all roots.
@@ -199,7 +198,8 @@
}
final long delta = SystemClock.elapsedRealtime() - start;
- Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
+ if (DEBUG)
+ Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms");
synchronized (mLock) {
mRoots = mTaskRoots;
mStoppedAuthorities = mTaskStoppedAuthorities;
@@ -213,7 +213,7 @@
// Ignore stopped packages for now; we might query them
// later during UI interaction.
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0) {
- if (LOGD) Log.d(TAG, "Ignoring stopped authority " + info.authority);
+ if (DEBUG) Log.d(TAG, "Ignoring stopped authority " + info.authority);
mTaskStoppedAuthorities.add(info.authority);
return;
}
@@ -223,7 +223,7 @@
if (mFilterPackage != null && !mFilterPackage.equals(info.packageName)) {
synchronized (mLock) {
if (mTaskRoots.putAll(info.authority, mRoots.get(info.authority))) {
- if (LOGD) Log.d(TAG, "Used cached roots for " + info.authority);
+ if (DEBUG) Log.d(TAG, "Used cached roots for " + info.authority);
cacheHit = true;
}
}
@@ -241,7 +241,7 @@
* Bring up requested provider and query for all active roots.
*/
private Collection<RootInfo> loadRootsForAuthority(ContentResolver resolver, String authority) {
- if (LOGD) Log.d(TAG, "Loading roots for " + authority);
+ if (DEBUG) Log.d(TAG, "Loading roots for " + authority);
synchronized (mObservedAuthorities) {
if (mObservedAuthorities.add(authority)) {
@@ -251,7 +251,7 @@
}
}
- final List<RootInfo> roots = Lists.newArrayList();
+ final List<RootInfo> roots = new ArrayList<>();
final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
ContentProviderClient client = null;
@@ -350,7 +350,7 @@
@VisibleForTesting
static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
- final List<RootInfo> matching = Lists.newArrayList();
+ final List<RootInfo> matching = new ArrayList<>();
for (RootInfo root : roots) {
final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0;
final boolean supportsIsChild = (root.flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0;
@@ -360,7 +360,7 @@
// Exclude read-only devices when creating
if (state.action == State.ACTION_CREATE && !supportsCreate) continue;
- if (state.action == State.ACTION_OPEN_COPY_DESTINATION && !supportsCreate) continue;
+ if (state.action == State.ACTION_PICK_COPY_DESTINATION && !supportsCreate) continue;
// Exclude roots that don't support directory picking
if (state.action == State.ACTION_OPEN_TREE && !supportsIsChild) continue;
// Exclude advanced devices when not requested
@@ -370,10 +370,13 @@
// Exclude downloads roots that don't support directory creation
// TODO: Add flag to check the root supports directory creation or not.
if (state.directoryCopy && root.isDownloads()) continue;
- // Only show empty roots when creating
- if ((state.action != State.ACTION_CREATE ||
- state.action != State.ACTION_OPEN_TREE ||
- state.action != State.ACTION_OPEN_COPY_DESTINATION) && empty) continue;
+
+ // Only show empty roots when creating, or in browse mode.
+ if (empty && (state.action == State.ACTION_OPEN
+ || state.action == State.ACTION_GET_CONTENT)) {
+ if (DEBUG) Log.i(TAG, "Skipping empty root: " + root);
+ continue;
+ }
// Only include roots that serve requested content
final boolean overlap =
@@ -385,7 +388,7 @@
// Exclude roots from the calling package.
if (state.excludedAuthorities.contains(root.authority)) {
- if (LOGD) Log.d(TAG, "Excluding root " + root.authority + " from calling package.");
+ if (DEBUG) Log.d(TAG, "Excluding root " + root.authority + " from calling package.");
continue;
}
diff --git a/src/com/android/documentsui/RootsFragment.java b/src/com/android/documentsui/RootsFragment.java
index fd67a77..4c844c4 100644
--- a/src/com/android/documentsui/RootsFragment.java
+++ b/src/com/android/documentsui/RootsFragment.java
@@ -16,6 +16,8 @@
package com.android.documentsui;
+import static com.android.documentsui.Shared.DEBUG;
+
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
@@ -30,6 +32,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.Formatter;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -41,11 +44,10 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Lists;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -57,12 +59,13 @@
*/
public class RootsFragment extends Fragment {
+ private static final String TAG = "RootsFragment";
+ private static final String EXTRA_INCLUDE_APPS = "includeApps";
+
private ListView mList;
private RootsAdapter mAdapter;
-
private LoaderCallbacks<Collection<RootInfo>> mCallbacks;
- private static final String EXTRA_INCLUDE_APPS = "includeApps";
public static void show(FragmentManager fm, Intent includeApps) {
final Bundle args = new Bundle();
@@ -181,6 +184,8 @@
} else if (item instanceof AppItem) {
DocumentsActivity activity = DocumentsActivity.get(RootsFragment.this);
activity.onAppPicked(((AppItem) item).info);
+ } else if (item instanceof SpacerItem) {
+ if (DEBUG) Log.d(TAG, "Ignoring click on spacer item.");
} else {
throw new IllegalStateException("Unknown root: " + item);
}
@@ -287,58 +292,32 @@
public RootsAdapter(Context context, Collection<RootInfo> roots, Intent includeApps) {
super(context, 0);
- RootItem recents = null;
- RootItem images = null;
- RootItem videos = null;
- RootItem audio = null;
- RootItem downloads = null;
+ final List<RootItem> libraries = new ArrayList<>();
+ final List<RootItem> others = new ArrayList<>();
- final List<RootInfo> clouds = Lists.newArrayList();
- final List<RootInfo> locals = Lists.newArrayList();
-
- for (RootInfo root : roots) {
- if (root.isRecents()) {
- recents = new RootItem(root);
- } else if (root.isExternalStorage()) {
- locals.add(root);
- } else if (root.isDownloads()) {
- downloads = new RootItem(root);
- } else if (root.isImages()) {
- images = new RootItem(root);
- } else if (root.isVideos()) {
- videos = new RootItem(root);
- } else if (root.isAudio()) {
- audio = new RootItem(root);
+ for (final RootInfo root : roots) {
+ final RootItem item = new RootItem(root);
+ if (root.isLibrary() || root.isHome()) {
+ libraries.add(item);
} else {
- clouds.add(root);
+ others.add(item);
}
}
final RootComparator comp = new RootComparator();
- Collections.sort(clouds, comp);
- Collections.sort(locals, comp);
+ Collections.sort(libraries, comp);
+ Collections.sort(others, comp);
- if (recents != null) add(recents);
-
- for (RootInfo cloud : clouds) {
- add(new RootItem(cloud));
- }
-
- if (images != null) add(images);
- if (videos != null) add(videos);
- if (audio != null) add(audio);
- if (downloads != null) add(downloads);
-
- for (RootInfo local : locals) {
- add(new RootItem(local));
- }
+ addAll(libraries);
+ add(new SpacerItem());
+ addAll(others);
if (includeApps != null) {
final PackageManager pm = context.getPackageManager();
final List<ResolveInfo> infos = pm.queryIntentActivities(
includeApps, PackageManager.MATCH_DEFAULT_ONLY);
- final List<AppItem> apps = Lists.newArrayList();
+ final List<AppItem> apps = new ArrayList<>();
// Omit ourselves from the list
for (ResolveInfo info : infos) {
@@ -349,9 +328,7 @@
if (apps.size() > 0) {
add(new SpacerItem());
- for (Item item : apps) {
- add(item);
- }
+ addAll(apps);
}
}
}
@@ -388,15 +365,20 @@
}
}
- public static class RootComparator implements Comparator<RootInfo> {
+ public static class RootComparator implements Comparator<RootItem> {
@Override
- public int compare(RootInfo lhs, RootInfo rhs) {
- final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title);
+ public int compare(RootItem lhs, RootItem rhs) {
+ // Sort by root type, then title, then summary.
+ int score = lhs.root.derivedType - rhs.root.derivedType;
if (score != 0) {
return score;
- } else {
- return DocumentInfo.compareToIgnoreCaseNullable(lhs.summary, rhs.summary);
}
+ score = DocumentInfo.compareToIgnoreCaseNullable(lhs.root.title, rhs.root.title);
+ if (score != 0) {
+ return score;
+ }
+
+ return DocumentInfo.compareToIgnoreCaseNullable(lhs.root.summary, rhs.root.summary);
}
}
}
diff --git a/src/com/android/documentsui/RootsLoader.java b/src/com/android/documentsui/RootsLoader.java
index 49651b4..c81377a 100644
--- a/src/com/android/documentsui/RootsLoader.java
+++ b/src/com/android/documentsui/RootsLoader.java
@@ -19,7 +19,6 @@
import android.content.AsyncTaskLoader;
import android.content.Context;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
import java.util.Collection;
diff --git a/src/com/android/documentsui/SaveFragment.java b/src/com/android/documentsui/SaveFragment.java
index ce98db2..f3b750a 100644
--- a/src/com/android/documentsui/SaveFragment.java
+++ b/src/com/android/documentsui/SaveFragment.java
@@ -23,6 +23,7 @@
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -79,6 +80,17 @@
mDisplayName = (EditText) view.findViewById(android.R.id.title);
mDisplayName.addTextChangedListener(mDisplayNameWatcher);
mDisplayName.setText(getArguments().getString(EXTRA_DISPLAY_NAME));
+ mDisplayName.setOnKeyListener(
+ new View.OnKeyListener() {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER && mSave.isEnabled()) {
+ performSave();
+ return true;
+ }
+ return false;
+ }
+ });
mSave = (Button) view.findViewById(android.R.id.button1);
mSave.setOnClickListener(mSaveListener);
@@ -113,17 +125,22 @@
private View.OnClickListener mSaveListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
- if (mReplaceTarget != null) {
- activity.onSaveRequested(mReplaceTarget);
- } else {
- final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
- final String displayName = mDisplayName.getText().toString();
- activity.onSaveRequested(mimeType, displayName);
- }
+ performSave();
}
+
};
+ private void performSave() {
+ final DocumentsActivity activity = DocumentsActivity.get(SaveFragment.this);
+ if (mReplaceTarget != null) {
+ activity.onSaveRequested(mReplaceTarget);
+ } else {
+ final String mimeType = getArguments().getString(EXTRA_MIME_TYPE);
+ final String displayName = mDisplayName.getText().toString();
+ activity.onSaveRequested(mimeType, displayName);
+ }
+ }
+
/**
* Set given document as target for in-place writing if user hits save
* without changing the filename. Can be set to {@code null} if user
@@ -139,7 +156,11 @@
}
}
- public void setSaveEnabled(boolean enabled) {
+ public void prepareForDirectory(DocumentInfo cwd) {
+ setSaveEnabled(cwd != null && cwd.isCreateSupported());
+ }
+
+ private void setSaveEnabled(boolean enabled) {
mSave.setEnabled(enabled);
}
diff --git a/src/com/android/documentsui/SectionedListAdapter.java b/src/com/android/documentsui/SectionedListAdapter.java
index 088e3fa..ae959f9 100644
--- a/src/com/android/documentsui/SectionedListAdapter.java
+++ b/src/com/android/documentsui/SectionedListAdapter.java
@@ -22,8 +22,6 @@
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
-import com.google.android.collect.Lists;
-
import java.util.ArrayList;
/**
@@ -31,7 +29,7 @@
* provide a header, and correctly handling item types across child adapters.
*/
public class SectionedListAdapter extends BaseAdapter {
- private ArrayList<SectionAdapter> mSections = Lists.newArrayList();
+ private ArrayList<SectionAdapter> mSections = new ArrayList<>();
public interface SectionAdapter extends ListAdapter {
public View getHeaderView(View convertView, ViewGroup parent);
diff --git a/src/com/android/documentsui/Shared.java b/src/com/android/documentsui/Shared.java
new file mode 100644
index 0000000..570c9bf
--- /dev/null
+++ b/src/com/android/documentsui/Shared.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+
+/** @hide */
+public final class Shared {
+ /** Intent action name to pick a copy destination. */
+ public static final String ACTION_PICK_COPY_DESTINATION =
+ "com.android.documentsui.PICK_COPY_DESTINATION";
+
+ /**
+ * Extra boolean flag for {@link ACTION_PICK_COPY_DESTINATION}, which
+ * specifies if the destination directory needs to create new directory or not.
+ */
+ public static final String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY";
+
+ public static final boolean DEBUG = true;
+ public static final String TAG = "Documents";
+ public static final String EXTRA_STACK = "com.android.documentsui.STACK";
+
+ /**
+ * Generates a formatted quantity string.
+ */
+ public static final String getQuantityString(Context context, int resourceId, int quantity) {
+ return context.getResources().getQuantityString(resourceId, quantity, quantity);
+ }
+}
diff --git a/src/com/android/documentsui/Snackbars.java b/src/com/android/documentsui/Snackbars.java
new file mode 100644
index 0000000..48c1a73
--- /dev/null
+++ b/src/com/android/documentsui/Snackbars.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.Activity;
+import android.support.design.widget.Snackbar;
+import android.view.View;
+
+public final class Snackbars {
+ private Snackbars() {}
+
+ public static final Snackbar makeSnackbar(Activity activity, int messageId, int duration) {
+ return Snackbars.makeSnackbar(activity, activity.getResources().getText(messageId), duration);
+ }
+
+ public static final Snackbar makeSnackbar(Activity activity, CharSequence message, int duration)
+ {
+ final View view = checkNotNull(activity.findViewById(R.id.coordinator_layout));
+ return Snackbar.make(view, message, duration);
+ }
+}
diff --git a/src/com/android/documentsui/SortingCursorWrapper.java b/src/com/android/documentsui/SortingCursorWrapper.java
index 3ec3d1c..6698ff1 100644
--- a/src/com/android/documentsui/SortingCursorWrapper.java
+++ b/src/com/android/documentsui/SortingCursorWrapper.java
@@ -16,9 +16,9 @@
package com.android.documentsui;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
-import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
+import static com.android.documentsui.State.SORT_ORDER_DISPLAY_NAME;
+import static com.android.documentsui.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.State.SORT_ORDER_SIZE;
import static com.android.documentsui.model.DocumentInfo.getCursorLong;
import static com.android.documentsui.model.DocumentInfo.getCursorString;
diff --git a/src/com/android/documentsui/State.java b/src/com/android/documentsui/State.java
new file mode 100644
index 0000000..c81d4fb
--- /dev/null
+++ b/src/com/android/documentsui/State.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.DurableUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class State implements android.os.Parcelable {
+ public int action;
+ public String[] acceptMimes;
+
+ /** Explicit user choice */
+ public int userMode = MODE_UNKNOWN;
+ /** Derived after loader */
+ public int derivedMode = MODE_LIST;
+
+ /** Explicit user choice */
+ public int userSortOrder = SORT_ORDER_UNKNOWN;
+ /** Derived after loader */
+ public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME;
+
+ public boolean allowMultiple;
+ public boolean forceSize;
+ public boolean showSize;
+ public boolean localOnly;
+ public boolean forceAdvanced;
+ public boolean showAdvanced;
+ public boolean stackTouched;
+ public boolean restored;
+ public boolean directoryCopy;
+ public boolean openableOnly;
+ /** Transfer mode for file copy/move operations. */
+ public int transferMode;
+
+ /** Current user navigation stack; empty implies recents. */
+ public DocumentStack stack = new DocumentStack();
+ /** Currently active search, overriding any stack. */
+ public String currentSearch;
+
+ /** Instance state for every shown directory */
+ public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>();
+
+ /** Currently copying file */
+ public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
+
+ /** Name of the package that started DocsUI */
+ public List<String> excludedAuthorities = new ArrayList<>();
+
+ public static final int ACTION_OPEN = 1;
+ public static final int ACTION_CREATE = 2;
+ public static final int ACTION_GET_CONTENT = 3;
+ public static final int ACTION_OPEN_TREE = 4;
+ public static final int ACTION_MANAGE = 5;
+ public static final int ACTION_BROWSE = 6;
+ public static final int ACTION_PICK_COPY_DESTINATION = 8;
+
+ public static final int MODE_UNKNOWN = 0;
+ public static final int MODE_LIST = 1;
+ public static final int MODE_GRID = 2;
+
+ public static final int SORT_ORDER_UNKNOWN = 0;
+ public static final int SORT_ORDER_DISPLAY_NAME = 1;
+ public static final int SORT_ORDER_LAST_MODIFIED = 2;
+ public static final int SORT_ORDER_SIZE = 3;
+
+ public void initAcceptMimes(Intent intent) {
+ if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
+ acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
+ } else {
+ String glob = intent.getType();
+ acceptMimes = new String[] { glob != null ? glob : "*/*" };
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(action);
+ out.writeInt(userMode);
+ out.writeStringArray(acceptMimes);
+ out.writeInt(userSortOrder);
+ out.writeInt(allowMultiple ? 1 : 0);
+ out.writeInt(forceSize ? 1 : 0);
+ out.writeInt(showSize ? 1 : 0);
+ out.writeInt(localOnly ? 1 : 0);
+ out.writeInt(forceAdvanced ? 1 : 0);
+ out.writeInt(showAdvanced ? 1 : 0);
+ out.writeInt(stackTouched ? 1 : 0);
+ out.writeInt(restored ? 1 : 0);
+ DurableUtils.writeToParcel(out, stack);
+ out.writeString(currentSearch);
+ out.writeMap(dirState);
+ out.writeList(selectedDocumentsForCopy);
+ out.writeList(excludedAuthorities);
+ out.writeInt(openableOnly ? 1 : 0);
+ }
+
+ public static final Creator<State> CREATOR = new Creator<State>() {
+ @Override
+ public State createFromParcel(Parcel in) {
+ final State state = new State();
+ state.action = in.readInt();
+ state.userMode = in.readInt();
+ state.acceptMimes = in.readStringArray();
+ state.userSortOrder = in.readInt();
+ state.allowMultiple = in.readInt() != 0;
+ state.forceSize = in.readInt() != 0;
+ state.showSize = in.readInt() != 0;
+ state.localOnly = in.readInt() != 0;
+ state.forceAdvanced = in.readInt() != 0;
+ state.showAdvanced = in.readInt() != 0;
+ state.stackTouched = in.readInt() != 0;
+ state.restored = in.readInt() != 0;
+ DurableUtils.readFromParcel(in, state.stack);
+ state.currentSearch = in.readString();
+ in.readMap(state.dirState, null);
+ in.readList(state.selectedDocumentsForCopy, null);
+ in.readList(state.excludedAuthorities, null);
+ state.openableOnly = in.readInt() != 0;
+ return state;
+ }
+
+ @Override
+ public State[] newArray(int size) {
+ return new State[size];
+ }
+ };
+}
diff --git a/src/com/android/documentsui/UriDerivativeLoader.java b/src/com/android/documentsui/UriDerivativeLoader.java
index 1a5bb0c..7bb662c 100644
--- a/src/com/android/documentsui/UriDerivativeLoader.java
+++ b/src/com/android/documentsui/UriDerivativeLoader.java
@@ -27,16 +27,16 @@
* changes while started, manages {@link CancellationSignal}, and caches
* returned results.
*/
-public abstract class UriDerivativeLoader<P, R> extends AsyncTaskLoader<R> {
+public abstract class UriDerivativeLoader<Param, Res> extends AsyncTaskLoader<Res> {
final ForceLoadContentObserver mObserver;
- private final P mParam;
+ private final Param mParam;
- private R mResult;
+ private Res mResult;
private CancellationSignal mCancellationSignal;
@Override
- public final R loadInBackground() {
+ public final Res loadInBackground() {
synchronized (this) {
if (isLoadInBackgroundCanceled()) {
throw new OperationCanceledException();
@@ -52,7 +52,7 @@
}
}
- public abstract R loadInBackground(P param, CancellationSignal signal);
+ public abstract Res loadInBackground(Param param, CancellationSignal signal);
@Override
public void cancelLoadInBackground() {
@@ -66,12 +66,12 @@
}
@Override
- public void deliverResult(R result) {
+ public void deliverResult(Res result) {
if (isReset()) {
closeQuietly(result);
return;
}
- R oldResult = mResult;
+ Res oldResult = mResult;
mResult = result;
if (isStarted()) {
@@ -83,7 +83,7 @@
}
}
- public UriDerivativeLoader(Context context, P param) {
+ public UriDerivativeLoader(Context context, Param param) {
super(context);
mObserver = new ForceLoadContentObserver();
mParam = param;
@@ -105,7 +105,7 @@
}
@Override
- public void onCanceled(R result) {
+ public void onCanceled(Res result) {
closeQuietly(result);
}
@@ -122,7 +122,7 @@
getContext().getContentResolver().unregisterContentObserver(mObserver);
}
- private void closeQuietly(R result) {
+ private void closeQuietly(Res result) {
if (result instanceof AutoCloseable) {
try {
((AutoCloseable) result).close();
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
new file mode 100644
index 0000000..2e7c908
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -0,0 +1,1994 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_MANAGE;
+import static com.android.documentsui.State.MODE_GRID;
+import static com.android.documentsui.State.MODE_LIST;
+import static com.android.documentsui.State.MODE_UNKNOWN;
+import static com.android.documentsui.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.model.DocumentInfo.getCursorInt;
+import static com.android.documentsui.model.DocumentInfo.getCursorLong;
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.ClipData;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Loader;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Looper;
+import android.os.OperationCanceledException;
+import android.os.Parcelable;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.design.widget.Snackbar;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.LayoutManager;
+import android.support.v7.widget.RecyclerView.OnItemTouchListener;
+import android.support.v7.widget.RecyclerView.RecyclerListener;
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.text.format.Formatter;
+import android.text.format.Time;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.TypedValue;
+import android.view.ActionMode;
+import android.view.DragEvent;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.CopyService;
+import com.android.documentsui.DirectoryLoader;
+import com.android.documentsui.DirectoryResult;
+import com.android.documentsui.DocumentClipper;
+import com.android.documentsui.DocumentsActivity;
+import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.Events;
+import com.android.documentsui.IconUtils;
+import com.android.documentsui.Menus;
+import com.android.documentsui.MessageBar;
+import com.android.documentsui.MimePredicate;
+import com.android.documentsui.ProviderExecutor;
+import com.android.documentsui.R;
+import com.android.documentsui.RecentLoader;
+import com.android.documentsui.RecentsProvider;
+import com.android.documentsui.RootCursorWrapper;
+import com.android.documentsui.RootsCache;
+import com.android.documentsui.Shared;
+import com.android.documentsui.Snackbars;
+import com.android.documentsui.State;
+import com.android.documentsui.ThumbnailCache;
+import com.android.documentsui.BaseActivity.DocumentContext;
+import com.android.documentsui.ProviderExecutor.Preemptable;
+import com.android.documentsui.Shared;
+import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.dirlist.MultiSelectManager.Callback;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
+import com.android.internal.annotations.GuardedBy;
+
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Display the documents inside a single directory.
+ */
+public class DirectoryFragment extends Fragment {
+
+ public static final String TAG = "DirectoryFragment";
+
+ public static final int TYPE_NORMAL = 1;
+ public static final int TYPE_SEARCH = 2;
+ public static final int TYPE_RECENT_OPEN = 3;
+
+ public static final int ANIM_NONE = 1;
+ public static final int ANIM_SIDE = 2;
+ public static final int ANIM_DOWN = 3;
+ public static final int ANIM_UP = 4;
+
+ public static final int REQUEST_COPY_DESTINATION = 1;
+
+ private static final int LOADER_ID = 42;
+ private static final boolean DEBUG_ENABLE_DND = true;
+
+ private static final String EXTRA_TYPE = "type";
+ private static final String EXTRA_ROOT = "root";
+ private static final String EXTRA_DOC = "doc";
+ private static final String EXTRA_QUERY = "query";
+ private static final String EXTRA_IGNORE_STATE = "ignoreState";
+
+ private Model mModel;
+ private MultiSelectManager mSelectionManager;
+ private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener();
+ private ItemClickListener mItemClickListener = new ItemClickListener();
+
+ private View mEmptyView;
+ private RecyclerView mRecView;
+
+ private int mType = TYPE_NORMAL;
+ private String mStateKey;
+
+ private int mLastMode = MODE_UNKNOWN;
+ private int mLastSortOrder = SORT_ORDER_UNKNOWN;
+ private boolean mLastShowSize;
+ private boolean mHideGridTitles;
+ private boolean mSvelteRecents;
+ private Point mThumbSize;
+ private DocumentsAdapter mAdapter;
+ private LoaderCallbacks<DirectoryResult> mCallbacks;
+ private FragmentTuner mTuner;
+ private DocumentClipper mClipper;
+ // These are lazily initialized.
+ private LinearLayoutManager mListLayout;
+ private GridLayoutManager mGridLayout;
+ private int mColumnCount = 1; // This will get updated when layout changes.
+
+ private MessageBar mMessageBar;
+ private View mProgressBar;
+
+ private int mSelectedItemColor;
+ private int mDefaultItemColor;
+
+ public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
+ show(fm, TYPE_NORMAL, root, doc, null, anim);
+ }
+
+ public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) {
+ show(fm, TYPE_SEARCH, root, null, query, anim);
+ }
+
+ public static void showRecentsOpen(FragmentManager fm, int anim) {
+ show(fm, TYPE_RECENT_OPEN, null, null, null, anim);
+ }
+
+ private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc,
+ String query, int anim) {
+ final Bundle args = new Bundle();
+ args.putInt(EXTRA_TYPE, type);
+ args.putParcelable(EXTRA_ROOT, root);
+ args.putParcelable(EXTRA_DOC, doc);
+ args.putString(EXTRA_QUERY, query);
+
+ final FragmentTransaction ft = fm.beginTransaction();
+ switch (anim) {
+ case ANIM_SIDE:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ break;
+ case ANIM_DOWN:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen);
+ break;
+ case ANIM_UP:
+ ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up);
+ break;
+ }
+
+ final DirectoryFragment fragment = new DirectoryFragment();
+ fragment.setArguments(args);
+
+ ft.replace(R.id.container_directory, fragment);
+ ft.commitAllowingStateLoss();
+ }
+
+ private static String buildStateKey(RootInfo root, DocumentInfo doc) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(root != null ? root.authority : "null").append(';');
+ builder.append(root != null ? root.rootId : "null").append(';');
+ builder.append(doc != null ? doc.documentId : "null");
+ return builder.toString();
+ }
+
+ public static @Nullable DirectoryFragment get(FragmentManager fm) {
+ // TODO: deal with multiple directories shown at once
+ Fragment fragment = fm.findFragmentById(R.id.container_directory);
+ return fragment instanceof DirectoryFragment
+ ? (DirectoryFragment) fragment
+ : null;
+ }
+
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.fragment_directory, container, false);
+
+ mMessageBar = MessageBar.create(getChildFragmentManager());
+ mProgressBar = view.findViewById(R.id.progressbar);
+
+ mEmptyView = view.findViewById(android.R.id.empty);
+
+ mRecView = (RecyclerView) view.findViewById(R.id.list);
+ mRecView.setRecyclerListener(
+ new RecyclerListener() {
+ @Override
+ public void onViewRecycled(ViewHolder holder) {
+ cancelThumbnailTask(holder.itemView);
+ }
+ });
+
+ // TODO: Rather than update columns on layout changes, push this
+ // code (or something like it) into GridLayoutManager.
+ mRecView.addOnLayoutChangeListener(
+ new View.OnLayoutChangeListener() {
+
+ @Override
+ public void onLayoutChange(
+ View v, int left, int top, int right, int bottom, int oldLeft,
+ int oldTop, int oldRight, int oldBottom) {
+ mColumnCount = calculateColumnCount();
+ if (mGridLayout != null) {
+ mGridLayout.setSpanCount(mColumnCount);
+ }
+ }
+ });
+
+ mRecView.setItemAnimator(new DirectoryItemAnimator(getActivity()));
+
+ // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration).
+ if (DEBUG_ENABLE_DND) {
+ setupDragAndDropOnDirectoryView(mRecView);
+ }
+
+ return view;
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+
+ // Cancel any outstanding thumbnail requests
+ final int count = mRecView.getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View view = mRecView.getChildAt(i);
+ cancelThumbnailTask(view);
+ }
+
+ // Clear any outstanding selection
+ mSelectionManager.clearSelection();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ final Context context = getActivity();
+ final State state = getDisplayState();
+
+ final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+ final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+ mAdapter = new DocumentsAdapter(context);
+ mRecView.setAdapter(mAdapter);
+
+ mDefaultItemColor = context.getResources().getColor(android.R.color.transparent);
+ // Get the accent color.
+ TypedValue selColor = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.colorAccent, selColor, true);
+ // Set the opacity to 10%.
+ mSelectedItemColor = (selColor.data & 0x00ffffff) | 0x16000000;
+
+ GestureDetector.SimpleOnGestureListener listener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ return DirectoryFragment.this.onSingleTapUp(e);
+ }
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ Log.d(TAG, "Handling double tap.");
+ return DirectoryFragment.this.onDoubleTap(e);
+ }
+ };
+
+ final GestureDetector detector = new GestureDetector(this.getContext(), listener);
+ detector.setOnDoubleTapListener(listener);
+
+ mRecView.addOnItemTouchListener(
+ new OnItemTouchListener() {
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ detector.onTouchEvent(e);
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {}
+
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+ });
+
+ // TODO: instead of inserting the view into the constructor, extract listener-creation code
+ // and set the listener on the view after the fact. Then the view doesn't need to be passed
+ // into the selection manager.
+ mSelectionManager = new MultiSelectManager(
+ mRecView,
+ state.allowMultiple
+ ? MultiSelectManager.MODE_MULTIPLE
+ : MultiSelectManager.MODE_SINGLE);
+ mSelectionManager.addCallback(new SelectionModeListener());
+
+ mModel = new Model(context, mAdapter);
+ mModel.addUpdateListener(mModelUpdateListener);
+
+ mType = getArguments().getInt(EXTRA_TYPE);
+ mStateKey = buildStateKey(root, doc);
+
+ mTuner = FragmentTuner.pick(state);
+ mClipper = new DocumentClipper(context);
+
+ if (mType == TYPE_RECENT_OPEN) {
+ // Hide titles when showing recents for picking images/videos
+ mHideGridTitles = MimePredicate.mimeMatches(
+ MimePredicate.VISUAL_MIMES, state.acceptMimes);
+ } else {
+ mHideGridTitles = (doc != null) && doc.isGridTitlesHidden();
+ }
+
+ final ActivityManager am = (ActivityManager) context.getSystemService(
+ Context.ACTIVITY_SERVICE);
+ mSvelteRecents = am.isLowRamDevice() && (mType == TYPE_RECENT_OPEN);
+
+ mCallbacks = new LoaderCallbacks<DirectoryResult>() {
+ @Override
+ public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) {
+ final String query = getArguments().getString(EXTRA_QUERY);
+
+ Uri contentsUri;
+ switch (mType) {
+ case TYPE_NORMAL:
+ contentsUri = DocumentsContract.buildChildDocumentsUri(
+ doc.authority, doc.documentId);
+ if (state.action == ACTION_MANAGE) {
+ contentsUri = DocumentsContract.setManageMode(contentsUri);
+ }
+ return new DirectoryLoader(
+ context, mType, root, doc, contentsUri, state.userSortOrder);
+ case TYPE_SEARCH:
+ contentsUri = DocumentsContract.buildSearchDocumentsUri(
+ root.authority, root.rootId, query);
+ if (state.action == ACTION_MANAGE) {
+ contentsUri = DocumentsContract.setManageMode(contentsUri);
+ }
+ return new DirectoryLoader(
+ context, mType, root, doc, contentsUri, state.userSortOrder);
+ case TYPE_RECENT_OPEN:
+ final RootsCache roots = DocumentsApplication.getRootsCache(context);
+ return new RecentLoader(context, roots, state);
+ default:
+ throw new IllegalStateException("Unknown type " + mType);
+ }
+ }
+
+ @Override
+ public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
+ if (!isAdded()) return;
+
+ mModel.update(result);
+
+ // Push latest state up to UI
+ // TODO: if mode change was racing with us, don't overwrite it
+ if (result.mode != MODE_UNKNOWN) {
+ state.derivedMode = result.mode;
+ }
+ state.derivedSortOrder = result.sortOrder;
+ ((BaseActivity) context).onStateChanged();
+
+ updateDisplayState();
+
+ // When launched into empty recents, show drawer
+ if (mType == TYPE_RECENT_OPEN && mModel.isEmpty() && !state.stackTouched &&
+ context instanceof DocumentsActivity) {
+ ((DocumentsActivity) context).setRootsDrawerOpen(true);
+ }
+
+ // Restore any previous instance state
+ final SparseArray<Parcelable> container = state.dirState.remove(mStateKey);
+ if (container != null && !getArguments().getBoolean(EXTRA_IGNORE_STATE, false)) {
+ getView().restoreHierarchyState(container);
+ } else if (mLastSortOrder != state.derivedSortOrder) {
+ mRecView.smoothScrollToPosition(0);
+ }
+
+ mLastSortOrder = state.derivedSortOrder;
+ }
+
+ @Override
+ public void onLoaderReset(Loader<DirectoryResult> loader) {
+ mModel.update(null);
+ }
+ };
+
+ // Kick off loader at least once
+ getLoaderManager().restartLoader(LOADER_ID, null, mCallbacks);
+
+ updateDisplayState();
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // There's only one request code right now. Replace this with a switch statement or
+ // something more scalable when more codes are added.
+ if (requestCode != REQUEST_COPY_DESTINATION) {
+ return;
+ }
+ if (resultCode == Activity.RESULT_CANCELED || data == null) {
+ // User pressed the back button or otherwise cancelled the destination pick. Don't
+ // proceed with the copy.
+ return;
+ }
+
+ CopyService.start(getActivity(), getDisplayState().selectedDocumentsForCopy,
+ (DocumentStack) data.getParcelableExtra(Shared.EXTRA_STACK),
+ data.getIntExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_COPY));
+ }
+
+ private int getEventAdapterPosition(MotionEvent e) {
+ View view = mRecView.findChildViewUnder(e.getX(), e.getY());
+ return view != null ? mRecView.getChildAdapterPosition(view) : RecyclerView.NO_POSITION;
+ }
+
+ private boolean onSingleTapUp(MotionEvent e) {
+ // Only respond to touch events. Single-click mouse events are selection events and are
+ // handled by the selection manager. Tap events that occur while the selection manager is
+ // active are also selection events.
+ if (Events.isTouchEvent(e) && !mSelectionManager.hasSelection()) {
+ int position = getEventAdapterPosition(e);
+ if (position != RecyclerView.NO_POSITION) {
+ return handleViewItem(position);
+ }
+ }
+ return false;
+ }
+
+ protected boolean onDoubleTap(MotionEvent e) {
+ if (Events.isMouseEvent(e)) {
+ Log.d(TAG, "Handling double tap from mouse.");
+ int position = getEventAdapterPosition(e);
+ if (position != RecyclerView.NO_POSITION) {
+ return handleViewItem(position);
+ }
+ }
+ return false;
+ }
+
+ private boolean handleViewItem(int position) {
+ final Cursor cursor = mModel.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ if (mTuner.isDocumentEnabled(docMimeType, docFlags)) {
+ final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+ ((BaseActivity) getActivity()).onDocumentPicked(doc, mModel);
+ mSelectionManager.clearSelection();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+
+ // Remember last scroll location
+ final SparseArray<Parcelable> container = new SparseArray<Parcelable>();
+ getView().saveHierarchyState(container);
+ final State state = getDisplayState();
+ state.dirState.put(mStateKey, container);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updateDisplayState();
+ }
+
+ public void onDisplayStateChanged() {
+ updateDisplayState();
+ }
+
+ public void onUserSortOrderChanged() {
+ // Sort order change always triggers reload; we'll trigger state change
+ // on the flip side.
+ getLoaderManager().restartLoader(LOADER_ID, null, mCallbacks);
+ }
+
+ public void onUserModeChanged() {
+ final ContentResolver resolver = getActivity().getContentResolver();
+ final State state = getDisplayState();
+
+ final RootInfo root = getArguments().getParcelable(EXTRA_ROOT);
+ final DocumentInfo doc = getArguments().getParcelable(EXTRA_DOC);
+
+ if (root != null && doc != null) {
+ final Uri stateUri = RecentsProvider.buildState(
+ root.authority, root.rootId, doc.documentId);
+ final ContentValues values = new ContentValues();
+ values.put(StateColumns.MODE, state.userMode);
+
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ resolver.insert(stateUri, values);
+ return null;
+ }
+ }.execute();
+ }
+
+ // Mode change is just visual change; no need to kick loader, and
+ // deliver change event immediately.
+ state.derivedMode = state.userMode;
+ ((BaseActivity) getActivity()).onStateChanged();
+
+ updateDisplayState();
+ }
+
+ private void updateDisplayState() {
+ final State state = getDisplayState();
+
+ if (mLastMode == state.derivedMode && mLastShowSize == state.showSize) return;
+ mLastMode = state.derivedMode;
+ mLastShowSize = state.showSize;
+
+ updateLayout(state.derivedMode);
+
+ mRecView.setAdapter(mAdapter);
+ }
+
+ /**
+ * Returns a {@code LayoutManager} for {@code mode}, lazily initializing
+ * classes as needed.
+ */
+ private void updateLayout(int mode) {
+ final int thumbSize;
+
+ final LayoutManager layout;
+ switch (mode) {
+ case MODE_GRID:
+ thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
+ if (mGridLayout == null) {
+ mGridLayout = new GridLayoutManager(getContext(), mColumnCount );
+ }
+ layout = mGridLayout;
+ break;
+ case MODE_LIST:
+ thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
+ if (mListLayout == null) {
+ mListLayout = new LinearLayoutManager(getContext());
+ }
+ layout = mListLayout;
+ break;
+ case MODE_UNKNOWN:
+ default:
+ throw new IllegalArgumentException("Unsupported layout mode: " + mode);
+ }
+
+ mRecView.setLayoutManager(layout);
+ // TODO: Once b/23691541 is resolved, use a listener within MultiSelectManager instead of
+ // imperatively calling this function.
+ mSelectionManager.handleLayoutChanged();
+ // setting layout manager automatically invalidates existing ViewHolders.
+ mThumbSize = new Point(thumbSize, thumbSize);
+ }
+
+ private int calculateColumnCount() {
+ int cellWidth = getResources().getDimensionPixelSize(R.dimen.grid_width);
+ int cellMargin = 2 * getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
+ int viewPadding = mRecView.getPaddingLeft() + mRecView.getPaddingRight();
+
+ checkState(mRecView.getWidth() > 0);
+ int columnCount = Math.max(1,
+ (mRecView.getWidth() - viewPadding) / (cellWidth + cellMargin));
+
+ return columnCount;
+ }
+
+ /**
+ * Manages the integration between our ActionMode and MultiSelectManager, initiating
+ * ActionMode when there is a selection, canceling it when there is no selection,
+ * and clearing selection when action mode is explicitly exited by the user.
+ */
+ private final class SelectionModeListener
+ implements MultiSelectManager.Callback, ActionMode.Callback {
+
+ private Selection mSelected = new Selection();
+ private ActionMode mActionMode;
+ private int mNoDeleteCount = 0;
+ private Menu mMenu;
+
+ @Override
+ public boolean onBeforeItemStateChange(int position, boolean selected) {
+ if (selected) {
+ final Cursor cursor = mModel.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ return mTuner.canSelectType(docMimeType, docFlags);
+ }
+ return true;
+ }
+
+ @Override
+ public void onItemStateChanged(int position, boolean selected) {
+ final Cursor cursor = mModel.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) {
+ mNoDeleteCount += selected ? 1 : -1;
+ }
+ }
+
+ @Override
+ public void onSelectionChanged() {
+ mSelectionManager.getSelection(mSelected);
+ TypedValue color = new TypedValue();
+ if (mSelected.size() > 0) {
+ if (DEBUG) Log.d(TAG, "Maybe starting action mode.");
+ if (mActionMode == null) {
+ if (DEBUG) Log.d(TAG, "Yeah. Starting action mode.");
+ mActionMode = getActivity().startActionMode(this);
+ }
+ getActivity().getTheme().resolveAttribute(R.attr.colorActionMode, color, true);
+ updateActionMenu();
+ } else {
+ if (DEBUG) Log.d(TAG, "Finishing action mode.");
+ if (mActionMode != null) {
+ mActionMode.finish();
+ }
+ getActivity().getTheme().resolveAttribute(
+ android.R.attr.colorPrimaryDark, color, true);
+ }
+ getActivity().getWindow().setStatusBarColor(color.data);
+
+ if (mActionMode != null) {
+ mActionMode.setTitle(String.valueOf(mSelected.size()));
+ }
+ }
+
+ // Called when the user exits the action mode
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ if (DEBUG) Log.d(TAG, "Handling action mode destroyed.");
+ mActionMode = null;
+ // clear selection
+ mSelectionManager.clearSelection();
+ mSelected.clear();
+ mNoDeleteCount = 0;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ int size = mSelectionManager.getSelection().size();
+ mode.getMenuInflater().inflate(R.menu.mode_directory, menu);
+ mode.setTitle(TextUtils.formatSelectedCount(size));
+ return (size > 0);
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ mMenu = menu;
+ updateActionMenu();
+ return true;
+ }
+
+ private void updateActionMenu() {
+ checkNotNull(mMenu);
+ // Delegate update logic to our owning action, since specialized logic is desired.
+ mTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
+ Menus.disableHiddenItems(mMenu);
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+
+ Selection selection = mSelectionManager.getSelection(new Selection());
+
+ switch (item.getItemId()) {
+ case R.id.menu_open:
+ openDocuments(selection);
+ mode.finish();
+ return true;
+
+ case R.id.menu_share:
+ shareDocuments(selection);
+ mode.finish();
+ return true;
+
+ case R.id.menu_delete:
+ // Exit selection mode first, so we avoid deselecting deleted documents.
+ mode.finish();
+ deleteDocuments(selection);
+ return true;
+
+ case R.id.menu_copy_to:
+ transferDocuments(selection, CopyService.TRANSFER_MODE_COPY);
+ mode.finish();
+ return true;
+
+ case R.id.menu_move_to:
+ // Exit selection mode first, so we avoid deselecting deleted documents.
+ mode.finish();
+ transferDocuments(selection, CopyService.TRANSFER_MODE_MOVE);
+ return true;
+
+ case R.id.menu_copy_to_clipboard:
+ copySelectionToClipboard(selection);
+ return true;
+
+ case R.id.menu_select_all:
+ selectAllFiles();
+ return true;
+
+ default:
+ if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
+ return false;
+ }
+ }
+ }
+
+ private static void cancelThumbnailTask(View view) {
+ final ImageView iconThumb = (ImageView) view.findViewById(R.id.icon_thumb);
+ if (iconThumb != null) {
+ final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
+ if (oldTask != null) {
+ oldTask.preempt();
+ iconThumb.setTag(null);
+ }
+ }
+ }
+
+ private void openDocuments(final Selection selected) {
+ new GetDocumentsTask() {
+ @Override
+ void onDocumentsReady(List<DocumentInfo> docs) {
+ // TODO: Implement support in Files activity for opening multiple docs.
+ BaseActivity.get(DirectoryFragment.this).onDocumentsPicked(docs);
+ }
+ }.execute(selected);
+ }
+
+ private void shareDocuments(final Selection selected) {
+ new GetDocumentsTask() {
+ @Override
+ void onDocumentsReady(List<DocumentInfo> docs) {
+ Intent intent;
+
+ // Filter out directories - those can't be shared.
+ List<DocumentInfo> docsForSend = new ArrayList<>();
+ for (DocumentInfo doc: docs) {
+ if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
+ docsForSend.add(doc);
+ }
+ }
+
+ if (docsForSend.size() == 1) {
+ final DocumentInfo doc = docsForSend.get(0);
+
+ intent = new Intent(Intent.ACTION_SEND);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.setType(doc.mimeType);
+ intent.putExtra(Intent.EXTRA_STREAM, doc.derivedUri);
+
+ } else if (docsForSend.size() > 1) {
+ intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+
+ final ArrayList<String> mimeTypes = new ArrayList<>();
+ final ArrayList<Uri> uris = new ArrayList<>();
+ for (DocumentInfo doc : docsForSend) {
+ mimeTypes.add(doc.mimeType);
+ uris.add(doc.derivedUri);
+ }
+
+ intent.setType(findCommonMimeType(mimeTypes));
+ intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
+
+ } else {
+ return;
+ }
+
+ intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via));
+ startActivity(intent);
+ }
+ }.execute(selected);
+ }
+
+ private void deleteDocuments(final Selection selected) {
+ Context context = getActivity();
+ String message = Shared.getQuantityString(context, R.plurals.deleting, selected.size());
+
+ mModel.markForDeletion(selected);
+
+ final Activity activity = getActivity();
+ Snackbars.makeSnackbar(activity, message, Snackbar.LENGTH_LONG)
+ .setAction(
+ R.string.undo,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {}
+ })
+ .setCallback(
+ new Snackbar.Callback() {
+ @Override
+ public void onDismissed(Snackbar snackbar, int event) {
+ if (event == Snackbar.Callback.DISMISS_EVENT_ACTION) {
+ mModel.undoDeletion();
+ } else {
+ mModel.finalizeDeletion(
+ new Model.DeletionListener() {
+ @Override
+ public void onError() {
+ Snackbars.makeSnackbar(
+ activity,
+ R.string.toast_failed_delete,
+ Snackbar.LENGTH_LONG)
+ .show();
+
+ }
+ });
+ }
+ }
+ })
+ .show();
+ }
+
+ private void transferDocuments(final Selection selected, final int mode) {
+ // Pop up a dialog to pick a destination. This is inadequate but works for now.
+ // TODO: Implement a picker that is to spec.
+ final Intent intent = new Intent(
+ Shared.ACTION_PICK_COPY_DESTINATION,
+ Uri.EMPTY,
+ getActivity(),
+ DocumentsActivity.class);
+
+ new GetDocumentsTask() {
+ @Override
+ void onDocumentsReady(List<DocumentInfo> docs) {
+ getDisplayState().selectedDocumentsForCopy = docs;
+
+ boolean directoryCopy = false;
+ for (DocumentInfo info : docs) {
+ if (Document.MIME_TYPE_DIR.equals(info.mimeType)) {
+ directoryCopy = true;
+ break;
+ }
+ }
+ intent.putExtra(Shared.EXTRA_DIRECTORY_COPY, directoryCopy);
+ intent.putExtra(CopyService.EXTRA_TRANSFER_MODE, mode);
+ startActivityForResult(intent, REQUEST_COPY_DESTINATION);
+ }
+ }.execute(selected);
+ }
+
+ private State getDisplayState() {
+ return ((BaseActivity) getActivity()).getDisplayState();
+ }
+
+ // Provide a reference to the views for each data item
+ // Complex data items may need more than one view per item, and
+ // you provide access to all the views for a data item in a view holder
+ private final class DocumentHolder
+ extends RecyclerView.ViewHolder
+ implements View.OnKeyListener
+ {
+ public String docId; // The stable document id.
+ private ClickListener mClickListener;
+ private View.OnKeyListener mKeyListener;
+
+ public DocumentHolder(View view) {
+ super(view);
+ view.setOnKeyListener(this);
+ }
+
+ public void setSelected(boolean selected) {
+ itemView.setActivated(selected);
+ }
+
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ // Intercept enter key-up events, and treat them as clicks. Forward other events.
+ if (event.getAction() == KeyEvent.ACTION_UP &&
+ keyCode == KeyEvent.KEYCODE_ENTER) {
+ if (mClickListener != null) {
+ mClickListener.onClick(this);
+ }
+ return true;
+ } else if (mKeyListener != null) {
+ return mKeyListener.onKey(v, keyCode, event);
+ }
+ return false;
+ }
+
+ public void addClickListener(ClickListener listener) {
+ // Just handle one for now; switch to a list if necessary.
+ checkState(mClickListener == null);
+ mClickListener = listener;
+ }
+
+ public void addOnKeyListener(View.OnKeyListener listener) {
+ // Just handle one for now; switch to a list if necessary.
+ checkState(mKeyListener == null);
+ mKeyListener = listener;
+ }
+ }
+
+ interface ClickListener {
+ public void onClick(DocumentHolder doc);
+ }
+
+ void showEmptyView() {
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecView.setVisibility(View.GONE);
+ TextView msg = (TextView) mEmptyView.findViewById(R.id.message);
+ msg.setText(R.string.empty);
+ // No retry button for the empty view.
+ mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE);
+ }
+
+ void showErrorView() {
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecView.setVisibility(View.GONE);
+ TextView msg = (TextView) mEmptyView.findViewById(R.id.message);
+ msg.setText(R.string.query_error);
+ // TODO: Enable this once the retry button does something.
+ mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE);
+ }
+
+ void showRecyclerView() {
+ mEmptyView.setVisibility(View.GONE);
+ mRecView.setVisibility(View.VISIBLE);
+ }
+
+ private final class DocumentsAdapter extends RecyclerView.Adapter<DocumentHolder> {
+
+ private final Context mContext;
+ private final LayoutInflater mInflater;
+
+ public DocumentsAdapter(Context context) {
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public DocumentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ final State state = getDisplayState();
+ final LayoutInflater inflater = LayoutInflater.from(getContext());
+ View item = null;
+ switch (state.derivedMode) {
+ case MODE_GRID:
+ item = inflater.inflate(R.layout.item_doc_grid, parent, false);
+ break;
+ case MODE_LIST:
+ item = inflater.inflate(R.layout.item_doc_list, parent, false);
+ break;
+ case MODE_UNKNOWN:
+ default:
+ throw new IllegalStateException("Unsupported layout mode.");
+ }
+
+ DocumentHolder holder = new DocumentHolder(item);
+ holder.addClickListener(mItemClickListener);
+ holder.addOnKeyListener(mSelectionManager);
+ return holder;
+ }
+
+ /**
+ * Deal with selection changed events by using a custom ItemAnimator that just changes the
+ * background color. This works around focus issues (otherwise items lose focus when their
+ * selection state changes) but also optimizes change animations for selection.
+ */
+ @Override
+ public void onBindViewHolder(DocumentHolder holder, int position, List<Object> payload) {
+ final View itemView = holder.itemView;
+
+ if (payload.contains(MultiSelectManager.SELECTION_CHANGED_MARKER)) {
+ final boolean selected = isSelected(position);
+ itemView.setActivated(selected);
+ return;
+ } else {
+ onBindViewHolder(holder, position);
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(DocumentHolder holder, int position) {
+
+ final Context context = getContext();
+ final State state = getDisplayState();
+ final RootsCache roots = DocumentsApplication.getRootsCache(context);
+ final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
+ context, mThumbSize);
+
+ final Cursor cursor = mModel.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+
+ final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY);
+ final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID);
+ final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID);
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME);
+ final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+ final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON);
+ final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
+ final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY);
+ final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE);
+
+ holder.docId = docId;
+ final View itemView = holder.itemView;
+
+ holder.setSelected(isSelected(position));
+
+ final ImageView iconMime = (ImageView) itemView.findViewById(R.id.icon_mime);
+ final ImageView iconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb);
+ final TextView title = (TextView) itemView.findViewById(android.R.id.title);
+ final ImageView icon1 = (ImageView) itemView.findViewById(android.R.id.icon1);
+ final TextView summary = (TextView) itemView.findViewById(android.R.id.summary);
+ final TextView date = (TextView) itemView.findViewById(R.id.date);
+ final TextView size = (TextView) itemView.findViewById(R.id.size);
+
+ final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) iconThumb.getTag();
+ if (oldTask != null) {
+ oldTask.preempt();
+ iconThumb.setTag(null);
+ }
+
+ iconMime.animate().cancel();
+ iconThumb.animate().cancel();
+
+ final boolean supportsThumbnail = (docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0;
+ final boolean allowThumbnail = (state.derivedMode == MODE_GRID)
+ || MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, docMimeType);
+ final boolean showThumbnail = supportsThumbnail && allowThumbnail && !mSvelteRecents;
+
+ final boolean enabled = mTuner.isDocumentEnabled(docMimeType, docFlags);
+ final float iconAlpha = (state.derivedMode == MODE_LIST && !enabled) ? 0.5f : 1f;
+
+ boolean cacheHit = false;
+ if (showThumbnail) {
+ final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId);
+ final Bitmap cachedResult = thumbs.get(uri);
+ if (cachedResult != null) {
+ iconThumb.setImageBitmap(cachedResult);
+ cacheHit = true;
+ } else {
+ iconThumb.setImageDrawable(null);
+ // TODO: Hang this off DocumentHolder?
+ final ThumbnailAsyncTask task = new ThumbnailAsyncTask(
+ uri, iconMime, iconThumb, mThumbSize, iconAlpha);
+ iconThumb.setTag(task);
+ ProviderExecutor.forAuthority(docAuthority).execute(task);
+ }
+ }
+
+ // Always throw MIME icon into place, even when a thumbnail is being
+ // loaded in background.
+ if (cacheHit) {
+ iconMime.setAlpha(0f);
+ iconMime.setImageDrawable(null);
+ iconThumb.setAlpha(1f);
+ } else {
+ iconMime.setAlpha(1f);
+ iconThumb.setAlpha(0f);
+ iconThumb.setImageDrawable(null);
+ iconMime.setImageDrawable(
+ getDocumentIcon(mContext, docAuthority, docId, docMimeType, docIcon, state));
+ }
+
+ if ((state.derivedMode == MODE_GRID) && mHideGridTitles) {
+ title.setVisibility(View.GONE);
+ } else {
+ title.setText(docDisplayName);
+ title.setVisibility(View.VISIBLE);
+ }
+
+ Drawable iconDrawable = null;
+ if (mType == TYPE_RECENT_OPEN) {
+ // We've already had to enumerate roots before any results can
+ // be shown, so this will never block.
+ final RootInfo root = roots.getRootBlocking(docAuthority, docRootId);
+ iconDrawable = root.loadIcon(mContext);
+
+ if (summary != null) {
+ final boolean alwaysShowSummary = getResources()
+ .getBoolean(R.bool.always_show_summary);
+ if (alwaysShowSummary) {
+ summary.setText(root.getDirectoryString());
+ summary.setVisibility(View.VISIBLE);
+ } else {
+ if (iconDrawable != null && roots.isIconUniqueBlocking(root)) {
+ // No summary needed if icon speaks for itself
+ summary.setVisibility(View.INVISIBLE);
+ } else {
+ summary.setText(root.getDirectoryString());
+ summary.setVisibility(View.VISIBLE);
+ summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END);
+ }
+ }
+ }
+ } else {
+ // Directories showing thumbnails in grid mode get a little icon
+ // hint to remind user they're a directory.
+ if (Document.MIME_TYPE_DIR.equals(docMimeType) && state.derivedMode == MODE_GRID
+ && showThumbnail) {
+ iconDrawable = IconUtils.applyTintAttr(mContext, R.drawable.ic_doc_folder,
+ android.R.attr.textColorPrimaryInverse);
+ }
+
+ if (summary != null) {
+ if (docSummary != null) {
+ summary.setText(docSummary);
+ summary.setVisibility(View.VISIBLE);
+ } else {
+ summary.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
+ if (iconDrawable != null) {
+ icon1.setVisibility(View.VISIBLE);
+ icon1.setImageDrawable(iconDrawable);
+ } else {
+ icon1.setVisibility(View.GONE);
+ }
+
+ if (docLastModified == -1) {
+ date.setText(null);
+ } else {
+ date.setText(formatTime(mContext, docLastModified));
+ }
+
+ if (!state.showSize || Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) {
+ size.setVisibility(View.GONE);
+ } else {
+ size.setVisibility(View.VISIBLE);
+ size.setText(Formatter.formatFileSize(mContext, docSize));
+ }
+
+ setEnabledRecursive(itemView, enabled);
+
+ iconMime.setAlpha(iconAlpha);
+ iconThumb.setAlpha(iconAlpha);
+ icon1.setAlpha(iconAlpha);
+
+ if (DEBUG_ENABLE_DND) {
+ setupDragAndDropOnDocumentView(itemView, cursor);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mModel.getItemCount();
+ }
+
+ }
+
+ private static String formatTime(Context context, long when) {
+ // TODO: DateUtils should make this easier
+ Time then = new Time();
+ then.set(when);
+ Time now = new Time();
+ now.setToNow();
+
+ int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
+ | DateUtils.FORMAT_ABBREV_ALL;
+
+ if (then.year != now.year) {
+ flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
+ } else if (then.yearDay != now.yearDay) {
+ flags |= DateUtils.FORMAT_SHOW_DATE;
+ } else {
+ flags |= DateUtils.FORMAT_SHOW_TIME;
+ }
+
+ return DateUtils.formatDateTime(context, when, flags);
+ }
+
+ private String findCommonMimeType(List<String> mimeTypes) {
+ String[] commonType = mimeTypes.get(0).split("/");
+ if (commonType.length != 2) {
+ return "*/*";
+ }
+
+ for (int i = 1; i < mimeTypes.size(); i++) {
+ String[] type = mimeTypes.get(i).split("/");
+ if (type.length != 2) continue;
+
+ if (!commonType[1].equals(type[1])) {
+ commonType[1] = "*";
+ }
+
+ if (!commonType[0].equals(type[0])) {
+ commonType[0] = "*";
+ commonType[1] = "*";
+ break;
+ }
+ }
+
+ return commonType[0] + "/" + commonType[1];
+ }
+
+ private void setEnabledRecursive(View v, boolean enabled) {
+ if (v == null) return;
+ if (v.isEnabled() == enabled) return;
+ v.setEnabled(enabled);
+
+ if (v instanceof ViewGroup) {
+ final ViewGroup vg = (ViewGroup) v;
+ for (int i = vg.getChildCount() - 1; i >= 0; i--) {
+ setEnabledRecursive(vg.getChildAt(i), enabled);
+ }
+ }
+ }
+
+ private void copyFromClipboard() {
+ new AsyncTask<Void, Void, List<DocumentInfo>>() {
+
+ @Override
+ protected List<DocumentInfo> doInBackground(Void... params) {
+ return mClipper.getClippedDocuments();
+ }
+
+ @Override
+ protected void onPostExecute(List<DocumentInfo> docs) {
+ DocumentInfo destination =
+ ((BaseActivity) getActivity()).getCurrentDirectory();
+ copyDocuments(docs, destination);
+ }
+ }.execute();
+ }
+
+ private void copyFromClipData(final ClipData clipData, final DocumentInfo destination) {
+ checkNotNull(clipData);
+ new AsyncTask<Void, Void, List<DocumentInfo>>() {
+
+ @Override
+ protected List<DocumentInfo> doInBackground(Void... params) {
+ return mClipper.getDocumentsFromClipData(clipData);
+ }
+
+ @Override
+ protected void onPostExecute(List<DocumentInfo> docs) {
+ copyDocuments(docs, destination);
+ }
+ }.execute();
+ }
+
+ private void copyDocuments(final List<DocumentInfo> docs, final DocumentInfo destination) {
+ if (!canCopy(docs, destination)) {
+ Snackbars.makeSnackbar(
+ getActivity(),
+ R.string.clipboard_files_cannot_paste,
+ Snackbar.LENGTH_SHORT)
+ .show();
+ return;
+ }
+
+ if (docs.isEmpty()) {
+ return;
+ }
+
+ final DocumentStack curStack = getDisplayState().stack;
+ DocumentStack tmpStack = new DocumentStack();
+ if (destination != null) {
+ tmpStack.push(destination);
+ tmpStack.addAll(curStack);
+ } else {
+ tmpStack = curStack;
+ }
+
+ CopyService.start(getActivity(), docs, tmpStack, CopyService.TRANSFER_MODE_COPY);
+ }
+
+ private ClipData getClipDataFromDocuments(List<DocumentInfo> docs) {
+ Context context = getActivity();
+ final ContentResolver resolver = context.getContentResolver();
+ ClipData clipData = null;
+ for (DocumentInfo doc : docs) {
+ final Uri uri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId);
+ if (clipData == null) {
+ // TODO: figure out what this string should be.
+ // Currently it is not displayed anywhere in the UI, but this might change.
+ final String label = "";
+ clipData = ClipData.newUri(resolver, label, uri);
+ } else {
+ // TODO: update list of mime types in ClipData.
+ clipData.addItem(new ClipData.Item(uri));
+ }
+ }
+ return clipData;
+ }
+
+ public void copySelectedToClipboard() {
+ Selection sel = mSelectionManager.getSelection(new Selection());
+ copySelectionToClipboard(sel);
+ }
+
+ void copySelectionToClipboard(Selection items) {
+ new GetDocumentsTask() {
+ @Override
+ void onDocumentsReady(List<DocumentInfo> docs) {
+ mClipper.clipDocuments(docs);
+ Activity activity = getActivity();
+ Snackbars.makeSnackbar(activity,
+ activity.getResources().getQuantityString(
+ R.plurals.clipboard_files_clipped, docs.size(), docs.size()),
+ Snackbar.LENGTH_SHORT).show();
+ }
+ }.execute(items);
+ }
+
+ public void pasteFromClipboard() {
+ copyFromClipboard();
+ getActivity().invalidateOptionsMenu();
+ }
+
+ /**
+ * Returns true if the list of files can be copied to destination. Note that this
+ * is a policy check only. Currently the method does not attempt to verify
+ * available space or any other environmental aspects possibly resulting in
+ * failure to copy.
+ *
+ * @return true if the list of files can be copied to destination.
+ */
+ boolean canCopy(List<DocumentInfo> files, DocumentInfo dest) {
+ BaseActivity activity = (BaseActivity) getActivity();
+
+ final RootInfo root = activity.getCurrentRoot();
+
+ // Can't copy folders to Downloads.
+ if (root.isDownloads()) {
+ for (DocumentInfo docs : files) {
+ if (docs.isDirectory()) {
+ return false;
+ }
+ }
+ }
+
+ return dest != null && dest.isDirectory() && dest.isCreateSupported();
+ }
+
+ public void selectAllFiles() {
+ boolean changed = mSelectionManager.setItemsSelected(0, mModel.getItemCount(), true);
+ if (changed) {
+ updateDisplayState();
+ }
+ }
+
+ private void setupDragAndDropOnDirectoryView(View view) {
+ // Listen for drops on non-directory items and empty space.
+ view.setOnDragListener(mOnDragListener);
+ }
+
+ private void setupDragAndDropOnDocumentView(View view, Cursor cursor) {
+ final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+ if (Document.MIME_TYPE_DIR.equals(docMimeType)) {
+ // Make a directory item a drop target. Drop on non-directories and empty space
+ // is handled at the list/grid view level.
+ view.setOnDragListener(mOnDragListener);
+ }
+
+ // Temporary: attaching the listener to the title only.
+ // Attaching to the entire item conflicts with the item long click handler responsible
+ // for item selection.
+ final View title = view.findViewById(android.R.id.title);
+ title.setOnLongClickListener(mLongClickListener);
+ }
+
+ private View.OnDragListener mOnDragListener = new View.OnDragListener() {
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ // TODO: Check if the event contains droppable data.
+ return true;
+
+ // TODO: Highlight potential drop target directory?
+ // TODO: Expand drop target directory on hover?
+ case DragEvent.ACTION_DRAG_ENTERED:
+ case DragEvent.ACTION_DRAG_LOCATION:
+ case DragEvent.ACTION_DRAG_EXITED:
+ case DragEvent.ACTION_DRAG_ENDED:
+ return true;
+
+ case DragEvent.ACTION_DROP:
+ int dstPosition = mRecView.getChildAdapterPosition(getContainingItemView(v));
+ DocumentInfo dstDir = null;
+ if (dstPosition != android.widget.AdapterView.INVALID_POSITION) {
+ Cursor dstCursor = mModel.getItem(dstPosition);
+ checkNotNull(dstCursor, "Cursor cannot be null.");
+ dstDir = DocumentInfo.fromDirectoryCursor(dstCursor);
+ // TODO: Do not drop into the directory where the documents came from.
+ }
+ copyFromClipData(event.getClipData(), dstDir);
+ return true;
+ }
+ return false;
+ }
+ };
+
+ private View getContainingItemView(View view) {
+ while (true) {
+ if (view.getLayoutParams() instanceof RecyclerView.LayoutParams) {
+ return view;
+ }
+ ViewParent parent = view.getParent();
+ if (parent == null || !(parent instanceof View)) {
+ return null;
+ }
+ view = (View) parent;
+ }
+ }
+
+ private View.OnLongClickListener mLongClickListener = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ final List<DocumentInfo> docs = getDraggableDocuments(v);
+ if (docs.isEmpty()) {
+ return false;
+ }
+ v.startDrag(
+ getClipDataFromDocuments(docs),
+ new DrawableShadowBuilder(getDragShadowIcon(docs)),
+ null,
+ View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ |
+ View.DRAG_FLAG_GLOBAL_URI_WRITE
+ );
+ return true;
+ }
+ };
+
+ private List<DocumentInfo> getDraggableDocuments(View currentItemView) {
+ int position = mRecView.getChildAdapterPosition(getContainingItemView(currentItemView));
+ if (position == android.widget.AdapterView.INVALID_POSITION) {
+ return Collections.EMPTY_LIST;
+ }
+
+ final List<DocumentInfo> selectedDocs =
+ mModel.getDocuments(mSelectionManager.getSelection());
+ if (!selectedDocs.isEmpty()) {
+ if (!isSelected(position)) {
+ // There is a selection that does not include the current item, drag nothing.
+ return Collections.EMPTY_LIST;
+ }
+ return selectedDocs;
+ }
+
+ final Cursor cursor = mModel.getItem(position);
+ checkNotNull(cursor, "Cursor cannot be null.");
+ final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+
+ return Lists.newArrayList(doc);
+ }
+
+ private Drawable getDragShadowIcon(List<DocumentInfo> docs) {
+ if (docs.size() == 1) {
+ final DocumentInfo doc = docs.get(0);
+ return getDocumentIcon(getActivity(), doc.authority, doc.documentId,
+ doc.mimeType, doc.icon, getDisplayState());
+ }
+ return getActivity().getDrawable(R.drawable.ic_doc_generic);
+ }
+
+ public static Drawable getDocumentIcon(Context context, String docAuthority, String docId,
+ String docMimeType, int docIcon, State state) {
+ if (docIcon != 0) {
+ return IconUtils.loadPackageIcon(context, docAuthority, docIcon);
+ } else {
+ return IconUtils.loadMimeIcon(context, docMimeType, docAuthority, docId,
+ state.derivedMode);
+ }
+ }
+
+ private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap>
+ implements Preemptable {
+ private final Uri mUri;
+ private final ImageView mIconMime;
+ private final ImageView mIconThumb;
+ private final Point mThumbSize;
+ private final float mTargetAlpha;
+ private final CancellationSignal mSignal;
+
+ public ThumbnailAsyncTask(Uri uri, ImageView iconMime, ImageView iconThumb, Point thumbSize,
+ float targetAlpha) {
+ mUri = uri;
+ mIconMime = iconMime;
+ mIconThumb = iconThumb;
+ mThumbSize = thumbSize;
+ mTargetAlpha = targetAlpha;
+ mSignal = new CancellationSignal();
+ }
+
+ @Override
+ public void preempt() {
+ cancel(false);
+ mSignal.cancel();
+ }
+
+ @Override
+ protected Bitmap doInBackground(Uri... params) {
+ if (isCancelled()) return null;
+
+ final Context context = mIconThumb.getContext();
+ final ContentResolver resolver = context.getContentResolver();
+
+ ContentProviderClient client = null;
+ Bitmap result = null;
+ try {
+ client = DocumentsApplication.acquireUnstableProviderOrThrow(
+ resolver, mUri.getAuthority());
+ result = DocumentsContract.getDocumentThumbnail(client, mUri, mThumbSize, mSignal);
+ if (result != null) {
+ final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache(
+ context, mThumbSize);
+ thumbs.put(mUri, result);
+ }
+ } catch (Exception e) {
+ if (!(e instanceof OperationCanceledException)) {
+ Log.w(TAG, "Failed to load thumbnail for " + mUri + ": " + e);
+ }
+ } finally {
+ ContentProviderClient.releaseQuietly(client);
+ }
+ return result;
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap result) {
+ if (mIconThumb.getTag() == this && result != null) {
+ mIconThumb.setTag(null);
+ mIconThumb.setImageBitmap(result);
+
+ mIconMime.setAlpha(mTargetAlpha);
+ mIconMime.animate().alpha(0f).start();
+ mIconThumb.setAlpha(0f);
+ mIconThumb.animate().alpha(mTargetAlpha).start();
+ }
+ }
+ }
+
+ private class DrawableShadowBuilder extends View.DragShadowBuilder {
+
+ private final Drawable mShadow;
+
+ private final int mShadowDimension;
+
+ public DrawableShadowBuilder(Drawable shadow) {
+ mShadow = shadow;
+ mShadowDimension = getResources().getDimensionPixelSize(
+ R.dimen.drag_shadow_size);
+ mShadow.setBounds(0, 0, mShadowDimension, mShadowDimension);
+ }
+
+ @Override
+ public void onProvideShadowMetrics(
+ Point shadowSize, Point shadowTouchPoint) {
+ shadowSize.set(mShadowDimension, mShadowDimension);
+ shadowTouchPoint.set(mShadowDimension / 2, mShadowDimension / 2);
+ }
+
+ @Override
+ public void onDrawShadow(Canvas canvas) {
+ mShadow.draw(canvas);
+ }
+ }
+
+ /**
+ * Abstract task providing support for loading documents *off*
+ * the main thread. And if it isn't obvious, creating a list
+ * of documents (especially large lists) can be pretty expensive.
+ */
+ private abstract class GetDocumentsTask
+ extends AsyncTask<Selection, Void, List<DocumentInfo>> {
+ @Override
+ protected final List<DocumentInfo> doInBackground(Selection... selected) {
+ return mModel.getDocuments(selected[0]);
+ }
+
+ @Override
+ protected final void onPostExecute(List<DocumentInfo> docs) {
+ onDocumentsReady(docs);
+ }
+
+ abstract void onDocumentsReady(List<DocumentInfo> docs);
+ }
+
+ boolean isSelected(int position) {
+ return mSelectionManager.getSelection().contains(position);
+ }
+
+ /**
+ * The data model for the current loaded directory.
+ */
+ @VisibleForTesting
+ public static final class Model implements DocumentContext {
+ private RecyclerView.Adapter<?> mViewAdapter;
+ private Context mContext;
+ private int mCursorCount;
+ private boolean mIsLoading;
+ @GuardedBy("mPendingDelete")
+ private Boolean mPendingDelete = false;
+ @GuardedBy("mPendingDelete")
+ private SparseBooleanArray mMarkedForDeletion = new SparseBooleanArray();
+ private UpdateListener mUpdateListener;
+ @Nullable private Cursor mCursor;
+ @Nullable private String info;
+ @Nullable private String error;
+
+ Model(Context context, RecyclerView.Adapter<?> viewAdapter) {
+ mContext = context;
+ mViewAdapter = viewAdapter;
+ }
+
+ void update(DirectoryResult result) {
+ if (DEBUG) Log.i(TAG, "Updating model with new result set.");
+
+ if (result == null) {
+ mCursor = null;
+ mCursorCount = 0;
+ info = null;
+ error = null;
+ mIsLoading = false;
+ mUpdateListener.onModelUpdate(this);
+ return;
+ }
+
+ if (result.exception != null) {
+ Log.e(TAG, "Error while loading directory contents", result.exception);
+ mUpdateListener.onModelUpdateFailed(result.exception);
+ return;
+ }
+
+ mCursor = result.cursor;
+ mCursorCount = mCursor.getCount();
+
+ final Bundle extras = mCursor.getExtras();
+ if (extras != null) {
+ info = extras.getString(DocumentsContract.EXTRA_INFO);
+ error = extras.getString(DocumentsContract.EXTRA_ERROR);
+ mIsLoading = extras.getBoolean(DocumentsContract.EXTRA_LOADING, false);
+ }
+
+ mUpdateListener.onModelUpdate(this);
+ }
+
+ int getItemCount() {
+ synchronized(mPendingDelete) {
+ return mCursorCount - mMarkedForDeletion.size();
+ }
+ }
+
+ Cursor getItem(int position) {
+ synchronized(mPendingDelete) {
+ // Items marked for deletion are masked out of the UI. To do this, for every marked
+ // item whose position is less than the requested item position, advance the requested
+ // position by 1.
+ final int originalPos = position;
+ final int size = mMarkedForDeletion.size();
+ for (int i = 0; i < size; ++i) {
+ // It'd be more concise, but less efficient, to iterate over positions while calling
+ // mMarkedForDeletion.get. Instead, iterate over deleted entries.
+ if (mMarkedForDeletion.keyAt(i) <= position && mMarkedForDeletion.valueAt(i)) {
+ ++position;
+ }
+ }
+
+ if (DEBUG && position != originalPos) {
+ Log.d(TAG, "Item position adjusted for deletion. Original: " + originalPos
+ + " Adjusted: " + position);
+ }
+
+ if (position >= mCursorCount) {
+ throw new IndexOutOfBoundsException("Attempt to retrieve " + position + " of " +
+ mCursorCount + " items");
+ }
+
+ mCursor.moveToPosition(position);
+ return mCursor;
+ }
+ }
+
+ private boolean isEmpty() {
+ return mCursorCount == 0;
+ }
+
+ private boolean isLoading() {
+ return mIsLoading;
+ }
+
+ List<DocumentInfo> getDocuments(Selection items) {
+ final int size = (items != null) ? items.size() : 0;
+
+ final List<DocumentInfo> docs = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ final Cursor cursor = getItem(items.get(i));
+ checkNotNull(cursor, "Cursor cannot be null.");
+ final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+ docs.add(doc);
+ }
+ return docs;
+ }
+
+ @Override
+ public Cursor getCursor() {
+ if (Looper.myLooper() != Looper.getMainLooper()) {
+ throw new IllegalStateException("Can't call getCursor from non-main thread.");
+ }
+ return mCursor;
+ }
+
+ List<DocumentInfo> getDocumentsMarkedForDeletion() {
+ synchronized (mPendingDelete) {
+ final int size = mMarkedForDeletion.size();
+ List<DocumentInfo> docs = new ArrayList<>(size);
+
+ for (int i = 0; i < size; ++i) {
+ final int position = mMarkedForDeletion.keyAt(i);
+ checkState(position < mCursorCount);
+ mCursor.moveToPosition(position);
+ final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(mCursor);
+ docs.add(doc);
+ }
+ return docs;
+ }
+ }
+
+ /**
+ * Marks the given files for deletion. This will remove them from the UI. Clients must then
+ * call either {@link #undoDeletion()} or {@link #finalizeDeletion()} to cancel or confirm
+ * the deletion, respectively. Only one deletion operation is allowed at a time.
+ *
+ * @param selected A selection representing the files to delete.
+ */
+ void markForDeletion(Selection selected) {
+ synchronized (mPendingDelete) {
+ mPendingDelete = true;
+ // Only one deletion operation at a time.
+ checkState(mMarkedForDeletion.size() == 0);
+ // There should never be more to delete than what exists.
+ checkState(mCursorCount >= selected.size());
+
+ int[] positions = selected.getAll();
+ Arrays.sort(positions);
+
+ // Walk backwards through the set, since we're removing positions.
+ // Otherwise, positions would change after the first modification.
+ for (int p = positions.length - 1; p >= 0; p--) {
+ mMarkedForDeletion.append(positions[p], true);
+ mViewAdapter.notifyItemRemoved(positions[p]);
+ if (DEBUG) Log.d(TAG, "Scheduled " + positions[p] + " for delete.");
+ }
+ }
+ }
+
+ /**
+ * Cancels an ongoing deletion operation. All files currently marked for deletion will be
+ * unmarked, and restored in the UI. See {@link #markForDeletion(Selection)}.
+ */
+ void undoDeletion() {
+ synchronized (mPendingDelete) {
+ // Iterate over deleted items, temporarily marking them false in the deletion list, and
+ // re-adding them to the UI.
+ final int size = mMarkedForDeletion.size();
+ for (int i = 0; i < size; ++i) {
+ final int position = mMarkedForDeletion.keyAt(i);
+ mMarkedForDeletion.put(position, false);
+ mViewAdapter.notifyItemInserted(position);
+ }
+ resetDeleteData();
+ }
+ }
+
+ private void resetDeleteData() {
+ synchronized (mPendingDelete) {
+ mPendingDelete = false;
+ mMarkedForDeletion.clear();
+ }
+ }
+
+ /**
+ * Finalizes an ongoing deletion operation. All files currently marked for deletion will be
+ * deleted. See {@link #markForDeletion(Selection)}.
+ *
+ * @param view The view which will be used to interact with the user (e.g. surfacing
+ * snackbars) for errors, info, etc.
+ */
+ void finalizeDeletion(DeletionListener listener) {
+ synchronized (mPendingDelete) {
+ if (mPendingDelete) {
+ // Necessary to avoid b/25072545. Even when that's resolved, this
+ // is a nice safe thing to day.
+ mPendingDelete = false;
+ final ContentResolver resolver = mContext.getContentResolver();
+ DeleteFilesTask task = new DeleteFilesTask(resolver, listener);
+ task.execute();
+ }
+ }
+ }
+
+ /**
+ * A Task which collects the DocumentInfo for documents that have been marked for deletion,
+ * and actually deletes them.
+ */
+ private class DeleteFilesTask extends AsyncTask<Void, Void, List<DocumentInfo>> {
+ private ContentResolver mResolver;
+ private DeletionListener mListener;
+
+ /**
+ * @param resolver A ContentResolver for performing the actual file deletions.
+ * @param errorCallback A Runnable that is executed in the event that one or more errors
+ * occured while copying files. Execution will occur on the UI thread.
+ */
+ public DeleteFilesTask(ContentResolver resolver, DeletionListener listener) {
+ mResolver = resolver;
+ mListener = listener;
+ }
+
+ @Override
+ protected List<DocumentInfo> doInBackground(Void... params) {
+ return getDocumentsMarkedForDeletion();
+ }
+
+ @Override
+ protected void onPostExecute(List<DocumentInfo> docs) {
+ boolean hadTrouble = false;
+ for (DocumentInfo doc : docs) {
+ if (!doc.isDeleteSupported()) {
+ Log.w(TAG, doc + " could not be deleted. Skipping...");
+ hadTrouble = true;
+ continue;
+ }
+
+ ContentProviderClient client = null;
+ try {
+ if (DEBUG) Log.d(TAG, "Deleting: " + doc.displayName);
+ client = DocumentsApplication.acquireUnstableProviderOrThrow(
+ mResolver, doc.derivedUri.getAuthority());
+ DocumentsContract.deleteDocument(client, doc.derivedUri);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to delete " + doc);
+ hadTrouble = true;
+ } finally {
+ ContentProviderClient.releaseQuietly(client);
+ }
+ }
+
+ if (hadTrouble) {
+ // TODO show which files failed? b/23720103
+ mListener.onError();
+ if (DEBUG) Log.d(TAG, "Deletion task completed. Some deletions failed.");
+ } else {
+ if (DEBUG) Log.d(TAG, "Deletion task completed successfully.");
+ }
+ resetDeleteData();
+
+ mListener.onCompletion();
+ }
+ }
+
+ static class DeletionListener {
+ /**
+ * Called when deletion has completed (regardless of whether an error occurred).
+ */
+ void onCompletion() {}
+
+ /**
+ * Called at the end of a deletion operation that produced one or more errors.
+ */
+ void onError() {}
+ }
+
+ void addUpdateListener(UpdateListener listener) {
+ checkState(mUpdateListener == null);
+ mUpdateListener = listener;
+ }
+
+ static class UpdateListener {
+ /**
+ * Called when a successful update has occurred.
+ */
+ void onModelUpdate(Model model) {}
+
+ /**
+ * Called when an update has been attempted but failed.
+ */
+ void onModelUpdateFailed(Exception e) {}
+ }
+ }
+
+ private class ItemClickListener implements ClickListener {
+ @Override
+ public void onClick(DocumentHolder doc) {
+ final int position = doc.getAdapterPosition();
+ if (mSelectionManager.hasSelection()) {
+ mSelectionManager.toggleSelection(position);
+ } else {
+ handleViewItem(position);
+ }
+ }
+ }
+
+ private class ModelUpdateListener extends Model.UpdateListener {
+ @Override
+ public void onModelUpdate(Model model) {
+ if (model.info != null || model.error != null) {
+ mMessageBar.setInfo(model.info);
+ mMessageBar.setError(model.error);
+ mMessageBar.show();
+ }
+
+ mProgressBar.setVisibility(model.isLoading() ? View.VISIBLE : View.GONE);
+
+ if (model.isEmpty()) {
+ showEmptyView();
+ } else {
+ showRecyclerView();
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onModelUpdateFailed(Exception e) {
+ showErrorView();
+ }
+ }
+}
diff --git a/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java b/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java
new file mode 100644
index 0000000..1135c21
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/DirectoryItemAnimator.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.animation.Animator;
+import android.animation.ArgbEvaluator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.support.v4.util.ArrayMap;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.RecyclerView;
+import android.util.TypedValue;
+
+import com.android.documentsui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Performs change animations on Items in DirectoryFragment's RecyclerView. This class overrides
+ * the way selection animations are normally performed - instead of cross fading the old Item with a
+ * new Item, this class manually animates a background color change. This enables selected Items to
+ * correctly maintain focus.
+ */
+class DirectoryItemAnimator extends DefaultItemAnimator {
+ private final List<ColorAnimation> mPendingAnimations = new ArrayList<>();
+ private final Map<RecyclerView.ViewHolder, ColorAnimation> mRunningAnimations =
+ new ArrayMap<>();
+ private final Integer mDefaultColor;
+ private final Integer mSelectedColor;
+
+ public DirectoryItemAnimator(Context context) {
+ mDefaultColor = context.getResources().getColor(R.color.item_doc_background);
+ mSelectedColor = context.getResources().getColor(R.color.item_doc_background_selected);
+ }
+
+ @Override
+ public void runPendingAnimations() {
+ super.runPendingAnimations();
+ for (ColorAnimation anim: mPendingAnimations) {
+ anim.start();
+ mRunningAnimations.put(anim.viewHolder, anim);
+ }
+ mPendingAnimations.clear();
+ }
+
+ @Override
+ public void endAnimation(RecyclerView.ViewHolder vh) {
+ super.endAnimation(vh);
+
+ for (int i = mPendingAnimations.size() - 1; i >= 0; --i) {
+ ColorAnimation anim = mPendingAnimations.get(i);
+ if (anim.viewHolder == vh) {
+ mPendingAnimations.remove(i);
+ anim.end();
+ }
+ }
+
+ ColorAnimation anim = mRunningAnimations.get(vh);
+ if (anim != null) {
+ anim.cancel();
+ }
+ }
+
+ @Override
+ public ItemHolderInfo recordPreLayoutInformation(
+ RecyclerView.State state,
+ RecyclerView.ViewHolder viewHolder,
+ @AdapterChanges int changeFlags,
+ List<Object> payloads) {
+ ItemInfo info = (ItemInfo) super.recordPreLayoutInformation(state,
+ viewHolder, changeFlags, payloads);
+ info.isActivated = viewHolder.itemView.isActivated();
+ return info;
+ }
+
+
+ @Override
+ public ItemHolderInfo recordPostLayoutInformation(
+ RecyclerView.State state, RecyclerView.ViewHolder viewHolder) {
+ ItemInfo info = (ItemInfo) super.recordPostLayoutInformation(state,
+ viewHolder);
+ info.isActivated = viewHolder.itemView.isActivated();
+ return info;
+ }
+
+ @Override
+ public boolean animateChange(final RecyclerView.ViewHolder oldHolder,
+ RecyclerView.ViewHolder newHolder, ItemHolderInfo preInfo,
+ ItemHolderInfo postInfo) {
+ if (oldHolder != newHolder) {
+ return super.animateChange(oldHolder, newHolder, preInfo, postInfo);
+ }
+
+ ItemInfo pre = (ItemInfo)preInfo;
+ ItemInfo post = (ItemInfo)postInfo;
+
+ if (pre.isActivated == post.isActivated) {
+ dispatchAnimationFinished(oldHolder);
+ return false;
+ } else {
+ Integer startColor = pre.isActivated ? mSelectedColor : mDefaultColor;
+ Integer endColor = post.isActivated ? mSelectedColor : mDefaultColor;
+ oldHolder.itemView.setBackgroundColor(startColor);
+ mPendingAnimations.add(new ColorAnimation(oldHolder, startColor, endColor));
+ }
+ return true;
+ }
+
+ @Override
+ public ItemHolderInfo obtainHolderInfo() {
+ return new ItemInfo();
+ }
+
+ @Override
+ public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder vh) {
+ return true;
+ }
+
+ class ItemInfo extends DefaultItemAnimator.ItemHolderInfo {
+ boolean isActivated;
+ };
+
+ /**
+ * Animates changes in background color.
+ */
+ class ColorAnimation
+ implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
+ ValueAnimator mValueAnimator;
+ final RecyclerView.ViewHolder viewHolder;
+ int mEndColor;
+
+ public ColorAnimation(RecyclerView.ViewHolder vh, int startColor, int endColor)
+ {
+ viewHolder = vh;
+ mValueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
+ mValueAnimator.addUpdateListener(this);
+ mValueAnimator.addListener(this);
+
+ mEndColor = endColor;
+ }
+
+ public void start() {
+ mValueAnimator.start();
+ }
+
+ public void cancel() {
+ mValueAnimator.cancel();
+ }
+
+ public void end() {
+ mValueAnimator.end();
+ }
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animator) {
+ viewHolder.itemView.setBackgroundColor((Integer)animator.getAnimatedValue());
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ viewHolder.itemView.setBackgroundColor(mEndColor);
+ mRunningAnimations.remove(viewHolder);
+ dispatchAnimationFinished(viewHolder);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ dispatchAnimationStarted(viewHolder);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {}
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {}
+ };
+};
diff --git a/src/com/android/documentsui/dirlist/FragmentTuner.java b/src/com/android/documentsui/dirlist/FragmentTuner.java
new file mode 100644
index 0000000..ef6d2c9
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.State.ACTION_BROWSE;
+import static com.android.documentsui.State.ACTION_CREATE;
+import static com.android.documentsui.State.ACTION_GET_CONTENT;
+import static com.android.documentsui.State.ACTION_MANAGE;
+import static com.android.documentsui.State.ACTION_OPEN;
+import static com.android.documentsui.State.ACTION_OPEN_TREE;
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import com.android.documentsui.Menus;
+import com.android.documentsui.MimePredicate;
+import com.android.documentsui.R;
+import com.android.documentsui.State;
+
+import android.os.SystemProperties;
+import android.provider.DocumentsContract.Document;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Providers support for specializing the DirectoryFragment to the "host" Activity.
+ * Feel free to expand the role of this class to handle other specializations.
+ */
+public abstract class FragmentTuner {
+
+ final State mState;
+
+ public FragmentTuner(State state) {
+ mState = state;
+ }
+
+ public static FragmentTuner pick(State state) {
+ switch (state.action) {
+ case ACTION_BROWSE:
+ return new FilesTuner(state);
+ case ACTION_MANAGE:
+ return new DownloadsTuner(state);
+ default:
+ return new DocumentsTuner(state);
+ }
+ }
+
+
+ public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete);
+
+ // Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
+ // A folder is enabled such that it may be double clicked, even in settings
+ // when the folder itself cannot be selected. This may also be true of container types.
+ public boolean canSelectType(String docMimeType, int docFlags) {
+ return true;
+ }
+
+ public boolean isDocumentEnabled(String docMimeType, int docFlags) {
+ if (isDirectory(docMimeType)) {
+ return true;
+ }
+
+ return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+ }
+
+ /**
+ * Provides support for Platform specific specializations of DirectoryFragment.
+ */
+ private static final class DocumentsTuner extends FragmentTuner {
+
+ public DocumentsTuner(State state) {
+ super(state);
+ }
+
+ @Override
+ public boolean canSelectType(String docMimeType, int docFlags) {
+ if (!isDocumentEnabled(docMimeType, docFlags)) {
+ return false;
+ }
+
+ if (isDirectory(docMimeType)) {
+ return false;
+ }
+
+ if (mState.action == ACTION_OPEN_TREE) {
+ // In this case nothing *ever* is selectable...the expected user behavior is
+ // they navigate *into* a folder, then click a confirmation button indicating
+ // that the current directory is the directory they are picking.
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isDocumentEnabled(String docMimeType, int docFlags) {
+ // Directories are always enabled.
+ if (isDirectory(docMimeType)) {
+ return true;
+ }
+
+ switch (mState.action) {
+ case ACTION_CREATE:
+ // Read-only files are disabled when creating.
+ if ((docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
+ return false;
+ }
+ case ACTION_OPEN:
+ case ACTION_GET_CONTENT:
+ final boolean isVirtual = (docFlags & Document.FLAG_VIRTUAL_DOCUMENT) != 0;
+ if (isVirtual && mState.openableOnly) {
+ return false;
+ }
+ }
+
+ return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
+ }
+
+ @Override
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+
+ boolean copyEnabled = dirType != DirectoryFragment.TYPE_RECENT_OPEN;
+ boolean moveEnabled =
+ SystemProperties.getBoolean("debug.documentsui.enable_move", false);
+ menu.findItem(R.id.menu_copy_to_clipboard).setEnabled(copyEnabled);
+
+ final MenuItem open = menu.findItem(R.id.menu_open);
+ final MenuItem share = menu.findItem(R.id.menu_share);
+ final MenuItem delete = menu.findItem(R.id.menu_delete);
+ final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
+ final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+
+ open.setVisible(true);
+ share.setVisible(false);
+ delete.setVisible(false);
+ copyTo.setVisible(copyEnabled);
+ copyTo.setEnabled(copyEnabled);
+ moveTo.setVisible(moveEnabled);
+ moveTo.setEnabled(moveEnabled);
+ }
+ }
+
+ /**
+ * Provides support for Platform specific specializations of DirectoryFragment.
+ */
+ private static final class DownloadsTuner extends FragmentTuner {
+
+ public DownloadsTuner(State state) {
+ super(state);
+ }
+
+ @Override
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+ checkArgument(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
+
+ boolean moveEnabled =
+ SystemProperties.getBoolean("debug.documentsui.enable_move", false);
+ menu.findItem(R.id.menu_copy_to_clipboard).setEnabled(true);
+
+ final MenuItem open = menu.findItem(R.id.menu_open);
+ final MenuItem share = menu.findItem(R.id.menu_share);
+ final MenuItem delete = menu.findItem(R.id.menu_delete);
+ final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
+ final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+
+ open.setVisible(false);
+ delete.setVisible(canDelete);
+ copyTo.setVisible(true);
+ copyTo.setEnabled(true);
+ moveTo.setVisible(moveEnabled);
+ moveTo.setEnabled(moveEnabled);
+ }
+ }
+
+ /**
+ * Provides support for Files activity specific specializations of DirectoryFragment.
+ */
+ private static final class FilesTuner extends FragmentTuner {
+
+ public FilesTuner(State state) {
+ super(state);
+ }
+
+ @Override
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+
+ MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
+ MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
+ copy.setEnabled(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
+
+ menu.findItem(R.id.menu_share).setVisible(true);
+ menu.findItem(R.id.menu_delete).setVisible(canDelete);
+
+ menu.findItem(R.id.menu_open).setVisible(false);
+ menu.findItem(R.id.menu_copy_to).setVisible(true);
+ menu.findItem(R.id.menu_move_to).setVisible(true);
+
+ Menus.disableHiddenItems(menu, copy, paste);
+ }
+ }
+
+ private static boolean isDirectory(String mimeType) {
+ return Document.MIME_TYPE_DIR.equals(mimeType);
+ }
+}
diff --git a/src/com/android/documentsui/dirlist/MultiSelectManager.java b/src/com/android/documentsui/dirlist/MultiSelectManager.java
new file mode 100644
index 0000000..65e1a28
--- /dev/null
+++ b/src/com/android/documentsui/dirlist/MultiSelectManager.java
@@ -0,0 +1,2032 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.Shared.DEBUG;
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.support.v7.widget.RecyclerView.AdapterDataObserver;
+import android.support.v7.widget.RecyclerView.LayoutManager;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.documentsui.Events.InputEvent;
+import com.android.documentsui.Events.MotionInputEvent;
+import com.android.documentsui.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * MultiSelectManager provides support traditional multi-item selection support to RecyclerView.
+ * Additionally it can be configured to restrict selection to a single element, @see
+ * #setSelectMode.
+ */
+public final class MultiSelectManager implements View.OnKeyListener {
+
+ /** Selection mode for multiple select. **/
+ public static final int MODE_MULTIPLE = 0;
+
+ /** Selection mode for multiple select. **/
+ public static final int MODE_SINGLE = 1;
+
+ private static final String TAG = "MultiSelectManager";
+
+ private final Selection mSelection = new Selection();
+
+ // Only created when selection is cleared.
+ private Selection mIntermediateSelection;
+
+ private Range mRanger;
+ private SelectionEnvironment mEnvironment;
+
+ private final List<MultiSelectManager.Callback> mCallbacks = new ArrayList<>(1);
+
+ private Adapter<?> mAdapter;
+ private boolean mSingleSelect;
+
+ // Payloads for notifyItemChange to distinguish between selection and other events.
+ public static final String SELECTION_CHANGED_MARKER = "Selection-Changed";
+
+ @Nullable private BandController mBandManager;
+
+ /**
+ * @param recyclerView
+ * @param mode Selection mode
+ */
+ public MultiSelectManager(final RecyclerView recyclerView, int mode) {
+ this(recyclerView.getAdapter(), new RuntimeSelectionEnvironment(recyclerView), mode);
+
+ if (mode == MODE_MULTIPLE) {
+ mBandManager = new BandController();
+ }
+
+ GestureDetector.SimpleOnGestureListener listener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ return MultiSelectManager.this.onSingleTapUp(
+ new MotionInputEvent(e, recyclerView));
+ }
+ @Override
+ public void onLongPress(MotionEvent e) {
+ MultiSelectManager.this.onLongPress(
+ new MotionInputEvent(e, recyclerView));
+ }
+ };
+
+ final GestureDetector detector = new GestureDetector(recyclerView.getContext(), listener);
+ detector.setOnDoubleTapListener(listener);
+
+ recyclerView.addOnItemTouchListener(
+ new RecyclerView.OnItemTouchListener() {
+ @Override
+ public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+ detector.onTouchEvent(e);
+
+ if (mBandManager != null) {
+ return mBandManager.handleEvent(new MotionInputEvent(e, recyclerView));
+ }
+ return false;
+ }
+
+ @Override
+ public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+ mBandManager.processInputEvent(
+ new MotionInputEvent(e, recyclerView));
+ }
+ @Override
+ public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
+ });
+ }
+
+ /**
+ * Constructs a new instance with {@code adapter} and {@code helper}.
+ * @param runtimeSelectionEnvironment
+ * @hide
+ */
+ @VisibleForTesting
+ MultiSelectManager(Adapter<?> adapter, SelectionEnvironment environment, int mode) {
+ mAdapter = checkNotNull(adapter, "'adapter' cannot be null.");
+ mEnvironment = checkNotNull(environment, "'environment' cannot be null.");
+ mSingleSelect = mode == MODE_SINGLE;
+
+ mAdapter.registerAdapterDataObserver(
+ new AdapterDataObserver() {
+
+ @Override
+ public void onChanged() {
+ mSelection.clear();
+ }
+
+ @Override
+ public void onItemRangeChanged(
+ int positionStart, int itemCount, Object payload) {
+ // No change in position. Ignoring.
+ }
+
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ mSelection.expand(positionStart, itemCount);
+ }
+
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ mSelection.collapse(positionStart, itemCount);
+ }
+
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ throw new UnsupportedOperationException();
+ }
+ });
+ }
+
+ /**
+ * Adds {@code callback} such that it will be notified when {@code MultiSelectManager}
+ * events occur.
+ *
+ * @param callback
+ */
+ public void addCallback(MultiSelectManager.Callback callback) {
+ mCallbacks.add(callback);
+ }
+
+ public boolean hasSelection() {
+ return !mSelection.isEmpty();
+ }
+
+ /**
+ * Returns a Selection object that provides a live view
+ * on the current selection.
+ *
+ * @see #getSelection(Selection) on how to get a snapshot
+ * of the selection that will not reflect future changes
+ * to selection.
+ *
+ * @return The current selection.
+ */
+ public Selection getSelection() {
+ return mSelection;
+ }
+
+ /**
+ * Updates {@code dest} to reflect the current selection.
+ * @param dest
+ *
+ * @return The Selection instance passed in, for convenience.
+ */
+ public Selection getSelection(Selection dest) {
+ dest.copyFrom(mSelection);
+ return dest;
+ }
+
+ /**
+ * Causes item at {@code position} in adapter to be selected.
+ *
+ * @param position Adapter position
+ * @param selected
+ * @return True if the selection state of the item changed.
+ */
+ @VisibleForTesting
+ public boolean setItemSelected(int position, boolean selected) {
+ if (mSingleSelect && hasSelection()) {
+ clearSelectionQuietly();
+ }
+ return setItemsSelected(position, 1, selected);
+ }
+
+ /**
+ * Sets the selected state of the specified items. Note that the callback will NOT
+ * be consulted to see if an item can be selected.
+ *
+ * @return True if the selection state of any of the items changed.
+ */
+ public boolean setItemsSelected(int position, int length, boolean selected) {
+ boolean changed = false;
+ for (int i = position; i < position + length; i++) {
+ boolean itemChanged = selected ? mSelection.add(i) : mSelection.remove(i);
+ if (itemChanged) {
+ notifyItemStateChanged(i, selected);
+ }
+ changed |= itemChanged;
+ }
+
+ notifySelectionChanged();
+ return changed;
+ }
+
+ /**
+ * Clears the selection and notifies (even if nothing changes).
+ */
+ public void clearSelection() {
+ clearSelectionQuietly();
+ notifySelectionChanged();
+ }
+
+ public void handleLayoutChanged() {
+ if (mBandManager != null) {
+ mBandManager.handleLayoutChanged();
+ }
+ }
+
+ /**
+ * Clears the selection, without notifying anyone.
+ */
+ private void clearSelectionQuietly() {
+ mRanger = null;
+
+ if (!hasSelection()) {
+ return;
+ }
+ if (mIntermediateSelection == null) {
+ mIntermediateSelection = new Selection();
+ }
+ getSelection(mIntermediateSelection);
+ mSelection.clear();
+
+ for (int i = 0; i < mIntermediateSelection.size(); i++) {
+ int position = mIntermediateSelection.get(i);
+ notifyItemStateChanged(position, false);
+ }
+ }
+
+ @VisibleForTesting
+ void onLongPress(InputEvent input) {
+ if (DEBUG) Log.d(TAG, "Handling long press event.");
+
+ if (!input.isOverItem()) {
+ if (DEBUG) Log.i(TAG, "Cannot handle tap. No adapter position available.");
+ }
+
+ handleAdapterEvent(input);
+ }
+
+ @VisibleForTesting
+ boolean onSingleTapUp(InputEvent input) {
+ if (DEBUG) Log.d(TAG, "Processing tap event.");
+ if (!hasSelection()) {
+ // if this is a mouse click on an item, start selection mode.
+ // TODO: && input.isPrimaryButtonPressed(), but it is returning false.
+ if (input.isOverItem() && input.isMouseEvent()) {
+ toggleSelection(input.getItemPosition());
+ }
+ return false;
+ }
+
+ if (!input.isOverItem()) {
+ if (DEBUG) Log.d(TAG, "Activity has no position. Canceling selection.");
+ clearSelection();
+ return false;
+ }
+
+ handleAdapterEvent(input);
+ return true;
+ }
+
+ /**
+ * Handles a change caused by a click on the item with the given position. If the Shift key is
+ * held down, this performs a range select; otherwise, it simply toggles the item's selection
+ * state.
+ */
+ private void handleAdapterEvent(InputEvent input) {
+ if (mRanger != null && input.isShiftKeyDown()) {
+ mRanger.snapSelection(input.getItemPosition());
+
+ // We're being lazy here notifying even when something might not have changed.
+ // To make this more correct, we'd need to update the Ranger class to return
+ // information about what has changed.
+ notifySelectionChanged();
+ } else {
+ toggleSelection(input.getItemPosition());
+ }
+ }
+
+ /**
+ * Toggles the selection state at position. If an item does end up selected
+ * a new Ranger (range selection manager) at that point is created.
+ *
+ * @param position
+ */
+ public void toggleSelection(int position) {
+ // Position may be special "no position" during certain
+ // transitional phases. If so, skip handling of the event.
+ if (position == RecyclerView.NO_POSITION) {
+ if (DEBUG) Log.d(TAG, "Ignoring toggle for element with no position.");
+ return;
+ }
+
+ boolean changed = false;
+ if (mSelection.contains(position)) {
+ changed = attemptDeselect(position);
+ } else {
+ boolean canSelect = notifyBeforeItemStateChange(position, true);
+ if (!canSelect) {
+ return;
+ }
+ if (mSingleSelect && hasSelection()) {
+ clearSelectionQuietly();
+ }
+
+ // Here we're already in selection mode. In that case
+ // When a simple click/tap (without SHIFT) creates causes
+ // an item to be selected.
+ // By recreating Ranger at this point, we allow the user to create
+ // multiple separate contiguous ranges with SHIFT+Click & Click.
+ selectAndNotify(position);
+ setSelectionFocusBegin(position);
+ changed = true;
+ }
+
+ if (changed) {
+ notifySelectionChanged();
+ }
+ }
+
+ /**
+ * Sets the magic location at which a selection range begins. This
+ * value is consulted when determining how to extend, and modify
+ * selection ranges.
+ *
+ * @throws IllegalStateException if {@code position} is not already be selected
+ * @param position
+ */
+ void setSelectionFocusBegin(int position) {
+ checkState(mSelection.contains(position));
+ mRanger = new Range(position);
+ }
+
+ /**
+ * Try to select all elements in range. Not that callbacks can cancel selection
+ * of specific items, so some or even all items may not reflect the desired
+ * state after the update is complete.
+ *
+ * @param begin inclusive
+ * @param end inclusive
+ * @param selected
+ */
+ private void updateRange(int begin, int end, boolean selected) {
+ checkState(end >= begin);
+ for (int i = begin; i <= end; i++) {
+ if (selected) {
+ boolean canSelect = notifyBeforeItemStateChange(i, true);
+ if (canSelect) {
+ if (mSingleSelect && hasSelection()) {
+ clearSelectionQuietly();
+ }
+ selectAndNotify(i);
+ }
+ } else {
+ attemptDeselect(i);
+ }
+ }
+ }
+
+ /**
+ * @param position
+ * @return True if the update was applied.
+ */
+ private boolean selectAndNotify(int position) {
+ boolean changed = mSelection.add(position);
+ if (changed) {
+ notifyItemStateChanged(position, true);
+ }
+ return changed;
+ }
+
+ /**
+ * @param position
+ * @return True if the update was applied.
+ */
+ private boolean attemptDeselect(int position) {
+ if (notifyBeforeItemStateChange(position, false)) {
+ mSelection.remove(position);
+ notifyItemStateChanged(position, false);
+ if (DEBUG) Log.d(TAG, "Selection after deselect: " + mSelection);
+ return true;
+ } else {
+ if (DEBUG) Log.d(TAG, "Select cancelled by listener.");
+ return false;
+ }
+ }
+
+ private boolean notifyBeforeItemStateChange(int position, boolean nextState) {
+ int lastListener = mCallbacks.size() - 1;
+ for (int i = lastListener; i > -1; i--) {
+ if (!mCallbacks.get(i).onBeforeItemStateChange(position, nextState)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Notifies registered listeners when the selection status of a single item
+ * (identified by {@code position}) changes.
+ */
+ private void notifyItemStateChanged(int position, boolean selected) {
+ int lastListener = mCallbacks.size() - 1;
+ for (int i = lastListener; i > -1; i--) {
+ mCallbacks.get(i).onItemStateChanged(position, selected);
+ }
+ mAdapter.notifyItemChanged(position, SELECTION_CHANGED_MARKER);
+ }
+
+ /**
+ * Notifies registered listeners when the selection has changed. This
+ * notification should be sent only once a full series of changes
+ * is complete, e.g. clearingSelection, or updating the single
+ * selection from one item to another.
+ */
+ private void notifySelectionChanged() {
+ int lastListener = mCallbacks.size() - 1;
+ for (int i = lastListener; i > -1; i--) {
+ mCallbacks.get(i).onSelectionChanged();
+ }
+ }
+
+ /**
+ * Class providing support for managing range selections.
+ */
+ private final class Range {
+ private static final int UNDEFINED = -1;
+
+ final int mBegin;
+ int mEnd = UNDEFINED;
+
+ public Range(int begin) {
+ if (DEBUG) Log.d(TAG, "New Ranger created beginning @ " + begin);
+ mBegin = begin;
+ }
+
+ private void snapSelection(int position) {
+ checkState(mRanger != null);
+ checkArgument(position != RecyclerView.NO_POSITION);
+
+ if (mEnd == UNDEFINED || mEnd == mBegin) {
+ // Reset mEnd so it can be established in establishRange.
+ mEnd = UNDEFINED;
+ establishRange(position);
+ } else {
+ reviseRange(position);
+ }
+ }
+
+ private void establishRange(int position) {
+ checkState(mRanger.mEnd == UNDEFINED);
+
+ if (position == mBegin) {
+ mEnd = position;
+ }
+
+ if (position > mBegin) {
+ updateRange(mBegin + 1, position, true);
+ } else if (position < mBegin) {
+ updateRange(position, mBegin - 1, true);
+ }
+
+ mEnd = position;
+ }
+
+ private void reviseRange(int position) {
+ checkState(mEnd != UNDEFINED);
+ checkState(mBegin != mEnd);
+
+ if (position == mEnd) {
+ if (DEBUG) Log.i(TAG, "Skipping no-op revision click on mEndRange.");
+ }
+
+ if (mEnd > mBegin) {
+ reviseAscendingRange(position);
+ } else if (mEnd < mBegin) {
+ reviseDescendingRange(position);
+ }
+ // the "else" case is covered by checkState at beginning of method.
+
+ mEnd = position;
+ }
+
+ /**
+ * Updates an existing ascending seleciton.
+ * @param position
+ */
+ private void reviseAscendingRange(int position) {
+ // Reducing or reversing the range....
+ if (position < mEnd) {
+ if (position < mBegin) {
+ updateRange(mBegin + 1, mEnd, false);
+ updateRange(position, mBegin -1, true);
+ } else {
+ updateRange(position + 1, mEnd, false);
+ }
+ }
+
+ // Extending the range...
+ else if (position > mEnd) {
+ updateRange(mEnd + 1, position, true);
+ }
+ }
+
+ private void reviseDescendingRange(int position) {
+ // Reducing or reversing the range....
+ if (position > mEnd) {
+ if (position > mBegin) {
+ updateRange(mEnd, mBegin - 1, false);
+ updateRange(mBegin + 1, position, true);
+ } else {
+ updateRange(mEnd, position - 1, false);
+ }
+ }
+
+ // Extending the range...
+ else if (position < mEnd) {
+ updateRange(position, mEnd - 1, true);
+ }
+ }
+ }
+
+ /**
+ * Object representing the current selection. Provides read only access
+ * public access, and private write access.
+ */
+ public static final class Selection {
+
+ // This class tracks selected positions by managing two arrays: the saved selection, and
+ // the total selection. Saved selections are those which have been completed by tapping an
+ // item or by completing a band select operation. Provisional selections are selections
+ // which have been temporarily created by an in-progress band select operation (once the
+ // user releases the mouse button during a band select operation, the selected items
+ // become saved). The total selection is the combination of both the saved selection and
+ // the provisional selection. Tracking both separately is necessary to ensure that saved
+ // selections do not become deselected when they are removed from the provisional selection;
+ // for example, if item A is tapped (and selected), then an in-progress band select covers A
+ // then uncovers A, A should still be selected as it has been saved. To ensure this
+ // behavior, the saved selection must be tracked separately.
+ private SparseBooleanArray mSavedSelection;
+ private SparseBooleanArray mTotalSelection;
+
+ public Selection() {
+ mSavedSelection = new SparseBooleanArray();
+ mTotalSelection = new SparseBooleanArray();
+ }
+
+ @VisibleForTesting
+ public Selection(int... positions) {
+ this();
+ for (int i = 0; i < positions.length; i++) {
+ add(positions[i]);
+ }
+ }
+
+ /**
+ * @param position
+ * @return true if the position is currently selected.
+ */
+ public boolean contains(int position) {
+ return mTotalSelection.get(position);
+ }
+
+ /**
+ * Useful for iterating over selection. Please note that
+ * iteration should be done over a copy of the selection,
+ * not the live selection.
+ *
+ * @see #copyTo(MultiSelectManager.Selection)
+ *
+ * @param index
+ * @return the position value stored at specified index.
+ */
+ public int get(int index) {
+ return mTotalSelection.keyAt(index);
+ }
+
+ /**
+ * Returns an unordered array of selected positions.
+ */
+ public int[] getAll() {
+ final int size = size();
+ int[] positions = new int[size];
+ for (int i = 0; i < size; i++) {
+ positions[i] = get(i);
+ }
+ return positions;
+ }
+
+ /**
+ * @return size of the selection.
+ */
+ public int size() {
+ return mTotalSelection.size();
+ }
+
+ /**
+ * @return true if the selection is empty.
+ */
+ public boolean isEmpty() {
+ return mTotalSelection.size() == 0;
+ }
+
+ /**
+ * Sets the provisional selection, which is a temporary selection that can be saved,
+ * canceled, or adjusted at a later time. When a new provision selection is applied, the old
+ * one (if it exists) is abandoned.
+ * @return Array with entry for each position added or removed. Entries which were added
+ * contain a value of true, and entries which were removed contain a value of false.
+ */
+ @VisibleForTesting
+ protected SparseBooleanArray setProvisionalSelection(
+ SparseBooleanArray provisionalSelection) {
+ SparseBooleanArray delta = new SparseBooleanArray();
+
+ for (int i = 0; i < mTotalSelection.size(); i++) {
+ int position = mTotalSelection.keyAt(i);
+ if (!provisionalSelection.get(position) && !mSavedSelection.get(position)) {
+ // Remove each item that used to be in the selection but is unsaved and not in
+ // the new provisional selection.
+ delta.put(position, false);
+ }
+ }
+
+ for (int i = 0; i < provisionalSelection.size(); i++) {
+ int position = provisionalSelection.keyAt(i);
+ if (!mTotalSelection.get(position)) {
+ // Add each item that was not previously in the selection but is in the
+ // new provisional selection.
+ delta.put(position, true);
+ }
+ }
+
+ // Now, iterate through the changes and actually add/remove them to/from
+ // mCurrentSelection. This could not be done in the previous loops because changing the
+ // size of the selection mid-iteration changes iteration order erroneously.
+ for (int i = 0; i < delta.size(); i++) {
+ int position = delta.keyAt(i);
+ if (delta.get(position)) {
+ mTotalSelection.put(position, true);
+ } else {
+ mTotalSelection.delete(position);
+ }
+ }
+
+ return delta;
+ }
+
+ /**
+ * Saves the existing provisional selection. Once the provisional selection is saved,
+ * subsequent provisional selections which are different from this existing one cannot
+ * cause items in this existing provisional selection to become deselected.
+ */
+ @VisibleForTesting
+ protected void applyProvisionalSelection() {
+ mSavedSelection = mTotalSelection.clone();
+ }
+
+ /**
+ * Abandons the existing provisional selection so that all items provisionally selected are
+ * now deselected.
+ */
+ @VisibleForTesting
+ protected void cancelProvisionalSelection() {
+ mTotalSelection = mSavedSelection.clone();
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ boolean add(int position) {
+ if (!mTotalSelection.get(position)) {
+ mTotalSelection.put(position, true);
+ mSavedSelection.put(position, true);
+ return true;
+ }
+ return false;
+ }
+
+ /** @hide */
+ @VisibleForTesting
+ boolean remove(int position) {
+ if (mTotalSelection.get(position)) {
+ mTotalSelection.delete(position);
+ mSavedSelection.delete(position);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Adjusts the selection range to reflect the existence of newly inserted values at
+ * the specified positions. This has the effect of adjusting all existing selected
+ * positions within the specified range accordingly. Note that this function discards any
+ * provisional selections which may have been applied.
+ *
+ * @param startPosition
+ * @param count
+ * @hide
+ */
+ @VisibleForTesting
+ void expand(int startPosition, int count) {
+ checkState(startPosition >= 0);
+ checkState(count > 0);
+ cancelProvisionalSelection();
+
+ for (int i = 0; i < mTotalSelection.size(); i++) {
+ int itemPosition = mTotalSelection.keyAt(i);
+ if (itemPosition >= startPosition) {
+ mTotalSelection.setKeyAt(i, itemPosition + count);
+ mSavedSelection.setKeyAt(i, itemPosition + count);
+ }
+ }
+ }
+
+ /**
+ * Adjusts the selection range to reflect the removal specified positions. This has
+ * the effect of adjusting all existing selected positions within the specified range
+ * accordingly. Note that this function discards any provisional selections which may have
+ * been applied.
+ *
+ * @param startPosition
+ * @param count The length of the range to collapse. Must be greater than 0.
+ * @hide
+ */
+ @VisibleForTesting
+ void collapse(int startPosition, int count) {
+ checkState(startPosition >= 0);
+ checkState(count > 0);
+
+ int endPosition = startPosition + count - 1;
+
+ SparseBooleanArray newSelection = new SparseBooleanArray();
+ for (int i = 0; i < mSavedSelection.size(); i++) {
+ int itemPosition = mSavedSelection.keyAt(i);
+ if (itemPosition < startPosition) {
+ newSelection.append(itemPosition, true);
+ } else if (itemPosition > endPosition) {
+ newSelection.append(itemPosition - count, true);
+ }
+ }
+ mSavedSelection = newSelection;
+ cancelProvisionalSelection();
+ }
+
+ public void clear() {
+ mSavedSelection.clear();
+ mTotalSelection.clear();
+ }
+
+ @VisibleForTesting
+ void copyFrom(Selection source) {
+ mSavedSelection = source.mSavedSelection.clone();
+ mTotalSelection = source.mTotalSelection.clone();
+ }
+
+ @Override
+ public String toString() {
+ if (size() <= 0) {
+ return "size=0, items=[]";
+ }
+
+ StringBuilder buffer = new StringBuilder(mTotalSelection.size() * 28);
+ buffer.append("{size=")
+ .append(mTotalSelection.size())
+ .append(", ")
+ .append("items=[");
+ for (int i=0; i < mTotalSelection.size(); i++) {
+ if (i > 0) {
+ buffer.append(", ");
+ }
+ buffer.append(mTotalSelection.keyAt(i));
+ }
+ buffer.append("]}");
+ return buffer.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return mSavedSelection.hashCode() ^ mTotalSelection.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (this == that) {
+ return true;
+ }
+
+ if (!(that instanceof Selection)) {
+ return false;
+ }
+
+ return mSavedSelection.equals(((Selection) that).mSavedSelection) &&
+ mTotalSelection.equals(((Selection) that).mTotalSelection);
+ }
+ }
+
+ /**
+ * Provides functionality for BandController. Exists primarily to tests that are
+ * fully isolated from RecyclerView.
+ */
+ interface SelectionEnvironment {
+ void showBand(Rect rect);
+ void hideBand();
+ void addOnScrollListener(RecyclerView.OnScrollListener listener);
+ void removeOnScrollListener(RecyclerView.OnScrollListener listener);
+ void scrollBy(int dy);
+ int getHeight();
+ void invalidateView();
+ void runAtNextFrame(Runnable r);
+ void removeCallback(Runnable r);
+ Point createAbsolutePoint(Point relativePoint);
+ Rect getAbsoluteRectForChildViewAt(int index);
+ int getAdapterPositionAt(int index);
+ int getAdapterPositionForChildView(View view);
+ int getColumnCount();
+ int getRowCount();
+ int getChildCount();
+ int getVisibleChildCount();
+ void focusItem(int position);
+ }
+
+ /** Recycler view facade implementation backed by good ol' RecyclerView. */
+ private static final class RuntimeSelectionEnvironment implements SelectionEnvironment {
+
+ private final RecyclerView mView;
+ private final Drawable mBand;
+
+ private boolean mIsOverlayShown = false;
+
+ RuntimeSelectionEnvironment(RecyclerView rv) {
+ mView = rv;
+ mBand = mView.getContext().getTheme().getDrawable(R.drawable.band_select_overlay);
+ }
+
+ @Override
+ public int getAdapterPositionForChildView(View view) {
+ if (view.getParent() == mView) {
+ return mView.getChildAdapterPosition(view);
+ } else {
+ return RecyclerView.NO_POSITION;
+ }
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ return getAdapterPositionForChildView(mView.getChildAt(index));
+ }
+
+ @Override
+ public void addOnScrollListener(OnScrollListener listener) {
+ mView.addOnScrollListener(listener);
+ }
+
+ @Override
+ public void removeOnScrollListener(OnScrollListener listener) {
+ mView.removeOnScrollListener(listener);
+ }
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return new Point(relativePoint.x + mView.computeHorizontalScrollOffset(),
+ relativePoint.y + mView.computeVerticalScrollOffset());
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ final View child = mView.getChildAt(index);
+ final Rect childRect = new Rect();
+ child.getHitRect(childRect);
+ childRect.left += mView.computeHorizontalScrollOffset();
+ childRect.right += mView.computeHorizontalScrollOffset();
+ childRect.top += mView.computeVerticalScrollOffset();
+ childRect.bottom += mView.computeVerticalScrollOffset();
+ return childRect;
+ }
+
+ @Override
+ public int getChildCount() {
+ return mView.getAdapter().getItemCount();
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ return mView.getChildCount();
+ }
+
+ @Override
+ public int getColumnCount() {
+ LayoutManager layoutManager = mView.getLayoutManager();
+ if (layoutManager instanceof GridLayoutManager) {
+ return ((GridLayoutManager) layoutManager).getSpanCount();
+ }
+
+ // Otherwise, it is a list with 1 column.
+ return 1;
+ }
+
+ @Override
+ public int getRowCount() {
+ int numFullColumns = getChildCount() / getColumnCount();
+ boolean hasPartiallyFullColumn = getChildCount() % getColumnCount() != 0;
+ return numFullColumns + (hasPartiallyFullColumn ? 1 : 0);
+ }
+
+ @Override
+ public int getHeight() {
+ return mView.getHeight();
+ }
+
+ @Override
+ public void invalidateView() {
+ mView.invalidate();
+ }
+
+ @Override
+ public void runAtNextFrame(Runnable r) {
+ mView.postOnAnimation(r);
+ }
+
+ @Override
+ public void removeCallback(Runnable r) {
+ mView.removeCallbacks(r);
+ }
+
+ @Override
+ public void scrollBy(int dy) {
+ mView.scrollBy(0, dy);
+ }
+
+ @Override
+ public void showBand(Rect rect) {
+ mBand.setBounds(rect);
+
+ if (!mIsOverlayShown) {
+ mView.getOverlay().add(mBand);
+ }
+ }
+
+ @Override
+ public void hideBand() {
+ mView.getOverlay().remove(mBand);
+ }
+
+ @Override
+ public void focusItem(final int pos) {
+ // If the item is already in view, focus it; otherwise, scroll to it and focus it.
+ RecyclerView.ViewHolder vh = mView.findViewHolderForAdapterPosition(pos);
+ if (vh != null) {
+ vh.itemView.requestFocus();
+ } else {
+ // Don't smooth scroll; that taxes the system unnecessarily and makes the scroll
+ // handling logic below more complicated. See b/24865658.
+ mView.scrollToPosition(pos);
+ // Set a one-time listener to request focus when the scroll has completed.
+ mView.addOnScrollListener(
+ new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(RecyclerView view, int dx, int dy) {
+ view.findViewHolderForAdapterPosition(pos).itemView.requestFocus();
+ view.removeOnScrollListener(this);
+ }
+ });
+ }
+ }
+ }
+
+ public interface Callback {
+ /**
+ * Called when an item is selected or unselected while in selection mode.
+ *
+ * @param position Adapter position of the item that was checked or unchecked
+ * @param selected <code>true</code> if the item is now selected, <code>false</code>
+ * if the item is now unselected.
+ */
+ public void onItemStateChanged(int position, boolean selected);
+
+ /**
+ * Called prior to an item changing state. Callbacks can cancel
+ * the change at {@code position} by returning {@code false}.
+ *
+ * @param position Adapter position of the item that was checked or unchecked
+ * @param selected <code>true</code> if the item is to be selected, <code>false</code>
+ * if the item is to be unselected.
+ */
+ public boolean onBeforeItemStateChange(int position, boolean selected);
+
+ /**
+ * Called immediately after completion of any set of changes.
+ */
+ public void onSelectionChanged();
+ }
+
+ /**
+ * Provides mouse driven band-select support when used in conjunction with {@link RecyclerView}
+ * and {@link MultiSelectManager}. This class is responsible for rendering the band select
+ * overlay and selecting overlaid items via MultiSelectManager.
+ */
+ public class BandController extends RecyclerView.OnScrollListener
+ implements GridModel.OnSelectionChangedListener {
+
+ private static final int NOT_SET = -1;
+
+ private final Runnable mModelBuilder;
+
+ @Nullable private Rect mBounds;
+ @Nullable private Point mCurrentPosition;
+ @Nullable private Point mOrigin;
+ @Nullable private GridModel mModel;
+
+ // The time at which the current band selection-induced scroll began. If no scroll is in
+ // progress, the value is NOT_SET.
+ private long mScrollStartTime = NOT_SET;
+ private final Runnable mViewScroller = new ViewScroller();
+
+ public BandController() {
+ mEnvironment.addOnScrollListener(this);
+
+ mModelBuilder = new Runnable() {
+ @Override
+ public void run() {
+ mModel = new GridModel(mEnvironment);
+ mModel.addOnSelectionChangedListener(BandController.this);
+ }
+ };
+ }
+
+ public boolean handleEvent(MotionInputEvent e) {
+ // b/23793622 notes the fact that we *never* receive ACTION_DOWN
+ // events in onTouchEvent. Where it not for this issue, we'd
+ // push start handling down into handleInputEvent.
+ if (mBandManager.shouldStart(e)) {
+ // endBandSelect is handled in handleInputEvent.
+ mBandManager.startBandSelect(e.getOrigin());
+ } else if (mBandManager.isActive()
+ && e.isMouseEvent()
+ && e.isActionUp()) {
+ // Same issue here w b/23793622. The ACTION_UP event
+ // is only evert dispatched to onTouchEvent when
+ // there is some associated motion. If a user taps
+ // mouse, but doesn't move, then band select gets
+ // started BUT not ended. Causing phantom
+ // bands to appear when the user later clicks to start
+ // band select.
+ mBandManager.processInputEvent(e);
+ }
+
+ return isActive();
+ }
+
+ private boolean isActive() {
+ return mModel != null;
+ }
+
+ /**
+ * Handle a change in layout by cleaning up and getting rid of the old model and creating
+ * a new model which will track the new layout.
+ */
+ public void handleLayoutChanged() {
+ if (mModel != null) {
+ mModel.removeOnSelectionChangedListener(this);
+ mModel.stopListening();
+
+ // build a new model, all fresh and happy.
+ mModelBuilder.run();
+ }
+ }
+
+ boolean shouldStart(MotionInputEvent e) {
+ return !isActive()
+ && e.isMouseEvent() // a mouse
+ && e.isActionDown() // the initial button press
+ && mAdapter.getItemCount() > 0
+ && e.getItemPosition() == RecyclerView.NO_ID; // in empty space
+ }
+
+ boolean shouldStop(InputEvent input) {
+ return isActive()
+ && input.isMouseEvent()
+ && input.isActionUp();
+ }
+
+ /**
+ * Processes a MotionEvent by starting, ending, or resizing the band select overlay.
+ * @param input
+ */
+ private void processInputEvent(InputEvent input) {
+ checkArgument(input.isMouseEvent());
+
+ if (shouldStop(input)) {
+ endBandSelect();
+ return;
+ }
+
+ // We shouldn't get any events in this method when band select is not active,
+ // but it turns some guests show up late to the party.
+ if (!isActive()) {
+ return;
+ }
+
+ mCurrentPosition = input.getOrigin();
+ mModel.resizeSelection(input.getOrigin());
+ scrollViewIfNecessary();
+ resizeBandSelectRectangle();
+ }
+
+ /**
+ * Starts band select by adding the drawable to the RecyclerView's overlay.
+ */
+ private void startBandSelect(Point origin) {
+ if (DEBUG) Log.d(TAG, "Starting band select @ " + origin);
+
+ mOrigin = origin;
+ mModelBuilder.run(); // Creates a new selection model.
+ mModel.startSelection(mOrigin);
+ }
+
+ /**
+ * Scrolls the view if necessary.
+ */
+ private void scrollViewIfNecessary() {
+ mEnvironment.removeCallback(mViewScroller);
+ mViewScroller.run();
+ mEnvironment.invalidateView();
+ }
+
+ /**
+ * Resizes the band select rectangle by using the origin and the current pointer position as
+ * two opposite corners of the selection.
+ */
+ private void resizeBandSelectRectangle() {
+ mBounds = new Rect(Math.min(mOrigin.x, mCurrentPosition.x),
+ Math.min(mOrigin.y, mCurrentPosition.y),
+ Math.max(mOrigin.x, mCurrentPosition.x),
+ Math.max(mOrigin.y, mCurrentPosition.y));
+ mEnvironment.showBand(mBounds);
+ }
+
+ /**
+ * Ends band select by removing the overlay.
+ */
+ private void endBandSelect() {
+ if (DEBUG) Log.d(TAG, "Ending band select.");
+
+ mEnvironment.hideBand();
+ mSelection.applyProvisionalSelection();
+ mModel.endSelection();
+ int firstSelected = mModel.getPositionNearestOrigin();
+ if (!mSelection.contains(firstSelected)) {
+ Log.w(TAG, "First selected by band is NOT in selection!");
+ // Sadly this is really happening. Need to figure out what's going on.
+ } else if (firstSelected != GridModel.NOT_SET) {
+ setSelectionFocusBegin(firstSelected);
+ }
+
+ mModel = null;
+ mOrigin = null;
+ }
+
+ @Override
+ public void onSelectionChanged(SparseBooleanArray updatedSelection) {
+ SparseBooleanArray delta = mSelection.setProvisionalSelection(updatedSelection);
+ for (int i = 0; i < delta.size(); i++) {
+ int position = delta.keyAt(i);
+ notifyItemStateChanged(position, delta.get(position));
+ }
+ notifySelectionChanged();
+ }
+
+ private class ViewScroller implements Runnable {
+ /**
+ * The number of milliseconds of scrolling at which scroll speed continues to increase.
+ * At first, the scroll starts slowly; then, the rate of scrolling increases until it
+ * reaches its maximum value at after this many milliseconds.
+ */
+ private static final long SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
+
+ @Override
+ public void run() {
+ // Compute the number of pixels the pointer's y-coordinate is past the view.
+ // Negative values mean the pointer is at or before the top of the view, and
+ // positive values mean that the pointer is at or after the bottom of the view. Note
+ // that one additional pixel is added here so that the view still scrolls when the
+ // pointer is exactly at the top or bottom.
+ int pixelsPastView = 0;
+ if (mCurrentPosition.y <= 0) {
+ pixelsPastView = mCurrentPosition.y - 1;
+ } else if (mCurrentPosition.y >= mEnvironment.getHeight() - 1) {
+ pixelsPastView = mCurrentPosition.y - mEnvironment.getHeight() + 1;
+ }
+
+ if (!isActive() || pixelsPastView == 0) {
+ // If band selection is inactive, or if it is active but not at the edge of the
+ // view, no scrolling is necessary.
+ mScrollStartTime = NOT_SET;
+ return;
+ }
+
+ if (mScrollStartTime == NOT_SET) {
+ // If the pointer was previously not at the edge of the view but now is, set the
+ // start time for the scroll.
+ mScrollStartTime = System.currentTimeMillis();
+ }
+
+ // Compute the number of pixels to scroll, and scroll that many pixels.
+ final int numPixels = computeScrollDistance(
+ pixelsPastView, System.currentTimeMillis() - mScrollStartTime);
+ mEnvironment.scrollBy(numPixels);
+
+ mEnvironment.removeCallback(mViewScroller);
+ mEnvironment.runAtNextFrame(this);
+ }
+
+ /**
+ * Computes the number of pixels to scroll based on how far the pointer is past the end
+ * of the view and how long it has been there. Roughly based on ItemTouchHelper's
+ * algorithm for computing the number of pixels to scroll when an item is dragged to the
+ * end of a {@link RecyclerView}.
+ * @param pixelsPastView
+ * @param scrollDuration
+ * @return
+ */
+ private int computeScrollDistance(int pixelsPastView, long scrollDuration) {
+ final int maxScrollStep = mEnvironment.getHeight();
+ final int direction = (int) Math.signum(pixelsPastView);
+ final int absPastView = Math.abs(pixelsPastView);
+
+ // Calculate the ratio of how far out of the view the pointer currently resides to
+ // the entire height of the view.
+ final float outOfBoundsRatio = Math.min(
+ 1.0f, (float) absPastView / mEnvironment.getHeight());
+ // Interpolate this ratio and use it to compute the maximum scroll that should be
+ // possible for this step.
+ final float cappedScrollStep =
+ direction * maxScrollStep * smoothOutOfBoundsRatio(outOfBoundsRatio);
+
+ // Likewise, calculate the ratio of the time spent in the scroll to the limit.
+ final float timeRatio = Math.min(
+ 1.0f, (float) scrollDuration / SCROLL_ACCELERATION_LIMIT_TIME_MS);
+ // Interpolate this ratio and use it to compute the final number of pixels to
+ // scroll.
+ final int numPixels = (int) (cappedScrollStep * smoothTimeRatio(timeRatio));
+
+ // If the final number of pixels to scroll ends up being 0, the view should still
+ // scroll at least one pixel.
+ return numPixels != 0 ? numPixels : direction;
+ }
+
+ /**
+ * Interpolates the given out of bounds ratio on a curve which starts at (0,0) and ends
+ * at (1,1) and quickly approaches 1 near the start of that interval. This ensures that
+ * drags that are at the edge or barely past the edge of the view still cause sufficient
+ * scrolling. The equation y=(x-1)^5+1 is used, but this could also be tweaked if
+ * needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothOutOfBoundsRatio(float ratio) {
+ return (float) Math.pow(ratio - 1.0f, 5) + 1.0f;
+ }
+
+ /**
+ * Interpolates the given time ratio on a curve which starts at (0,0) and ends at (1,1)
+ * and stays close to 0 for most input values except those very close to 1. This ensures
+ * that scrolls start out very slowly but speed up drastically after the scroll has been
+ * in progress close to SCROLL_ACCELERATION_LIMIT_TIME_MS. The equation y=x^5 is used,
+ * but this could also be tweaked if needed.
+ * @param ratio A ratio which is in the range [0, 1].
+ * @return A "smoothed" value, also in the range [0, 1].
+ */
+ private float smoothTimeRatio(float ratio) {
+ return (float) Math.pow(ratio, 5);
+ }
+ };
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if (!isActive()) {
+ return;
+ }
+
+ // Adjust the y-coordinate of the origin the opposite number of pixels so that the
+ // origin remains in the same place relative to the view's items.
+ mOrigin.y -= dy;
+ resizeBandSelectRectangle();
+ }
+ }
+
+ /**
+ * Provides a band selection item model for views within a RecyclerView. This class queries the
+ * RecyclerView to determine where its items are placed; then, once band selection is underway,
+ * it alerts listeners of which items are covered by the selections.
+ */
+ public static final class GridModel extends RecyclerView.OnScrollListener {
+
+ public static final int NOT_SET = -1;
+
+ // Enum values used to determine the corner at which the origin is located within the
+ private static final int UPPER = 0x00;
+ private static final int LOWER = 0x01;
+ private static final int LEFT = 0x00;
+ private static final int RIGHT = 0x02;
+ private static final int UPPER_LEFT = UPPER | LEFT;
+ private static final int UPPER_RIGHT = UPPER | RIGHT;
+ private static final int LOWER_LEFT = LOWER | LEFT;
+ private static final int LOWER_RIGHT = LOWER | RIGHT;
+
+ private final SelectionEnvironment mHelper;
+ private final List<OnSelectionChangedListener> mOnSelectionChangedListeners =
+ new ArrayList<>();
+
+ // Map from the x-value of the left side of a SparseBooleanArray of adapter positions, keyed
+ // by their y-offset. For example, if the first column of the view starts at an x-value of 5,
+ // mColumns.get(5) would return an array of positions in that column. Within that array, the
+ // value for key y is the adapter position for the item whose y-offset is y.
+ private final SparseArray<SparseIntArray> mColumns = new SparseArray<>();
+
+ // List of limits along the x-axis (columns).
+ // This list is sorted from furthest left to furthest right.
+ private final List<Limits> mColumnBounds = new ArrayList<>();
+
+ // List of limits along the y-axis (rows). Note that this list only contains items which
+ // have been in the viewport.
+ private final List<Limits> mRowBounds = new ArrayList<>();
+
+ // The adapter positions which have been recorded so far.
+ private final SparseBooleanArray mKnownPositions = new SparseBooleanArray();
+
+ // Array passed to registered OnSelectionChangedListeners. One array is created and reused
+ // throughout the lifetime of the object.
+ private final SparseBooleanArray mSelection = new SparseBooleanArray();
+
+ // The current pointer (in absolute positioning from the top of the view).
+ private Point mPointer = null;
+
+ // The bounds of the band selection.
+ private RelativePoint mRelativeOrigin;
+ private RelativePoint mRelativePointer;
+
+ private boolean mIsActive;
+
+ // Tracks where the band select originated from. This is used to determine where selections
+ // should expand from when Shift+click is used.
+ private int mPositionNearestOrigin = NOT_SET;
+
+ GridModel(SelectionEnvironment helper) {
+ mHelper = helper;
+ mHelper.addOnScrollListener(this);
+ }
+
+ /**
+ * Stops listening to the view's scrolls. Call this function before discarding a
+ * BandSelecModel object to prevent memory leaks.
+ */
+ void stopListening() {
+ mHelper.removeOnScrollListener(this);
+ }
+
+ /**
+ * Start a band select operation at the given point.
+ * @param relativeOrigin The origin of the band select operation, relative to the viewport.
+ * For example, if the view is scrolled to the bottom, the top-left of the viewport
+ * would have a relative origin of (0, 0), even though its absolute point has a higher
+ * y-value.
+ */
+ void startSelection(Point relativeOrigin) {
+ mIsActive = true;
+ mPointer = mHelper.createAbsolutePoint(relativeOrigin);
+
+ recordVisibleChildren();
+ mRelativeOrigin = new RelativePoint(mPointer);
+ mRelativePointer = new RelativePoint(mPointer);
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Resizes the selection by adjusting the pointer (i.e., the corner of the selection
+ * opposite the origin.
+ * @param relativePointer The pointer (opposite of the origin) of the band select operation,
+ * relative to the viewport. For example, if the view is scrolled to the bottom, the
+ * top-left of the viewport would have a relative origin of (0, 0), even though its
+ * absolute point has a higher y-value.
+ */
+ void resizeSelection(Point relativePointer) {
+ mPointer = mHelper.createAbsolutePoint(relativePointer);
+ updateModel();
+ }
+
+ /**
+ * Ends the band selection.
+ */
+ void endSelection() {
+ mIsActive = false;
+ }
+
+ /**
+ * @return The adapter position for the item nearest the origin corresponding to the latest
+ * band select operation, or NOT_SET if the selection did not cover any items.
+ */
+ int getPositionNearestOrigin() {
+ return mPositionNearestOrigin;
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ if (!mIsActive) {
+ return;
+ }
+
+ mPointer.x += dx;
+ mPointer.y += dy;
+ recordVisibleChildren();
+ updateModel();
+ }
+
+ /**
+ * Queries the view for all children and records their location metadata.
+ */
+ private void recordVisibleChildren() {
+ for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
+ int adapterPosition = mHelper.getAdapterPositionAt(i);
+ if (!mKnownPositions.get(adapterPosition)) {
+ mKnownPositions.put(adapterPosition, true);
+ recordItemData(
+ mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
+ }
+ }
+ }
+
+ /**
+ * Updates the limits lists and column map with the given item metadata.
+ * @param absoluteChildRect The absolute rectangle for the child view being processed.
+ * @param adapterPosition The position of the child view being processed.
+ */
+ private void recordItemData(Rect absoluteChildRect, int adapterPosition) {
+ if (mColumnBounds.size() != mHelper.getColumnCount()) {
+ // If not all x-limits have been recorded, record this one.
+ recordLimits(
+ mColumnBounds, new Limits(absoluteChildRect.left, absoluteChildRect.right));
+ }
+
+ if (mRowBounds.size() != mHelper.getRowCount()) {
+ // If not all y-limits have been recorded, record this one.
+ recordLimits(
+ mRowBounds, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
+ }
+
+ SparseIntArray columnList = mColumns.get(absoluteChildRect.left);
+ if (columnList == null) {
+ columnList = new SparseIntArray();
+ mColumns.put(absoluteChildRect.left, columnList);
+ }
+ columnList.put(absoluteChildRect.top, adapterPosition);
+ }
+
+ /**
+ * Ensures limits exists within the sorted list limitsList, and adds it to the list if it
+ * does not exist.
+ */
+ private void recordLimits(List<Limits> limitsList, Limits limits) {
+ int index = Collections.binarySearch(limitsList, limits);
+ if (index < 0) {
+ limitsList.add(~index, limits);
+ }
+ }
+
+ /**
+ * Handles a moved pointer; this function determines whether the pointer movement resulted
+ * in a selection change and, if it has, notifies listeners of this change.
+ */
+ private void updateModel() {
+ RelativePoint old = mRelativePointer;
+ mRelativePointer = new RelativePoint(mPointer);
+ if (old != null && mRelativePointer.equals(old)) {
+ return;
+ }
+
+ computeCurrentSelection();
+ notifyListeners();
+ }
+
+ /**
+ * Computes the currently-selected items.
+ */
+ private void computeCurrentSelection() {
+ if (areItemsCoveredByBand(mRelativePointer, mRelativeOrigin)) {
+ updateSelection(computeBounds());
+ } else {
+ mSelection.clear();
+ mPositionNearestOrigin = NOT_SET;
+ }
+ }
+
+ /**
+ * Notifies all listeners of a selection change. Note that this function simply passes
+ * mSelection, so computeCurrentSelection() should be called before this
+ * function.
+ */
+ private void notifyListeners() {
+ for (OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
+ listener.onSelectionChanged(mSelection);
+ }
+ }
+
+ /**
+ * @param rect Rectangle including all covered items.
+ */
+ private void updateSelection(Rect rect) {
+ int columnStartIndex =
+ Collections.binarySearch(mColumnBounds, new Limits(rect.left, rect.left));
+ checkState(columnStartIndex >= 0);
+ int columnEndIndex = columnStartIndex;
+
+ for (int i = columnStartIndex; i < mColumnBounds.size()
+ && mColumnBounds.get(i).lowerLimit <= rect.right; i++) {
+ columnEndIndex = i;
+ }
+
+ SparseIntArray firstColumn =
+ mColumns.get(mColumnBounds.get(columnStartIndex).lowerLimit);
+ int rowStartIndex = firstColumn.indexOfKey(rect.top);
+ if (rowStartIndex < 0) {
+ mPositionNearestOrigin = NOT_SET;
+ return;
+ }
+
+ int rowEndIndex = rowStartIndex;
+ for (int i = rowStartIndex;
+ i < firstColumn.size() && firstColumn.keyAt(i) <= rect.bottom; i++) {
+ rowEndIndex = i;
+ }
+
+ updateSelection(columnStartIndex, columnEndIndex, rowStartIndex, rowEndIndex);
+ }
+
+ /**
+ * Computes the selection given the previously-computed start- and end-indices for each
+ * row and column.
+ */
+ private void updateSelection(
+ int columnStartIndex, int columnEndIndex, int rowStartIndex, int rowEndIndex) {
+ mSelection.clear();
+ for (int column = columnStartIndex; column <= columnEndIndex; column++) {
+ SparseIntArray items = mColumns.get(mColumnBounds.get(column).lowerLimit);
+ for (int row = rowStartIndex; row <= rowEndIndex; row++) {
+ int position = items.get(items.keyAt(row));
+ mSelection.append(position, true);
+ if (isPossiblePositionNearestOrigin(column, columnStartIndex, columnEndIndex,
+ row, rowStartIndex, rowEndIndex)) {
+ // If this is the position nearest the origin, record it now so that it
+ // can be returned by endSelection() later.
+ mPositionNearestOrigin = position;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return Returns true if the position is the nearest to the origin, or, in the case of the
+ * lower-right corner, whether it is possible that the position is the nearest to the
+ * origin. See comment below for reasoning for this special case.
+ */
+ private boolean isPossiblePositionNearestOrigin(int columnIndex, int columnStartIndex,
+ int columnEndIndex, int rowIndex, int rowStartIndex, int rowEndIndex) {
+ int corner = computeCornerNearestOrigin();
+ switch (corner) {
+ case UPPER_LEFT:
+ return columnIndex == columnStartIndex && rowIndex == rowStartIndex;
+ case UPPER_RIGHT:
+ return columnIndex == columnEndIndex && rowIndex == rowStartIndex;
+ case LOWER_LEFT:
+ return columnIndex == columnStartIndex && rowIndex == rowEndIndex;
+ case LOWER_RIGHT:
+ // Note that in some cases, the last row will not have as many items as there
+ // are columns (e.g., if there are 4 items and 3 columns, the second row will
+ // only have one item in the first column). This function is invoked for each
+ // position from left to right, so return true for any position in the bottom
+ // row and only the right-most position in the bottom row will be recorded.
+ return rowIndex == rowEndIndex;
+ default:
+ throw new RuntimeException("Invalid corner type.");
+ }
+ }
+
+ /**
+ * Listener for changes in which items have been band selected.
+ */
+ static interface OnSelectionChangedListener {
+ public void onSelectionChanged(SparseBooleanArray updatedSelection);
+ }
+
+ void addOnSelectionChangedListener(OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.add(listener);
+ }
+
+ void removeOnSelectionChangedListener(OnSelectionChangedListener listener) {
+ mOnSelectionChangedListeners.remove(listener);
+ }
+
+ /**
+ * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
+ * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
+ * of item columns and the top- and bottom sides of item rows so that it can be determined
+ * whether the pointer is located within the bounds of an item.
+ */
+ private static class Limits implements Comparable<Limits> {
+ int lowerLimit;
+ int upperLimit;
+
+ Limits(int lowerLimit, int upperLimit) {
+ this.lowerLimit = lowerLimit;
+ this.upperLimit = upperLimit;
+ }
+
+ @Override
+ public int compareTo(Limits other) {
+ return lowerLimit - other.lowerLimit;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Limits)) {
+ return false;
+ }
+
+ return ((Limits) other).lowerLimit == lowerLimit &&
+ ((Limits) other).upperLimit == upperLimit;
+ }
+ }
+
+ /**
+ * The location of a coordinate relative to items. This class represents a general area of the
+ * view as it relates to band selection rather than an explicit point. For example, two
+ * different points within an item are considered to have the same "location" because band
+ * selection originating within the item would select the same items no matter which point
+ * was used. Same goes for points between items as well as those at the very beginning or end
+ * of the view.
+ *
+ * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
+ * advantage of tying the value to the Limits of items along that axis. This allows easy
+ * selection of items within those Limits as opposed to a search through every item to see if a
+ * given coordinate value falls within those Limits.
+ */
+ private static class RelativeCoordinate
+ implements Comparable<RelativeCoordinate> {
+ /**
+ * Location describing points after the last known item.
+ */
+ static final int AFTER_LAST_ITEM = 0;
+
+ /**
+ * Location describing points before the first known item.
+ */
+ static final int BEFORE_FIRST_ITEM = 1;
+
+ /**
+ * Location describing points between two items.
+ */
+ static final int BETWEEN_TWO_ITEMS = 2;
+
+ /**
+ * Location describing points within the limits of one item.
+ */
+ static final int WITHIN_LIMITS = 3;
+
+ /**
+ * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
+ * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
+ */
+ final int type;
+
+ /**
+ * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
+ * BETWEEN_TWO_ITEMS.
+ */
+ Limits limitsBeforeCoordinate;
+
+ /**
+ * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
+ */
+ Limits limitsAfterCoordinate;
+
+ // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
+ Limits mFirstKnownItem;
+ // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
+ Limits mLastKnownItem;
+
+ /**
+ * @param limitsList The sorted limits list for the coordinate type. If this
+ * CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
+ * mYLimitsList should be pased.
+ * @param value The coordinate value.
+ */
+ RelativeCoordinate(List<Limits> limitsList, int value) {
+ int index = Collections.binarySearch(limitsList, new Limits(value, value));
+
+ if (index >= 0) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(index);
+ } else if (~index == 0) {
+ this.type = BEFORE_FIRST_ITEM;
+ this.mFirstKnownItem = limitsList.get(0);
+ } else if (~index == limitsList.size()) {
+ Limits lastLimits = limitsList.get(limitsList.size() - 1);
+ if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = lastLimits;
+ } else {
+ this.type = AFTER_LAST_ITEM;
+ this.mLastKnownItem = lastLimits;
+ }
+ } else {
+ Limits limitsBeforeIndex = limitsList.get(~index - 1);
+ if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
+ this.type = WITHIN_LIMITS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ } else {
+ this.type = BETWEEN_TWO_ITEMS;
+ this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+ this.limitsAfterCoordinate = limitsList.get(~index);
+ }
+ }
+ }
+
+ int toComparisonValue() {
+ if (type == BEFORE_FIRST_ITEM) {
+ return mFirstKnownItem.lowerLimit - 1;
+ } else if (type == AFTER_LAST_ITEM) {
+ return mLastKnownItem.upperLimit + 1;
+ } else if (type == BETWEEN_TWO_ITEMS) {
+ return limitsBeforeCoordinate.upperLimit + 1;
+ } else {
+ return limitsBeforeCoordinate.lowerLimit;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof RelativeCoordinate)) {
+ return false;
+ }
+
+ RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
+ return toComparisonValue() == otherCoordinate.toComparisonValue();
+ }
+
+ @Override
+ public int compareTo(RelativeCoordinate other) {
+ return toComparisonValue() - other.toComparisonValue();
+ }
+ }
+
+ /**
+ * The location of a point relative to the Limits of nearby items; consists of both an x- and
+ * y-RelativeCoordinateLocation.
+ */
+ private class RelativePoint {
+ final RelativeCoordinate xLocation;
+ final RelativeCoordinate yLocation;
+
+ RelativePoint(Point point) {
+ this.xLocation = new RelativeCoordinate(mColumnBounds, point.x);
+ this.yLocation = new RelativeCoordinate(mRowBounds, point.y);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof RelativePoint)) {
+ return false;
+ }
+
+ RelativePoint otherPoint = (RelativePoint) other;
+ return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
+ }
+ }
+
+ /**
+ * Generates a rectangle which contains the items selected by the pointer and origin.
+ * @return The rectangle, or null if no items were selected.
+ */
+ private Rect computeBounds() {
+ Rect rect = new Rect();
+ rect.left = getCoordinateValue(
+ min(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+ mColumnBounds,
+ true);
+ rect.right = getCoordinateValue(
+ max(mRelativeOrigin.xLocation, mRelativePointer.xLocation),
+ mColumnBounds,
+ false);
+ rect.top = getCoordinateValue(
+ min(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+ mRowBounds,
+ true);
+ rect.bottom = getCoordinateValue(
+ max(mRelativeOrigin.yLocation, mRelativePointer.yLocation),
+ mRowBounds,
+ false);
+ return rect;
+ }
+
+ /**
+ * Computes the corner of the selection nearest the origin.
+ * @return
+ */
+ private int computeCornerNearestOrigin() {
+ int cornerValue = 0;
+
+ if (mRelativeOrigin.yLocation ==
+ min(mRelativeOrigin.yLocation, mRelativePointer.yLocation)) {
+ cornerValue |= UPPER;
+ } else {
+ cornerValue |= LOWER;
+ }
+
+ if (mRelativeOrigin.xLocation ==
+ min(mRelativeOrigin.xLocation, mRelativePointer.xLocation)) {
+ cornerValue |= LEFT;
+ } else {
+ cornerValue |= RIGHT;
+ }
+
+ return cornerValue;
+ }
+
+ private RelativeCoordinate min(RelativeCoordinate first, RelativeCoordinate second) {
+ return first.compareTo(second) < 0 ? first : second;
+ }
+
+ private RelativeCoordinate max(RelativeCoordinate first, RelativeCoordinate second) {
+ return first.compareTo(second) > 0 ? first : second;
+ }
+
+ /**
+ * @return The absolute coordinate (i.e., the x- or y-value) of the given relative
+ * coordinate.
+ */
+ private int getCoordinateValue(RelativeCoordinate coordinate,
+ List<Limits> limitsList, boolean isStartOfRange) {
+ switch (coordinate.type) {
+ case RelativeCoordinate.BEFORE_FIRST_ITEM:
+ return limitsList.get(0).lowerLimit;
+ case RelativeCoordinate.AFTER_LAST_ITEM:
+ return limitsList.get(limitsList.size() - 1).upperLimit;
+ case RelativeCoordinate.BETWEEN_TWO_ITEMS:
+ if (isStartOfRange) {
+ return coordinate.limitsAfterCoordinate.lowerLimit;
+ } else {
+ return coordinate.limitsBeforeCoordinate.upperLimit;
+ }
+ case RelativeCoordinate.WITHIN_LIMITS:
+ return coordinate.limitsBeforeCoordinate.lowerLimit;
+ }
+
+ throw new RuntimeException("Invalid coordinate value.");
+ }
+
+ private boolean areItemsCoveredByBand(
+ RelativePoint first, RelativePoint second) {
+ return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
+ doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
+ }
+
+ private boolean doesCoordinateLocationCoverItems(
+ RelativeCoordinate pointerCoordinate,
+ RelativeCoordinate originCoordinate) {
+ if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
+ originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
+ return false;
+ }
+
+ if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+ pointerCoordinate.limitsBeforeCoordinate.equals(
+ originCoordinate.limitsBeforeCoordinate) &&
+ pointerCoordinate.limitsAfterCoordinate.equals(
+ originCoordinate.limitsAfterCoordinate)) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ // TODO: Might have to move this to a more global level. e.g. What should happen if the
+ // user taps a file and then presses shift-down? Currently the RecyclerView never even sees
+ // the key event. Perhaps install a global key handler to catch those events while in
+ // selection mode?
+ @Override
+ public boolean onKey(View view, int keyCode, KeyEvent event) {
+ // Listen for key-down events. This allows the handler to respond appropriately when
+ // the user holds down the arrow keys for navigation.
+ if (event.getAction() != KeyEvent.ACTION_DOWN) {
+ return false;
+ }
+
+ // Here we unpack information from the event and pass it to an more
+ // easily tested method....basically eliminating the need to synthesize
+ // events and views and so on in our tests.
+ int position = findTargetPosition(view, keyCode);
+ if (position == RecyclerView.NO_POSITION) {
+ // If there is no valid navigation target, don't handle the keypress.
+ return false;
+ }
+
+ return attemptChangePosition(position, event.isShiftPressed());
+ }
+
+ @VisibleForTesting
+ boolean attemptChangePosition(int targetPosition, boolean isShiftPressed) {
+ // Focus the new file.
+ mEnvironment.focusItem(targetPosition);
+
+ if (isShiftPressed) {
+ if (!hasSelection()) {
+ // If there is no selection, start a selection when the user presses shift-arrow.
+ toggleSelection(targetPosition);
+ } else if (!mSingleSelect) {
+ mRanger.snapSelection(targetPosition);
+ notifySelectionChanged();
+ } else {
+ // We're in single select and have an existing selection.
+ // Our best guess as to what the user would expect is to advance the selection.
+ clearSelection();
+ toggleSelection(targetPosition);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the adapter position that the key combo is targeted at.
+ */
+ private int findTargetPosition(View view, int keyCode) {
+ int position = RecyclerView.NO_POSITION;
+ if (keyCode == KeyEvent.KEYCODE_MOVE_HOME) {
+ position = 0;
+ } else if (keyCode == KeyEvent.KEYCODE_MOVE_END) {
+ position = mAdapter.getItemCount() - 1;
+ } else {
+ // Find a navigation target based on the arrow key that the user pressed. Ignore
+ // navigation targets that aren't items in the recycler view.
+ int searchDir = -1;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_UP:
+ searchDir = View.FOCUS_UP;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ searchDir = View.FOCUS_DOWN;
+ break;
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ searchDir = View.FOCUS_LEFT;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ searchDir = View.FOCUS_RIGHT;
+ break;
+ }
+ if (searchDir != -1) {
+ View targetView = view.focusSearch(searchDir);
+ // TargetView can be null, for example, if the user pressed <down> at the bottom of
+ // the list.
+ if (targetView != null) {
+ position = mEnvironment.getAdapterPositionForChildView(targetView);
+ }
+ }
+ }
+ return position;
+ }
+}
diff --git a/src/com/android/documentsui/model/DocumentInfo.java b/src/com/android/documentsui/model/DocumentInfo.java
index 5d5f2eb..dfdc705 100644
--- a/src/com/android/documentsui/model/DocumentInfo.java
+++ b/src/com/android/documentsui/model/DocumentInfo.java
@@ -24,8 +24,8 @@
import android.os.Parcelable;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract.Root;
import android.provider.DocumentsProvider;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import com.android.documentsui.DocumentsApplication;
@@ -205,13 +205,18 @@
}
}
- private void deriveFields() {
+ @VisibleForTesting
+ void deriveFields() {
derivedUri = DocumentsContract.buildDocumentUri(authority, documentId);
}
@Override
public String toString() {
- return "Document{docId=" + documentId + ", name=" + displayName + "}";
+ return "Document{"
+ + "docId=" + documentId
+ + ", name=" + displayName
+ + ", isDirectory=" + isDirectory()
+ + "}";
}
public boolean isCreateSupported() {
@@ -238,6 +243,22 @@
return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
}
+ public int hashCode() {
+ return derivedUri.hashCode() + mimeType.hashCode();
+ }
+
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ } else if (!(other instanceof DocumentInfo)) {
+ return false;
+ }
+
+ DocumentInfo that = (DocumentInfo) other;
+ // Uri + mime type should be totally unique.
+ return derivedUri.equals(that.derivedUri) && mimeType.equals(that.mimeType);
+ }
+
public static String getCursorString(Cursor cursor, String columnName) {
final int index = cursor.getColumnIndex(columnName);
return (index != -1) ? cursor.getString(index) : null;
diff --git a/src/com/android/documentsui/model/DurableUtils.java b/src/com/android/documentsui/model/DurableUtils.java
index 2a29cbc..e21dd49 100644
--- a/src/com/android/documentsui/model/DurableUtils.java
+++ b/src/com/android/documentsui/model/DurableUtils.java
@@ -16,7 +16,7 @@
package com.android.documentsui.model;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
import android.os.BadParcelableException;
import android.os.Parcel;
diff --git a/src/com/android/documentsui/model/RootInfo.java b/src/com/android/documentsui/model/RootInfo.java
index ecf4d6c..4caa891 100644
--- a/src/com/android/documentsui/model/RootInfo.java
+++ b/src/com/android/documentsui/model/RootInfo.java
@@ -23,8 +23,10 @@
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;
@@ -44,6 +46,16 @@
private static final int VERSION_INIT = 1;
private static final int VERSION_DROP_TYPE = 2;
+ // The values of these constants determine the sort order of various roots in the RootsFragment.
+ public static final int TYPE_IMAGES = 1;
+ public static final int TYPE_VIDEO = 2;
+ public static final int TYPE_AUDIO = 3;
+ public static final int TYPE_RECENTS = 4;
+ public static final int TYPE_DOWNLOADS = 5;
+ public static final int TYPE_LOCAL = 6;
+ public static final int TYPE_MTP = 7;
+ public static final int TYPE_OTHER = 8;
+
public String authority;
public String rootId;
public int flags;
@@ -57,6 +69,7 @@
/** Derived fields that aren't persisted */
public String[] derivedMimeTypes;
public int derivedIcon;
+ public int derivedType;
public RootInfo() {
reset();
@@ -76,6 +89,7 @@
derivedMimeTypes = null;
derivedIcon = 0;
+ derivedType = 0;
}
@Override
@@ -156,23 +170,48 @@
derivedMimeTypes = (mimeTypes != null) ? mimeTypes.split("\n") : null;
// TODO: remove these special case icons
- if (isExternalStorage()) {
+ if (isHome()) {
+ derivedIcon = R.drawable.ic_root_home;
+ derivedType = TYPE_LOCAL;
+ } else if (isExternalStorage()) {
derivedIcon = R.drawable.ic_root_sdcard;
+ derivedType = TYPE_LOCAL;
} else if (isDownloads()) {
derivedIcon = R.drawable.ic_root_download;
+ derivedType = TYPE_DOWNLOADS;
} else if (isImages()) {
derivedIcon = R.drawable.ic_doc_image;
+ derivedType = TYPE_IMAGES;
} else if (isVideos()) {
derivedIcon = R.drawable.ic_doc_video;
+ derivedType = TYPE_VIDEO;
} else if (isAudio()) {
derivedIcon = R.drawable.ic_doc_audio;
+ derivedType = TYPE_AUDIO;
+ } else if (isRecents()) {
+ derivedType = TYPE_RECENTS;
+ } else if (isMtp()) {
+ derivedType = TYPE_MTP;
+ } else {
+ derivedType = TYPE_OTHER;
}
}
+ public Uri getUri() {
+ return DocumentsContract.buildRootUri(authority, rootId);
+ }
+
public boolean isRecents() {
return authority == null && rootId == null;
}
+ public boolean isHome() {
+ // Note that "home" is the expected root id for the auto-created
+ // user home directory on external storage. The "home" value should
+ // match ExternalStorageProvider.ROOT_ID_HOME.
+ return isExternalStorage() && "home".equals(rootId);
+ }
+
public boolean isExternalStorage() {
return "com.android.externalstorage.documents".equals(authority);
}
@@ -196,9 +235,13 @@
&& "audio_root".equals(rootId);
}
- @Override
- public String toString() {
- return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
+ public boolean isMtp() {
+ return "com.android.mtp.documents".equals(authority);
+ }
+
+ public boolean isLibrary() {
+ return derivedType == TYPE_IMAGES || derivedType == TYPE_VIDEO || derivedType == TYPE_AUDIO
+ || derivedType == TYPE_RECENTS || derivedType == TYPE_DOWNLOADS;
}
public Drawable loadIcon(Context context) {
@@ -217,15 +260,6 @@
}
}
- public Drawable loadGridIcon(Context context) {
- if (derivedIcon != 0) {
- return IconUtils.applyTintAttr(context, derivedIcon,
- android.R.attr.textColorPrimaryInverse);
- } else {
- return IconUtils.loadPackageIcon(context, authority, icon);
- }
- }
-
public Drawable loadToolbarIcon(Context context) {
if (derivedIcon != 0) {
return IconUtils.applyTintAttr(context, derivedIcon,
@@ -250,6 +284,11 @@
return Objects.hash(authority, rootId);
}
+ @Override
+ public String toString() {
+ return "Root{authority=" + authority + ", rootId=" + rootId + ", title=" + title + "}";
+ }
+
public String getDirectoryString() {
return !TextUtils.isEmpty(summary) ? summary : title;
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 3f191a9..b65ac98 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -3,11 +3,12 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
+#LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target guava
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target ub-uiautomator
LOCAL_PACKAGE_NAME := DocumentsUITests
LOCAL_INSTRUMENTATION_FOR := DocumentsUI
@@ -15,3 +16,4 @@
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
+
diff --git a/tests/src/com/android/documentsui/CopyServiceTest.java b/tests/src/com/android/documentsui/CopyServiceTest.java
new file mode 100644
index 0000000..079d599
--- /dev/null
+++ b/tests/src/com/android/documentsui/CopyServiceTest.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.pm.ProviderInfo;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.provider.DocumentsContract;
+import android.test.MoreAsserts;
+import android.test.ServiceTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.model.DocumentStack;
+import com.android.documentsui.model.RootInfo;
+
+import com.google.common.collect.Lists;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@MediumTest
+public class CopyServiceTest extends ServiceTestCase<CopyService> {
+
+ public CopyServiceTest() {
+ super(CopyService.class);
+ }
+
+ private static String AUTHORITY = "com.android.documentsui.stubprovider";
+ private static String SRC_ROOT = StubProvider.ROOT_0_ID;
+ private static String DST_ROOT = StubProvider.ROOT_1_ID;
+ private static String TAG = "CopyTest";
+
+ private Context mContext;
+ private TestContentResolver mResolver;
+ private ContentProviderClient mClient;
+ private DocumentsProviderHelper mDocHelper;
+ private StubProvider mStorage;
+ private Context mSystemContext;
+ private CopyJobListener mListener;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListener = new CopyJobListener();
+ setupTestContext();
+ mClient = mResolver.acquireContentProviderClient(AUTHORITY);
+
+ // Reset the stub provider's storage.
+ mStorage.clearCacheAndBuildRoots();
+
+ mDocHelper = new DocumentsProviderHelper(AUTHORITY, mClient);
+
+ assertDestFileCount(0);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mClient.release();
+ super.tearDown();
+ }
+
+ public void testCopyFile() throws Exception {
+ String srcPath = "/test0.txt";
+ Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
+ "The five boxing wizards jump quickly".getBytes());
+
+ startService(createCopyIntent(Lists.newArrayList(testFile)));
+
+ // 2 operations: file creation, then writing data.
+ mResolver.waitForChanges(2);
+
+ // Verify that one file was copied; check file contents.
+ assertDestFileCount(1);
+ assertCopied(srcPath);
+ }
+
+ public void testMoveFile() throws Exception {
+ String srcPath = "/test0.txt";
+ String testContent = "The five boxing wizards jump quickly";
+ Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain", testContent.getBytes());
+
+ Intent moveIntent = createCopyIntent(Lists.newArrayList(testFile));
+ moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
+ startService(moveIntent);
+
+ // 3 operations: file creation, writing data, deleting original.
+ mResolver.waitForChanges(3);
+
+ // Verify that one file was moved; check file contents.
+ assertDestFileCount(1);
+ assertDoesNotExist(SRC_ROOT, srcPath);
+
+ byte[] dstContent = readFile(DST_ROOT, srcPath);
+ MoreAsserts.assertEquals("Moved file contents differ", testContent.getBytes(), dstContent);
+ }
+
+ public void testCopyMultipleFiles() throws Exception {
+ String testContent[] = {
+ "The five boxing wizards jump quickly",
+ "The quick brown fox jumps over the lazy dog",
+ "Jackdaws love my big sphinx of quartz"
+ };
+ String srcPaths[] = {
+ "/test0.txt",
+ "/test1.txt",
+ "/test2.txt"
+ };
+ List<Uri> testFiles = Lists.newArrayList(
+ mStorage.createFile(SRC_ROOT, srcPaths[0], "text/plain", testContent[0].getBytes()),
+ mStorage.createFile(SRC_ROOT, srcPaths[1], "text/plain", testContent[1].getBytes()),
+ mStorage.createFile(SRC_ROOT, srcPaths[2], "text/plain", testContent[2].getBytes()));
+
+ // Copy all the test files.
+ startService(createCopyIntent(testFiles));
+
+ // 3 file creations, 3 file writes.
+ mResolver.waitForChanges(6);
+
+ assertDestFileCount(3);
+ for (String path : srcPaths) {
+ assertCopied(path);
+ }
+ }
+
+ public void testCopyEmptyDir() throws Exception {
+ String srcPath = "/emptyDir";
+ Uri testDir = createTestDirectory(srcPath);
+
+ startService(createCopyIntent(Lists.newArrayList(testDir)));
+
+ // Just 1 operation: Directory creation.
+ mResolver.waitForChanges(1);
+
+ assertDestFileCount(1);
+
+ // Verify that the dst exists and is a directory.
+ File dst = mStorage.getFile(DST_ROOT, srcPath);
+ assertTrue(dst.isDirectory());
+ }
+
+ public void testNoCopyDirToSelf() throws Exception {
+ Uri testDir = createTestDirectory("/someDir");
+
+ Intent intent = createCopyIntent(Lists.newArrayList(testDir), testDir);
+ startService(intent);
+
+ getService().addFinishedListener(mListener);
+
+ mListener.waitForFinished();
+ mListener.assertFailedCount(1);
+ mListener.assertFileFailed("someDir");
+
+ assertDestFileCount(0);
+ }
+
+ public void testNoCopyDirToDescendent() throws Exception {
+ Uri testDir = createTestDirectory("/someDir");
+ Uri descDir = createTestDirectory("/someDir/theDescendent");
+
+ Intent intent = createCopyIntent(Lists.newArrayList(testDir), descDir);
+ startService(intent);
+
+ getService().addFinishedListener(mListener);
+
+ mListener.waitForFinished();
+ mListener.assertFailedCount(1);
+ mListener.assertFileFailed("someDir");
+
+ assertDestFileCount(0);
+ }
+
+ public void testMoveEmptyDir() throws Exception {
+ String srcPath = "/emptyDir";
+ Uri testDir = createTestDirectory(srcPath);
+
+ Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
+ moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
+ startService(moveIntent);
+
+ // 2 operations: Directory creation, and removal of the original.
+ mResolver.waitForChanges(2);
+
+ assertDestFileCount(1);
+
+ // Verify that the dst exists and is a directory.
+ File dst = mStorage.getFile(DST_ROOT, srcPath);
+ assertTrue(dst.isDirectory());
+
+ // Verify that the src was cleaned up.
+ assertDoesNotExist(SRC_ROOT, srcPath);
+ }
+
+ public void testMovePopulatedDir() throws Exception {
+ String testContent[] = {
+ "The five boxing wizards jump quickly",
+ "The quick brown fox jumps over the lazy dog",
+ "Jackdaws love my big sphinx of quartz"
+ };
+ String srcDir = "/testdir";
+ String srcFiles[] = {
+ srcDir + "/test0.txt",
+ srcDir + "/test1.txt",
+ srcDir + "/test2.txt"
+ };
+ // Create test dir; put some files in it.
+ Uri testDir = createTestDirectory(srcDir);
+ mStorage.createFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
+ mStorage.createFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
+ mStorage.createFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
+
+ Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
+ moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
+ startService(moveIntent);
+
+ // dir creation, then creation and writing of 3 files, then removal of src dir and 3 src
+ // files.
+ mResolver.waitForChanges(11);
+
+ // Check the content of the moved files.
+ File dst = mStorage.getFile(DST_ROOT, srcDir);
+ assertTrue(dst.isDirectory());
+ for (int i = 0; i < testContent.length; ++i) {
+ byte[] dstContent = readFile(DST_ROOT, srcFiles[i]);
+ MoreAsserts.assertEquals("Copied file contents differ", testContent[i].getBytes(),
+ dstContent);
+ }
+
+ // Check that the src files were removed.
+ assertDoesNotExist(SRC_ROOT, srcDir);
+ for (String srcFile : srcFiles) {
+ assertDoesNotExist(SRC_ROOT, srcFile);
+ }
+ }
+
+ public void testCopyFileWithReadErrors() throws Exception {
+ String srcPath = "/test0.txt";
+ Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
+ "The five boxing wizards jump quickly".getBytes());
+
+ mStorage.simulateReadErrorsForFile(testFile);
+
+ startService(createCopyIntent(Lists.newArrayList(testFile)));
+
+ // 3 operations: file creation, writing, then deletion (due to failed copy).
+ mResolver.waitForChanges(3);
+
+ // Verify that the failed copy was cleaned up.
+ assertDestFileCount(0);
+ }
+
+ public void testMoveFileWithReadErrors() throws Exception {
+ String srcPath = "/test0.txt";
+ Uri testFile = mStorage.createFile(SRC_ROOT, srcPath, "text/plain",
+ "The five boxing wizards jump quickly".getBytes());
+
+ mStorage.simulateReadErrorsForFile(testFile);
+
+ Intent moveIntent = createCopyIntent(Lists.newArrayList(testFile));
+ moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
+ startService(moveIntent);
+
+ try {
+ // There should be 3 operations: file creation, writing, then deletion (due to failed
+ // copy). Wait for 4, in case the CopyService also attempts to do extra stuff (like
+ // delete the src file). This should time out.
+ mResolver.waitForChanges(4);
+ } catch (TimeoutException e) {
+ // Success path
+ return;
+ } finally {
+ // Verify that the failed copy was cleaned up, and the src file wasn't removed.
+ assertDestFileCount(0);
+ assertExists(SRC_ROOT, srcPath);
+ }
+ // The asserts above didn't fail, but the CopyService did something unexpected.
+ fail("Extra file operations were detected");
+ }
+
+ public void testMoveDirectoryWithReadErrors() throws Exception {
+ String testContent[] = {
+ "The five boxing wizards jump quickly",
+ "The quick brown fox jumps over the lazy dog",
+ "Jackdaws love my big sphinx of quartz"
+ };
+ String srcDir = "/testdir";
+ String srcFiles[] = {
+ srcDir + "/test0.txt",
+ srcDir + "/test1.txt",
+ srcDir + "/test2.txt"
+ };
+ // Create test dir; put some files in it.
+ Uri testDir = createTestDirectory(srcDir);
+ mStorage.createFile(SRC_ROOT, srcFiles[0], "text/plain", testContent[0].getBytes());
+ Uri errFile = mStorage
+ .createFile(SRC_ROOT, srcFiles[1], "text/plain", testContent[1].getBytes());
+ mStorage.createFile(SRC_ROOT, srcFiles[2], "text/plain", testContent[2].getBytes());
+
+ mStorage.simulateReadErrorsForFile(errFile);
+
+ Intent moveIntent = createCopyIntent(Lists.newArrayList(testDir));
+ moveIntent.putExtra(CopyService.EXTRA_TRANSFER_MODE, CopyService.TRANSFER_MODE_MOVE);
+ startService(moveIntent);
+
+ // - dst dir creation,
+ // - creation and writing of 2 files, removal of 2 src files
+ // - creation and writing of 1 file, then removal of that file (due to error)
+ mResolver.waitForChanges(10);
+
+ // Check that both the src and dst dirs exist. The src dir shouldn't have been removed,
+ // because it should contain the one errFile.
+ assertTrue(mStorage.getFile(SRC_ROOT, srcDir).isDirectory());
+ assertTrue(mStorage.getFile(DST_ROOT, srcDir).isDirectory());
+
+ // Check the content of the moved files.
+ MoreAsserts.assertEquals("Copied file contents differ", testContent[0].getBytes(),
+ readFile(DST_ROOT, srcFiles[0]));
+ MoreAsserts.assertEquals("Copied file contents differ", testContent[2].getBytes(),
+ readFile(DST_ROOT, srcFiles[2]));
+
+ // Check that the src files were removed.
+ assertDoesNotExist(SRC_ROOT, srcFiles[0]);
+ assertDoesNotExist(SRC_ROOT, srcFiles[2]);
+
+ // Check that the error file was not copied over.
+ assertDoesNotExist(DST_ROOT, srcFiles[1]);
+ assertExists(SRC_ROOT, srcFiles[1]);
+ }
+
+ private Uri createTestDirectory(String dir) throws IOException {
+ return mStorage.createFile(
+ SRC_ROOT, dir, DocumentsContract.Document.MIME_TYPE_DIR, null);
+ }
+
+ private Intent createCopyIntent(List<Uri> srcs) throws Exception {
+ RootInfo root = mDocHelper.getRoot(DST_ROOT);
+ final Uri dst = DocumentsContract.buildDocumentUri(AUTHORITY, root.documentId);
+
+ return createCopyIntent(srcs, dst);
+ }
+
+ private Intent createCopyIntent(List<Uri> srcs, Uri dst) throws Exception {
+ final ArrayList<DocumentInfo> srcDocs = Lists.newArrayList();
+ for (Uri src : srcs) {
+ srcDocs.add(DocumentInfo.fromUri(mResolver, src));
+ }
+
+ DocumentStack stack = new DocumentStack();
+ stack.push(DocumentInfo.fromUri(mResolver, dst));
+ final Intent copyIntent = new Intent(mContext, CopyService.class);
+ copyIntent.putParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST, srcDocs);
+ copyIntent.putExtra(Shared.EXTRA_STACK, (Parcelable) stack);
+
+ return copyIntent;
+ }
+
+ /**
+ * Returns a count of the files in the given directory.
+ */
+ private void assertDestFileCount(int expected) throws RemoteException {
+ RootInfo dest = mDocHelper.getRoot(DST_ROOT);
+ final Uri queryUri = DocumentsContract.buildChildDocumentsUri(AUTHORITY,
+ dest.documentId);
+ Cursor c = null;
+ int count = 0;
+ try {
+ c = mClient.query(queryUri, null, null, null, null);
+ count = c.getCount();
+ } finally {
+ IoUtils.closeQuietly(c);
+ }
+ assertEquals("Incorrect file count after copy", expected, count);
+ }
+
+ private void assertExists(String rootId, String path) throws Exception {
+ assertNotNull("An expected file was not found: " + path + " on root " + rootId,
+ mStorage.getFile(rootId, path));
+ }
+
+ private void assertDoesNotExist(String rootId, String path) throws Exception {
+ assertNull("Unexpected file found: " + path + " on root " + rootId,
+ mStorage.getFile(rootId, path));
+ }
+
+ private byte[] readFile(String rootId, String path) throws Exception {
+ File file = mStorage.getFile(rootId, path);
+ byte[] buf = null;
+ assertNotNull(file);
+
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ buf = Streams.readFully(in);
+ } finally {
+ IoUtils.closeQuietly(in);
+ }
+ return buf;
+ }
+
+ private void assertCopied(String path) throws Exception {
+ MoreAsserts.assertEquals("Copied file contents differ", readFile(SRC_ROOT, path),
+ readFile(DST_ROOT, path));
+ }
+
+ /**
+ * Sets up a ContextWrapper that substitutes a stub NotificationManager. This allows the test to
+ * listen for notification events, to gauge copy progress.
+ *
+ * @throws FileNotFoundException
+ */
+ private void setupTestContext() throws FileNotFoundException {
+ mSystemContext = getSystemContext();
+
+ // Set up the context with the test content resolver.
+ mResolver = new TestContentResolver();
+ mContext = new ContextWrapper(mSystemContext) {
+ @Override
+ public ContentResolver getContentResolver() {
+ return mResolver;
+ }
+ };
+ setContext(mContext);
+
+ // Create a local stub provider and add it to the content resolver.
+ ProviderInfo info = new ProviderInfo();
+ info.authority = AUTHORITY;
+ info.exported = true;
+ info.grantUriPermissions = true;
+ info.readPermission = android.Manifest.permission.MANAGE_DOCUMENTS;
+ info.writePermission = android.Manifest.permission.MANAGE_DOCUMENTS;
+
+ mStorage = new StubProvider();
+ mStorage.attachInfo(mContext, info);
+ mResolver.addProvider(AUTHORITY, mStorage);
+ }
+
+ private final class CopyJobListener implements CopyService.TestOnlyListener {
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final List<DocumentInfo> failedDocs = new ArrayList<>();
+ @Override
+ public void onFinished(List<DocumentInfo> failed) {
+ failedDocs.addAll(failed);
+ latch.countDown();
+ }
+
+ public void assertFileFailed(String expectedName) {
+ for (DocumentInfo failed : failedDocs) {
+ if (expectedName.equals(failed.displayName)) {
+ return;
+ }
+ }
+ fail("Couldn't find failed file: " + expectedName);
+ }
+
+ public void waitForFinished() throws InterruptedException {
+ latch.await(500, TimeUnit.MILLISECONDS);
+ }
+
+ public void assertFailedCount(int expected) {
+ assertEquals(expected, failedDocs.size());
+ }
+ }
+
+ /**
+ * A test resolver that enables this test suite to listen for notifications that mark when copy
+ * operations are done.
+ */
+ class TestContentResolver extends MockContentResolver {
+ private CountDownLatch mReadySignal;
+ private CountDownLatch mNotificationSignal;
+
+ public TestContentResolver() {
+ mReadySignal = new CountDownLatch(1);
+ }
+
+ /**
+ * Wait for the given number of files to be copied to destination. Times out after 1 sec.
+ */
+ public void waitForChanges(int count) throws Exception {
+ // Wait for no more than 1 second by default.
+ waitForChanges(count, 1000);
+ }
+
+ /**
+ * Wait for files to be copied to destination.
+ *
+ * @param count Number of files to wait for.
+ * @param timeOut Timeout in ms. TimeoutException will be thrown if this function times out.
+ */
+ public void waitForChanges(int count, int timeOut) throws Exception {
+ mNotificationSignal = new CountDownLatch(count);
+ // Signal that the test is now waiting for files.
+ mReadySignal.countDown();
+ if (!mNotificationSignal.await(timeOut, TimeUnit.MILLISECONDS)) {
+ throw new TimeoutException("Timed out waiting for file operations to complete.");
+ }
+ }
+
+ @Override
+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
+ // Wait until the test is ready to receive file notifications.
+ try {
+ mReadySignal.await();
+ } catch (InterruptedException e) {
+ Log.d(TAG, "Interrupted while waiting for file copy readiness");
+ Thread.currentThread().interrupt();
+ }
+ if (DocumentsContract.isDocumentUri(mContext, uri)) {
+ Log.d(TAG, "Notification: " + uri);
+ // Watch for document URI change notifications - this signifies the end of a copy.
+ mNotificationSignal.countDown();
+ }
+ }
+ };
+}
diff --git a/tests/src/com/android/documentsui/CopyTest.java b/tests/src/com/android/documentsui/CopyTest.java
deleted file mode 100644
index b1c84dd..0000000
--- a/tests/src/com/android/documentsui/CopyTest.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * 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
- *
- * http://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.
- */
-
-package com.android.documentsui;
-
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
-import android.content.pm.ProviderInfo;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.provider.DocumentsContract;
-import android.test.MoreAsserts;
-import android.test.ServiceTestCase;
-import android.test.mock.MockContentResolver;
-import android.util.Log;
-
-import com.android.documentsui.model.DocumentInfo;
-import com.android.documentsui.model.DocumentStack;
-import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Lists;
-
-import libcore.io.IoUtils;
-import libcore.io.Streams;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public class CopyTest extends ServiceTestCase<CopyService> {
-
- /**
- * A test resolver that enables this test suite to listen for notifications that mark when copy
- * operations are done.
- */
- class TestContentResolver extends MockContentResolver {
- private CountDownLatch mReadySignal;
- private CountDownLatch mNotificationSignal;
-
- public TestContentResolver() {
- mReadySignal = new CountDownLatch(1);
- }
-
- /**
- * Wait for the given number of files to be copied to destination. Times out after 1 sec.
- */
- public void waitForChanges(int count) throws Exception {
- // Wait for no more than 1 second by default.
- waitForChanges(count, 1000);
- }
-
- /**
- * Wait for files to be copied to destination.
- *
- * @param count Number of files to wait for.
- * @param timeOut Timeout in ms. TimeoutException will be thrown if this function times out.
- */
- public void waitForChanges(int count, int timeOut) throws Exception {
- mNotificationSignal = new CountDownLatch(count);
- // Signal that the test is now waiting for files.
- mReadySignal.countDown();
- if (!mNotificationSignal.await(timeOut, TimeUnit.MILLISECONDS)) {
- throw new TimeoutException("Timed out waiting for files to be copied.");
- }
- }
-
- @Override
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- // Wait until the test is ready to receive file notifications.
- try {
- mReadySignal.await();
- } catch (InterruptedException e) {
- Log.d(TAG, "Interrupted while waiting for file copy readiness");
- Thread.currentThread().interrupt();
- }
- if (DocumentsContract.isDocumentUri(mContext, uri)) {
- Log.d(TAG, "Notification: " + uri);
- // Watch for document URI change notifications - this signifies the end of a copy.
- mNotificationSignal.countDown();
- }
- }
- };
-
- public CopyTest() {
- super(CopyService.class);
- }
-
- private static String AUTHORITY = "com.android.documentsui.stubprovider";
- private static String DST = "sd1";
- private static String SRC = "sd0";
- private static String TAG = "CopyTest";
- private List<RootInfo> mRoots;
- private Context mContext;
- private TestContentResolver mResolver;
- private ContentProviderClient mClient;
- private StubProvider mStorage;
- private Context mSystemContext;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- setupTestContext();
- mClient = mResolver.acquireContentProviderClient(AUTHORITY);
-
- // Reset the stub provider's storage.
- mStorage.clearCacheAndBuildRoots();
-
- mRoots = Lists.newArrayList();
- Uri queryUri = DocumentsContract.buildRootsUri(AUTHORITY);
- Cursor cursor = null;
- try {
- cursor = mClient.query(queryUri, null, null, null, null);
- while (cursor.moveToNext()) {
- mRoots.add(RootInfo.fromRootsCursor(AUTHORITY, cursor));
- }
- } finally {
- IoUtils.closeQuietly(cursor);
- }
-
- }
-
- @Override
- protected void tearDown() throws Exception {
- mClient.release();
- super.tearDown();
- }
-
- /**
- * Test copying a single file.
- */
- public void testCopyFile() throws Exception {
- String srcPath = "/test0.txt";
- Uri testFile = mStorage.createFile(SRC, srcPath, "text/plain",
- "The five boxing wizards jump quickly".getBytes());
-
- assertDstFileCountEquals(0);
-
- copyToDestination(Lists.newArrayList(testFile));
-
- // 2 operations: file creation, then writing data.
- mResolver.waitForChanges(2);
-
- // Verify that one file was copied; check file contents.
- assertDstFileCountEquals(1);
- assertCopied(srcPath);
- }
-
- /**
- * Test copying multiple files.
- */
- public void testCopyMultipleFiles() throws Exception {
- String testContent[] = {
- "The five boxing wizards jump quickly",
- "The quick brown fox jumps over the lazy dog",
- "Jackdaws love my big sphinx of quartz"
- };
- String srcPaths[] = {
- "/test0.txt",
- "/test1.txt",
- "/test2.txt"
- };
- List<Uri> testFiles = Lists.newArrayList(
- mStorage.createFile(SRC, srcPaths[0], "text/plain", testContent[0].getBytes()),
- mStorage.createFile(SRC, srcPaths[1], "text/plain", testContent[1].getBytes()),
- mStorage.createFile(SRC, srcPaths[2], "text/plain", testContent[2].getBytes()));
-
- assertDstFileCountEquals(0);
-
- // Copy all the test files.
- copyToDestination(testFiles);
-
- // 3 file creations, 3 file writes.
- mResolver.waitForChanges(6);
-
- assertDstFileCountEquals(3);
- for (String path : srcPaths) {
- assertCopied(path);
- }
- }
-
- public void testCopyEmptyDir() throws Exception {
- String srcPath = "/emptyDir";
- Uri testDir = mStorage.createFile(SRC, srcPath, DocumentsContract.Document.MIME_TYPE_DIR,
- null);
-
- assertDstFileCountEquals(0);
-
- copyToDestination(Lists.newArrayList(testDir));
-
- // Just 1 operation: Directory creation.
- mResolver.waitForChanges(1);
-
- assertDstFileCountEquals(1);
-
- File dst = mStorage.getFile(DST, srcPath);
- assertTrue(dst.isDirectory());
- }
-
- public void testReadErrors() throws Exception {
- String srcPath = "/test0.txt";
- Uri testFile = mStorage.createFile(SRC, srcPath, "text/plain",
- "The five boxing wizards jump quickly".getBytes());
-
- assertDstFileCountEquals(0);
-
- mStorage.simulateReadErrors(true);
-
- copyToDestination(Lists.newArrayList(testFile));
-
- // 3 operations: file creation, writing, then deletion (due to failed copy).
- mResolver.waitForChanges(3);
-
- assertDstFileCountEquals(0);
- }
-
- /**
- * Copies the given files to a pre-determined destination.
- *
- * @throws FileNotFoundException
- */
- private void copyToDestination(List<Uri> srcs) throws FileNotFoundException {
- final ArrayList<DocumentInfo> srcDocs = Lists.newArrayList();
- for (Uri src : srcs) {
- srcDocs.add(DocumentInfo.fromUri(mResolver, src));
- }
-
- final Uri dst = DocumentsContract.buildDocumentUri(AUTHORITY, mRoots.get(1).documentId);
- DocumentStack stack = new DocumentStack();
- stack.push(DocumentInfo.fromUri(mResolver, dst));
- final Intent copyIntent = new Intent(mContext, CopyService.class);
- copyIntent.putParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST, srcDocs);
- copyIntent.putExtra(CopyService.EXTRA_STACK, (Parcelable) stack);
-
- startService(copyIntent);
- }
-
- /**
- * Returns a count of the files in the given directory.
- */
- private void assertDstFileCountEquals(int expected) throws RemoteException {
- final Uri queryUri = DocumentsContract.buildChildDocumentsUri(AUTHORITY,
- mRoots.get(1).documentId);
- Cursor c = null;
- int count = 0;
- try {
- c = mClient.query(queryUri, null, null, null, null);
- count = c.getCount();
- } finally {
- IoUtils.closeQuietly(c);
- }
- assertEquals("Incorrect file count after copy", expected, count);
- }
-
- private void assertCopied(String path) throws Exception {
- File srcFile = mStorage.getFile(SRC, path);
- File dstFile = mStorage.getFile(DST, path);
- assertNotNull(dstFile);
-
- FileInputStream src = null;
- FileInputStream dst = null;
- try {
- src = new FileInputStream(srcFile);
- dst = new FileInputStream(dstFile);
- byte[] srcbuf = Streams.readFully(src);
- byte[] dstbuf = Streams.readFully(dst);
-
- MoreAsserts.assertEquals(srcbuf, dstbuf);
- } finally {
- IoUtils.closeQuietly(src);
- IoUtils.closeQuietly(dst);
- }
- }
-
- /**
- * Sets up a ContextWrapper that substitutes a stub NotificationManager. This allows the test to
- * listen for notification events, to gauge copy progress.
- *
- * @throws FileNotFoundException
- */
- private void setupTestContext() throws FileNotFoundException {
- mSystemContext = getSystemContext();
-
- // Set up the context with the test content resolver.
- mResolver = new TestContentResolver();
- mContext = new ContextWrapper(mSystemContext) {
- @Override
- public ContentResolver getContentResolver() {
- return mResolver;
- }
- };
- setContext(mContext);
-
- // Create a local stub provider and add it to the content resolver.
- ProviderInfo info = new ProviderInfo();
- info.authority = AUTHORITY;
- info.exported = true;
- info.grantUriPermissions = true;
- info.readPermission = android.Manifest.permission.MANAGE_DOCUMENTS;
- info.writePermission = android.Manifest.permission.MANAGE_DOCUMENTS;
-
- mStorage = new StubProvider();
- mStorage.attachInfo(mContext, info);
- mResolver.addProvider(AUTHORITY, mStorage);
- }
-}
diff --git a/tests/src/com/android/documentsui/DocumentsProviderHelper.java b/tests/src/com/android/documentsui/DocumentsProviderHelper.java
new file mode 100644
index 0000000..7abc99c
--- /dev/null
+++ b/tests/src/com/android/documentsui/DocumentsProviderHelper.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.model.DocumentInfo.getCursorString;
+
+import android.content.ContentProviderClient;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.DocumentsContract;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+
+import com.android.documentsui.model.RootInfo;
+
+import libcore.io.IoUtils;
+
+/**
+ * Provides support for creation of documents in a test settings.
+ */
+public class DocumentsProviderHelper {
+
+ private final ContentProviderClient mClient;
+ private final String mAuthority;
+
+ public DocumentsProviderHelper(String authority, ContentProviderClient client) {
+ mClient = client;
+ mAuthority = authority;
+ }
+
+ public RootInfo getRoot(String id) throws RemoteException {
+ final Uri rootsUri = DocumentsContract.buildRootsUri(mAuthority);
+
+ Cursor cursor = null;
+ try {
+ cursor = mClient.query(rootsUri, null, null, null, null);
+ while (cursor.moveToNext()) {
+ if (id.equals(getCursorString(cursor, Root.COLUMN_ROOT_ID))) {
+ return RootInfo.fromRootsCursor(mAuthority, cursor);
+ }
+ }
+ throw new IllegalArgumentException("Can't find matching root for id=" + id);
+ } catch (Exception e) {
+ throw new RuntimeException("Can't load root for id=" + id , e);
+ } finally {
+ IoUtils.closeQuietly(cursor);
+ }
+ }
+
+ public Uri createDocument(Uri parentUri, String mimeType, String name) {
+ if (name.contains("/")) {
+ throw new IllegalArgumentException("Name and mimetype probably interposed.");
+ }
+ try {
+ return DocumentsContract.createDocument(mClient, parentUri, mimeType, name);
+ } catch (RemoteException e) {
+ throw new RuntimeException("Couldn't create document: " + name + " with mimetype " + mimeType, e);
+ }
+ }
+
+ public Uri createFolder(Uri parentUri, String name) {
+ return createDocument(parentUri, Document.MIME_TYPE_DIR, name);
+ }
+
+ public Uri createDocument(RootInfo root, String mimeType, String name) {
+ Uri rootUri = DocumentsContract.buildDocumentUri(mAuthority, root.documentId);
+ return createDocument(rootUri, mimeType, name);
+ }
+
+ public Uri createFolder(RootInfo root, String name) {
+ return createDocument(root, Document.MIME_TYPE_DIR, name);
+ }
+}
diff --git a/tests/src/com/android/documentsui/DownloadsActivityUiTest.java b/tests/src/com/android/documentsui/DownloadsActivityUiTest.java
new file mode 100644
index 0000000..737a8b6
--- /dev/null
+++ b/tests/src/com/android/documentsui/DownloadsActivityUiTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+
+import android.app.Instrumentation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.provider.DocumentsContract;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.model.RootInfo;
+
+@LargeTest
+public class DownloadsActivityUiTest extends InstrumentationTestCase {
+
+ private static final int TIMEOUT = 5000;
+ private static final String TAG = "DownloadsActivityUiTest";
+ private static final String TARGET_PKG = "com.android.documentsui";
+ private static final String LAUNCHER_PKG = "com.android.launcher";
+
+ private UiBot mBot;
+ private UiDevice mDevice;
+ private Context mContext;
+ private ContentResolver mResolver;
+ private DocumentsProviderHelper mDocsHelper;
+ private ContentProviderClient mClient;
+ private RootInfo mRoot;
+
+ public void setUp() throws Exception {
+ // Initialize UiDevice instance.
+ Instrumentation instrumentation = getInstrumentation();
+
+ mDevice = UiDevice.getInstance(instrumentation);
+
+ Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
+
+ // Start from the home screen.
+ mDevice.pressHome();
+ mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
+
+ // NOTE: Must be the "target" context, else security checks in content provider will fail.
+ mContext = instrumentation.getTargetContext();
+ mResolver = mContext.getContentResolver();
+
+ mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
+ mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
+
+ mRoot = mDocsHelper.getRoot(ROOT_0_ID);
+
+ // Open the Downloads activity on our stub provider root.
+ Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT);
+ intent.setDataAndType(mRoot.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait for the app to appear.
+ mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
+ mDevice.waitForIdle();
+
+ mBot = new UiBot(mDevice, TIMEOUT);
+
+ resetStorage(); // Just in case a test failed and tearDown didn't happen.
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Need to kill off the task we started.
+ super.tearDown();
+ Log.d(TAG, "Resetting storage from setUp");
+ resetStorage();
+ mClient.release();
+ }
+
+ private void resetStorage() throws RemoteException {
+ mClient.call("clear", null, null);
+ // TODO: Would be nice to have an event to wait on here.
+ mDevice.waitForIdle();
+ }
+
+ private void initTestFiles() throws RemoteException {
+ mDocsHelper.createDocument(mRoot, "text/plain", "file0.log");
+ mDocsHelper.createDocument(mRoot, "image/png", "file1.png");
+ mDocsHelper.createDocument(mRoot, "text/csv", "file2.csv");
+ }
+
+ public void testWindowTitle() throws Exception {
+ initTestFiles();
+
+ mBot.assertWindowTitle(ROOT_0_ID);
+ }
+
+ public void testFilesListed() throws Exception {
+ initTestFiles();
+
+ mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
+ }
+
+ public void testFilesList_LiveUpdate() throws Exception {
+ initTestFiles();
+
+ mDocsHelper.createDocument(mRoot, "yummers/sandwich", "Ham & Cheese.sandwich");
+ mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
+ }
+
+ public void testDeleteDocument() throws Exception {
+ initTestFiles();
+
+ mBot.clickDocument("file1.png");
+ mDevice.waitForIdle();
+ mBot.menuDelete().click();
+
+ mBot.waitForDeleteSnackbar();
+ assertFalse(mBot.hasDocuments("file1.png"));
+
+ mBot.waitForDeleteSnackbarGone();
+ assertFalse(mBot.hasDocuments("file1.png"));
+ }
+
+ public void testSupportsShare() throws Exception {
+ initTestFiles();
+
+ mBot.clickDocument("file1.png");
+ mDevice.waitForIdle();
+ assertNotNull(mBot.menuShare());
+ }
+}
diff --git a/tests/src/com/android/documentsui/FilesActivityUiTest.java b/tests/src/com/android/documentsui/FilesActivityUiTest.java
new file mode 100644
index 0000000..71d8b34
--- /dev/null
+++ b/tests/src/com/android/documentsui/FilesActivityUiTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static com.android.documentsui.StubProvider.DEFAULT_AUTHORITY;
+import static com.android.documentsui.StubProvider.ROOT_0_ID;
+import static com.android.documentsui.StubProvider.ROOT_1_ID;
+
+import android.app.Instrumentation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.RemoteException;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Configurator;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.documentsui.model.RootInfo;
+
+@LargeTest
+public class FilesActivityUiTest extends InstrumentationTestCase {
+
+ private static final int TIMEOUT = 5000;
+ private static final String TAG = "FilesActivityUiTest";
+ private static final String TARGET_PKG = "com.android.documentsui";
+ private static final String LAUNCHER_PKG = "com.android.launcher";
+
+ private UiBot mBot;
+ private UiDevice mDevice;
+ private Context mContext;
+ private ContentResolver mResolver;
+ private DocumentsProviderHelper mDocsHelper;
+ private ContentProviderClient mClient;
+ private RootInfo mRoot_0;
+ private RootInfo mRoot_1;
+
+ public void setUp() throws Exception {
+ // Initialize UiDevice instance.
+ Instrumentation instrumentation = getInstrumentation();
+
+ mDevice = UiDevice.getInstance(instrumentation);
+
+ Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
+
+ // Start from the home screen.
+ mDevice.pressHome();
+ mDevice.wait(Until.hasObject(By.pkg(LAUNCHER_PKG).depth(0)), TIMEOUT);
+
+ // NOTE: Must be the "target" context, else security checks in content provider will fail.
+ mContext = instrumentation.getTargetContext();
+ mResolver = mContext.getContentResolver();
+
+ mClient = mResolver.acquireUnstableContentProviderClient(DEFAULT_AUTHORITY);
+ mDocsHelper = new DocumentsProviderHelper(DEFAULT_AUTHORITY, mClient);
+
+ // Launch app.
+ Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(TARGET_PKG);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ mContext.startActivity(intent);
+
+ // Wait for the app to appear.
+ mDevice.wait(Until.hasObject(By.pkg(TARGET_PKG).depth(0)), TIMEOUT);
+ mDevice.waitForIdle();
+
+ mBot = new UiBot(mDevice, TIMEOUT);
+
+ resetStorage(); // Just incase a test failed and tearDown didn't happen.
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ Log.d(TAG, "Resetting storage from setUp");
+ resetStorage();
+ mClient.release();
+ }
+
+ private void resetStorage() throws RemoteException {
+ mClient.call("clear", null, null);
+ // TODO: Would be nice to have an event to wait on here.
+ mDevice.waitForIdle();
+ }
+
+ private void initTestFiles() throws RemoteException {
+ mRoot_0 = mDocsHelper.getRoot(ROOT_0_ID);
+ mRoot_1 = mDocsHelper.getRoot(ROOT_1_ID);
+
+ mDocsHelper.createDocument(mRoot_0, "text/plain", "file0.log");
+ mDocsHelper.createDocument(mRoot_0, "image/png", "file1.png");
+ mDocsHelper.createDocument(mRoot_0, "text/csv", "file2.csv");
+
+ mDocsHelper.createDocument(mRoot_1, "text/plain", "anotherFile0.log");
+ mDocsHelper.createDocument(mRoot_1, "text/plain", "poodles.text");
+ }
+
+ public void testRootsListed() throws Exception {
+ initTestFiles();
+
+ mBot.openRoot(ROOT_0_ID);
+
+ // Should also have Drive, but that requires pre-configuration of devices
+ // We omit for now.
+ mBot.assertHasRoots(
+ "Images",
+ "Videos",
+ "Audio",
+ "Downloads",
+ "Home",
+ ROOT_0_ID,
+ ROOT_1_ID);
+ }
+
+ public void testFilesListed() throws Exception {
+ initTestFiles();
+
+ mBot.openRoot(ROOT_0_ID);
+ mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv");
+ }
+
+ public void testRootClickSetsWindowTitle() throws Exception {
+ initTestFiles();
+
+ mBot.openRoot("Home");
+ mBot.assertWindowTitle("Home");
+ }
+
+ public void testFilesList_LiveUpdate() throws Exception {
+ initTestFiles();
+
+ mBot.openRoot(ROOT_0_ID);
+ mDocsHelper.createDocument(mRoot_0, "yummers/sandwich", "Ham & Cheese.sandwich");
+ mBot.assertHasDocuments("file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich");
+ }
+
+ public void testDeleteDocument() throws Exception {
+ initTestFiles();
+
+ mBot.openRoot(ROOT_0_ID);
+
+ mBot.clickDocument("file1.png");
+ mDevice.waitForIdle();
+ mBot.menuDelete().click();
+
+ mBot.waitForDeleteSnackbar();
+ assertFalse(mBot.hasDocuments("file1.png"));
+
+ mBot.waitForDeleteSnackbarGone();
+ assertFalse(mBot.hasDocuments("file1.png"));
+
+ // Now delete from another root.
+ mBot.openRoot(ROOT_1_ID);
+
+ mBot.clickDocument("poodles.text");
+ mDevice.waitForIdle();
+ mBot.menuDelete().click();
+
+ mBot.waitForDeleteSnackbar();
+ assertFalse(mBot.hasDocuments("poodles.text"));
+
+ mBot.waitForDeleteSnackbarGone();
+ assertFalse(mBot.hasDocuments("poodles.text"));
+ }
+}
diff --git a/tests/src/com/android/documentsui/RootsCacheTest.java b/tests/src/com/android/documentsui/RootsCacheTest.java
index 8c5bac1..7d3498e 100644
--- a/tests/src/com/android/documentsui/RootsCacheTest.java
+++ b/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -19,9 +19,9 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
+
+import com.google.common.collect.Lists;
import java.util.List;
diff --git a/tests/src/com/android/documentsui/StubProvider.java b/tests/src/com/android/documentsui/StubProvider.java
index 8cef433..7a75503 100644
--- a/tests/src/com/android/documentsui/StubProvider.java
+++ b/tests/src/com/android/documentsui/StubProvider.java
@@ -36,8 +36,6 @@
import android.support.annotation.VisibleForTesting;
import android.util.Log;
-import com.google.android.collect.Maps;
-
import libcore.io.IoUtils;
import java.io.File;
@@ -52,12 +50,17 @@
import java.util.Map;
public class StubProvider extends DocumentsProvider {
+
+ public static final String DEFAULT_AUTHORITY = "com.android.documentsui.stubprovider";
+ public static final String ROOT_0_ID = "TEST_ROOT_0";
+ public static final String ROOT_1_ID = "TEST_ROOT_1";
+
+ private static final String TAG = "StubProvider";
private static final String EXTRA_SIZE = "com.android.documentsui.stubprovider.SIZE";
private static final String EXTRA_ROOT = "com.android.documentsui.stubprovider.ROOT";
private static final String STORAGE_SIZE_KEY = "documentsui.stubprovider.size";
- private static int DEFAULT_SIZE = 1024 * 1024; // 1 MB.
- private static final String TAG = "StubProvider";
- private static final String MY_ROOT_ID = "sd0";
+ private static int DEFAULT_ROOT_SIZE = 1024 * 1024 * 100; // 100 MB.
+
private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID,
Root.COLUMN_AVAILABLE_BYTES
@@ -67,12 +70,13 @@
Document.COLUMN_LAST_MODIFIED, Document.COLUMN_FLAGS, Document.COLUMN_SIZE,
};
- private HashMap<String, StubDocument> mStorage = new HashMap<String, StubDocument>();
- private Object mWriteLock = new Object();
- private String mAuthority;
+ private final Map<String, StubDocument> mStorage = new HashMap<>();
+ private final Map<String, RootInfo> mRoots = new HashMap<>();
+ private final Object mWriteLock = new Object();
+
+ private String mAuthority = DEFAULT_AUTHORITY;
private SharedPreferences mPrefs;
- private Map<String, RootInfo> mRoots;
- private boolean mSimulateReadErrors;
+ private String mSimulateReadErrors;
@Override
public void attachInfo(Context context, ProviderInfo info) {
@@ -88,20 +92,18 @@
@VisibleForTesting
public void clearCacheAndBuildRoots() {
- final File cacheDir = getContext().getCacheDir();
- removeRecursively(cacheDir);
+ Log.d(TAG, "Resetting storage.");
+ removeChildrenRecursively(getContext().getCacheDir());
mStorage.clear();
mPrefs = getContext().getSharedPreferences(
"com.android.documentsui.stubprovider.preferences", Context.MODE_PRIVATE);
Collection<String> rootIds = mPrefs.getStringSet("roots", null);
if (rootIds == null) {
- rootIds = Arrays.asList(new String[] {
- "sd0", "sd1"
- });
+ rootIds = Arrays.asList(new String[] { ROOT_0_ID, ROOT_1_ID });
}
- // Create new roots.
- mRoots = Maps.newHashMap();
+
+ mRoots.clear();
for (String rootId : rootIds) {
final RootInfo rootInfo = new RootInfo(rootId, getSize(rootId));
mRoots.put(rootId, rootInfo);
@@ -113,7 +115,7 @@
*/
private long getSize(String rootId) {
final String key = STORAGE_SIZE_KEY + "." + rootId;
- return mPrefs.getLong(key, DEFAULT_SIZE);
+ return mPrefs.getLong(key, DEFAULT_ROOT_SIZE);
}
@Override
@@ -127,7 +129,7 @@
row.add(Root.COLUMN_ROOT_ID, id);
row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD);
row.add(Root.COLUMN_TITLE, id);
- row.add(Root.COLUMN_DOCUMENT_ID, info.rootDocument.documentId);
+ row.add(Root.COLUMN_DOCUMENT_ID, info.document.documentId);
row.add(Root.COLUMN_AVAILABLE_BYTES, info.getRemainingCapacity());
}
return result;
@@ -154,28 +156,49 @@
}
@Override
- public String createDocument(String parentDocumentId, String mimeType, String displayName)
+ public String createDocument(String parentId, String mimeType, String displayName)
throws FileNotFoundException {
- final StubDocument parentDocument = mStorage.get(parentDocumentId);
- if (parentDocument == null || !parentDocument.file.isDirectory()) {
- throw new FileNotFoundException();
+
+ final StubDocument parent = mStorage.get(parentId);
+ if (parent == null) {
+ throw new IllegalArgumentException(
+ "Can't create file " + displayName + " in null parent.");
}
- final File file = new File(parentDocument.file, displayName);
- if (mimeType.equals(Document.MIME_TYPE_DIR)) {
- if (!file.mkdirs()) {
- throw new FileNotFoundException();
- }
- } else {
- try {
- if (!file.createNewFile()) {
- throw new IllegalStateException("The file " + file.getPath() + " already exists");
- }
- } catch (IOException e) {
- throw new FileNotFoundException();
- }
+ if (!parent.file.isDirectory()) {
+ throw new IllegalArgumentException(
+ "Can't create file " + displayName + " inside non-directory parent "
+ + parent.file.getName());
}
- final StubDocument document = new StubDocument(file, mimeType, parentDocument);
+ final File file = new File(parent.file, displayName);
+ if (file.exists()) {
+ throw new FileNotFoundException(
+ "Duplicate file names not supported for " + file);
+ }
+
+ if (mimeType.equals(Document.MIME_TYPE_DIR)) {
+ if (!file.mkdirs()) {
+ throw new FileNotFoundException(
+ "Failed to create directory(s): " + file);
+ }
+ Log.i(TAG, "Created new directory: " + file);
+ } else {
+ boolean created = false;
+ try {
+ created = file.createNewFile();
+ } catch (IOException e) {
+ // We'll throw an FNF exception later :)
+ Log.e(TAG, "createnewFile operation failed for file: " + file, e);
+ }
+ if (!created) {
+ throw new FileNotFoundException(
+ "createNewFile operation failed for: " + file);
+ }
+ Log.i(TAG, "Created new file: " + file);
+ }
+
+ final StubDocument document = new StubDocument(file, mimeType, parent);
+ Log.d(TAG, "Created document " + document.documentId);
notifyParentChanged(document.parentId);
getContext().getContentResolver().notifyChange(
DocumentsContract.buildDocumentUri(mAuthority, document.documentId),
@@ -193,7 +216,9 @@
throw new FileNotFoundException();
synchronized (mWriteLock) {
document.rootInfo.size -= fileSize;
+ mStorage.remove(documentId);
}
+ Log.d(TAG, "Document deleted: " + documentId);
notifyParentChanged(document.parentId);
getContext().getContentResolver().notifyChange(
DocumentsContract.buildDocumentUri(mAuthority, document.documentId),
@@ -201,6 +226,12 @@
}
@Override
+ public Cursor queryChildDocumentsForManage(String parentDocumentId, String[] projection,
+ String sortOrder) throws FileNotFoundException {
+ return queryChildDocuments(parentDocumentId, projection, sortOrder);
+ }
+
+ @Override
public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder)
throws FileNotFoundException {
final StubDocument parentDocument = mStorage.get(parentDocumentId);
@@ -239,7 +270,7 @@
if ("r".equals(mode)) {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(document.file,
ParcelFileDescriptor.MODE_READ_ONLY);
- if (mSimulateReadErrors) {
+ if (docId.equals(mSimulateReadErrors)) {
pfd = new ParcelFileDescriptor(pfd) {
@Override
public void checkError() throws IOException {
@@ -257,8 +288,8 @@
}
@VisibleForTesting
- public void simulateReadErrors(boolean b) {
- mSimulateReadErrors = b;
+ public void simulateReadErrorsForFile(Uri uri) {
+ mSimulateReadErrors = DocumentsContract.getDocumentId(uri);
}
@Override
@@ -284,6 +315,7 @@
InputStream inputStream = null;
OutputStream outputStream = null;
try {
+ Log.d(TAG, "Opening write stream on file " + document.documentId);
inputStream = new ParcelFileDescriptor.AutoCloseInputStream(readPipe);
outputStream = new FileOutputStream(document.file);
byte[] buffer = new byte[32 * 1024];
@@ -312,6 +344,7 @@
} finally {
IoUtils.closeQuietly(inputStream);
IoUtils.closeQuietly(outputStream);
+ Log.d(TAG, "Closing write stream on file " + document.documentId);
notifyParentChanged(document.parentId);
getContext().getContentResolver().notifyChange(
DocumentsContract.buildDocumentUri(mAuthority, document.documentId),
@@ -346,7 +379,7 @@
private void configure(String arg, Bundle extras) {
Log.d(TAG, "Configure " + arg);
- String rootName = extras.getString(EXTRA_ROOT, MY_ROOT_ID);
+ String rootName = extras.getString(EXTRA_ROOT, ROOT_0_ID);
long rootSize = extras.getLong(EXTRA_SIZE, 1) * 1024 * 1024;
setSize(rootName, rootSize);
}
@@ -376,10 +409,10 @@
row.add(Document.COLUMN_LAST_MODIFIED, document.file.lastModified());
}
- private void removeRecursively(File file) {
+ private void removeChildrenRecursively(File file) {
for (File childFile : file.listFiles()) {
if (childFile.isDirectory()) {
- removeRecursively(childFile);
+ removeChildrenRecursively(childFile);
}
childFile.delete();
}
@@ -408,7 +441,8 @@
@VisibleForTesting
public Uri createFile(String rootId, String path, String mimeType, byte[] content)
throws FileNotFoundException, IOException {
- StubDocument root = mRoots.get(rootId).rootDocument;
+ Log.d(TAG, "Creating test file " + rootId + ":" + path);
+ StubDocument root = mRoots.get(rootId).document;
if (root == null) {
throw new FileNotFoundException("No roots with the ID " + rootId + " were found");
}
@@ -417,6 +451,9 @@
if (parent == null) {
parent = mStorage.get(createFile(rootId, file.getParentFile().getPath(),
DocumentsContract.Document.MIME_TYPE_DIR, null));
+ Log.d(TAG, "Created parent " + parent.documentId);
+ } else {
+ Log.d(TAG, "Found parent " + parent.documentId);
}
if (DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType)) {
@@ -438,7 +475,7 @@
@VisibleForTesting
public File getFile(String rootId, String path) throws FileNotFoundException {
- StubDocument root = mRoots.get(rootId).rootDocument;
+ StubDocument root = mRoots.get(rootId).document;
if (root == null) {
throw new FileNotFoundException("No roots with the ID " + rootId + " were found");
}
@@ -454,7 +491,7 @@
final class RootInfo {
public final String name;
- public final StubDocument rootDocument;
+ public final StubDocument document;
public long capacity;
public long size;
@@ -462,9 +499,11 @@
this.name = name;
this.capacity = 1024 * 1024;
// Make a subdir in the cache dir for each root.
- File rootDir = new File(getContext().getCacheDir(), name);
- rootDir.mkdir();
- this.rootDocument = new StubDocument(rootDir, Document.MIME_TYPE_DIR, this);
+ File file = new File(getContext().getCacheDir(), name);
+ if (file.mkdir()) {
+ Log.i(TAG, "Created new root directory @ " + file.getPath());
+ }
+ this.document = new StubDocument(file, Document.MIME_TYPE_DIR, this);
this.capacity = capacity;
this.size = 0;
}
@@ -498,6 +537,16 @@
this.rootInfo = rootInfo;
mStorage.put(this.documentId, this);
}
+ @Override
+ public String toString() {
+ return "StubDocument{"
+ + "path:" + file.getPath()
+ + ", mimeType:" + mimeType
+ + ", rootInfo:" + rootInfo
+ + ", documentId:" + documentId
+ + ", parentId:" + parentId
+ + "}";
+ }
}
private static String getDocumentIdForFile(File file) {
diff --git a/tests/src/com/android/documentsui/TestInputEvent.java b/tests/src/com/android/documentsui/TestInputEvent.java
new file mode 100644
index 0000000..ec5321a
--- /dev/null
+++ b/tests/src/com/android/documentsui/TestInputEvent.java
@@ -0,0 +1,90 @@
+package com.android.documentsui;
+
+import android.graphics.Point;
+import android.support.v7.widget.RecyclerView;
+
+public class TestInputEvent implements Events.InputEvent {
+
+ public boolean mouseEvent;
+ public boolean primaryButtonPressed;
+ public boolean secondaryButtonPressed;
+ public boolean shiftKeyDow;
+ public boolean actionDown;
+ public boolean actionUp;
+ public Point location;
+ public int position = Integer.MIN_VALUE;
+
+ public TestInputEvent() {}
+
+ public TestInputEvent(int position) {
+ this.position = position;
+ }
+
+ @Override
+ public boolean isMouseEvent() {
+ return mouseEvent;
+ }
+
+ @Override
+ public boolean isPrimaryButtonPressed() {
+ return primaryButtonPressed;
+ }
+
+ @Override
+ public boolean isSecondaryButtonPressed() {
+ return secondaryButtonPressed;
+ }
+
+ @Override
+ public boolean isShiftKeyDown() {
+ return shiftKeyDow;
+ }
+
+ @Override
+ public boolean isActionDown() {
+ return actionDown;
+ }
+
+ @Override
+ public boolean isActionUp() {
+ return actionUp;
+ }
+
+ @Override
+ public Point getOrigin() {
+ return location;
+ }
+
+ @Override
+ public boolean isOverItem() {
+ return position != Integer.MIN_VALUE && position != RecyclerView.NO_POSITION;
+ }
+
+ @Override
+ public int getItemPosition() {
+ return position;
+ }
+
+ public static TestInputEvent tap(int position) {
+ return new TestInputEvent(position);
+ }
+
+ public static TestInputEvent shiftTap(int position) {
+ TestInputEvent e = new TestInputEvent(position);
+ e.shiftKeyDow = true;
+ return e;
+ }
+
+ public static TestInputEvent click(int position) {
+ TestInputEvent e = new TestInputEvent(position);
+ e.mouseEvent = true;
+ return e;
+ }
+
+ public static TestInputEvent shiftClick(int position) {
+ TestInputEvent e = new TestInputEvent(position);
+ e.mouseEvent = true;
+ e.shiftKeyDow = true;
+ return e;
+ }
+}
diff --git a/tests/src/com/android/documentsui/UiBot.java b/tests/src/com/android/documentsui/UiBot.java
new file mode 100644
index 0000000..68cdf12
--- /dev/null
+++ b/tests/src/com/android/documentsui/UiBot.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * A test helper class that provides support for controlling DocumentsUI activities
+ * programmatically, and making assertions against the state of the UI.
+ */
+class UiBot {
+
+ private static final String TAG = "UiBot";
+
+ private static final BySelector SNACK_DELETE =
+ By.desc(Pattern.compile("^Deleting [0-9]+ file.+"));
+
+ private UiDevice mDevice;
+ private int mTimeout;
+
+ public UiBot(UiDevice device, int timeout) {
+ mDevice = device;
+ mTimeout = timeout;
+ }
+
+ UiObject findRoot(String label) throws UiObjectNotFoundException {
+ final UiSelector rootsList = new UiSelector().resourceId(
+ "com.android.documentsui:id/container_roots").childSelector(
+ new UiSelector().resourceId("android:id/list"));
+
+ // We might need to expand drawer if not visible
+ if (!new UiObject(rootsList).waitForExists(mTimeout)) {
+ Log.d(TAG, "Failed to find roots list; trying to expand");
+ final UiSelector hamburger = new UiSelector().resourceId(
+ "com.android.documentsui:id/toolbar").childSelector(
+ new UiSelector().className("android.widget.ImageButton").clickable(true));
+ new UiObject(hamburger).click();
+ }
+
+ // Wait for the first list item to appear
+ new UiObject(rootsList.childSelector(new UiSelector())).waitForExists(mTimeout);
+
+ // Now scroll around to find our item
+ new UiScrollable(rootsList).scrollIntoView(new UiSelector().text(label));
+ return new UiObject(rootsList.childSelector(new UiSelector().text(label)));
+ }
+
+ void openRoot(String label) throws UiObjectNotFoundException {
+ findRoot(label).click();
+ mDevice.waitForIdle();
+ }
+
+ void assertWindowTitle(String expected) {
+ // Turns out the title field on a window does not have
+ // an id associated with it at runtime (which confuses the hell out of me)
+ // In code we address this via "android.R.id.title".
+ UiObject2 o = find(By.text(expected));
+ // It's a bit of a conceit that we then *assert* that the title
+ // is the value that we used to identify the UiObject2.
+ // If the preceeding lookup fails, this'll choke with an NPE.
+ // But given the issue described in the comment above, we're
+ // going to do it anyway. Because we shouldn't be looking up
+ // the uiobject by it's expected content :|
+ assertEquals(expected, o.getText());
+ }
+
+ void assertHasRoots(String... labels) throws UiObjectNotFoundException {
+ List<String> missing = new ArrayList<>();
+ for (String label : labels) {
+ if (!findRoot(label).exists()) {
+ missing.add(label);
+ }
+ }
+ if (!missing.isEmpty()) {
+ Assert.fail(
+ "Expected roots " + Arrays.asList(labels) + ", but missing " + missing);
+ }
+ }
+
+ UiObject findDocument(String label) throws UiObjectNotFoundException {
+ final UiSelector docList = new UiSelector().resourceId(
+ "com.android.documentsui:id/container_directory").childSelector(
+ new UiSelector().resourceId("com.android.documentsui:id/list"));
+
+ // Wait for the first list item to appear
+ new UiObject(docList.childSelector(new UiSelector())).waitForExists(mTimeout);
+
+ // new UiScrollable(docList).scrollIntoView(new UiSelector().text(label));
+ return mDevice.findObject(docList.childSelector(new UiSelector().text(label)));
+ }
+
+ boolean hasDocuments(String... labels) throws UiObjectNotFoundException {
+ for (String label : labels) {
+ if (!findDocument(label).exists()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void assertHasDocuments(String... labels) throws UiObjectNotFoundException {
+ List<String> missing = new ArrayList<>();
+ for (String label : labels) {
+ if (!findDocument(label).exists()) {
+ missing.add(label);
+ }
+ }
+ if (!missing.isEmpty()) {
+ Assert.fail(
+ "Expected documents " + Arrays.asList(labels) + ", but missing " + missing);
+ }
+ }
+
+ void clickDocument(String label) throws UiObjectNotFoundException {
+ findDocument(label).click();
+ }
+
+ void waitForDeleteSnackbar() {
+ mDevice.wait(Until.findObject(SNACK_DELETE), mTimeout);
+ }
+
+ void waitForDeleteSnackbarGone() {
+ // wait a little longer for snackbar to go away, as it disappears after a timeout.
+ mDevice.wait(Until.gone(SNACK_DELETE), mTimeout * 2);
+ }
+
+ void switchViewMode() {
+ UiObject2 mode = menuGridMode();
+ if (mode != null) {
+ mode.click();
+ } else {
+ menuListMode().click();
+ }
+ }
+
+ UiObject2 menuGridMode() {
+ // Note that we're using By.desc rather than By.res, because of b/25285770
+ return find(By.desc("Grid view"));
+ }
+
+ UiObject2 menuListMode() {
+ // Note that we're using By.desc rather than By.res, because of b/25285770
+ return find(By.desc("List view"));
+ }
+
+ UiObject2 menuDelete() {
+ return find(By.res("com.android.documentsui:id/menu_delete"));
+ }
+
+ UiObject2 menuShare() {
+ return find(By.res("com.android.documentsui:id/menu_share"));
+ }
+
+ private UiObject2 find(BySelector selector) {
+ mDevice.wait(Until.findObject(selector), mTimeout);
+ return mDevice.findObject(selector);
+ }
+}
diff --git a/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java b/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java
new file mode 100644
index 0000000..b250e5d
--- /dev/null
+++ b/tests/src/com/android/documentsui/dirlist/DirectoryFragmentModelTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.provider.DocumentsContract.Document;
+import android.support.v7.widget.RecyclerView;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.ViewGroup;
+
+import com.android.documentsui.DirectoryResult;
+import com.android.documentsui.dirlist.DirectoryFragment.Model;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+import com.android.documentsui.model.DocumentInfo;
+
+import java.util.List;
+
+@SmallTest
+public class DirectoryFragmentModelTest extends AndroidTestCase {
+
+ private static final int ITEM_COUNT = 5;
+ private static final String[] COLUMNS = new String[]{
+ Document.COLUMN_DOCUMENT_ID
+ };
+ private static Cursor cursor;
+
+ private Context mContext;
+ private Model model;
+
+ public void setUp() {
+ setupTestContext();
+
+ MatrixCursor c = new MatrixCursor(COLUMNS);
+ for (int i = 0; i < ITEM_COUNT; ++i) {
+ MatrixCursor.RowBuilder row = c.newRow();
+ row.add(COLUMNS[0], i);
+ }
+ cursor = c;
+
+ DirectoryResult r = new DirectoryResult();
+ r.cursor = cursor;
+
+ // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
+ model = new Model(mContext, new DummyAdapter());
+ model.addUpdateListener(new DummyListener());
+ model.update(r);
+ }
+
+ // Tests that the item count is correct.
+ public void testItemCount() {
+ assertEquals(ITEM_COUNT, model.getItemCount());
+ }
+
+ // Tests that the item count is correct after a deletion.
+ public void testItemCount_WithDeletion() {
+ // Simulate deleting 2 files.
+ delete(2, 4);
+
+ assertEquals(ITEM_COUNT - 2, model.getItemCount());
+ }
+
+ // Tests that the item count is correct after a deletion is undone.
+ public void testItemCount_WithUndoneDeletion() {
+ // Simulate deleting 2 files.
+ delete(0, 3);
+
+ // Undo the deletion
+ model.undoDeletion();
+ assertEquals(ITEM_COUNT, model.getItemCount());
+ }
+
+ // Tests that the right things are marked for deletion.
+ public void testMarkForDeletion() {
+ delete(1, 3);
+
+ List<DocumentInfo> docs = model.getDocumentsMarkedForDeletion();
+ assertEquals(2, docs.size());
+ assertEquals("1", docs.get(0).documentId);
+ assertEquals("3", docs.get(1).documentId);
+ }
+
+ // Tests the base case for Model.getItem.
+ public void testGetItem() {
+ for (int i = 0; i < ITEM_COUNT; ++i) {
+ Cursor c = model.getItem(i);
+ assertEquals(i, c.getPosition());
+ }
+ }
+
+ // Tests that Model.getItem returns the right items after a deletion.
+ public void testGetItem_WithDeletion() {
+ // Simulate deleting 2 files.
+ delete(2, 3);
+
+ List<DocumentInfo> docs = getDocumentInfo(0, 1, 2);
+ assertEquals("0", docs.get(0).documentId);
+ assertEquals("1", docs.get(1).documentId);
+ assertEquals("4", docs.get(2).documentId);
+ }
+
+ // Tests that Model.getItem returns the right items after a deletion is undone.
+ public void testGetItem_WithCancelledDeletion() {
+ delete(0, 1);
+ model.undoDeletion();
+
+ // Test that all documents are accounted for, in the right position.
+ for (int i = 0; i < ITEM_COUNT; ++i) {
+ assertEquals(Integer.toString(i), getDocumentInfo(i).get(0).documentId);
+ }
+ }
+
+ private void setupTestContext() {
+ final MockContentResolver resolver = new MockContentResolver();
+ mContext = new ContextWrapper(getContext()) {
+ @Override
+ public ContentResolver getContentResolver() {
+ return resolver;
+ }
+ };
+ }
+
+ private void delete(int... positions) {
+ model.markForDeletion(new Selection(positions));
+ }
+
+ private List<DocumentInfo> getDocumentInfo(int... positions) {
+ return model.getDocuments(new Selection(positions));
+ }
+
+ private static class DummyListener extends Model.UpdateListener {
+ public void onModelUpdate(Model model) {}
+ public void onModelUpdateFailed(Exception e) {}
+ }
+
+ private static class DummyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ public int getItemCount() { return 0; }
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {}
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return null;
+ }
+ }
+}
diff --git a/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java b/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
new file mode 100644
index 0000000..b3d45ae
--- /dev/null
+++ b/tests/src/com/android/documentsui/dirlist/MultiSelectManagerTest.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.support.v7.widget.RecyclerView;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.SparseBooleanArray;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.documentsui.TestInputEvent;
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@SmallTest
+public class MultiSelectManagerTest extends AndroidTestCase {
+
+ private static final List<String> items;
+ static {
+ items = new ArrayList<String>();
+ items.add("aaa");
+ items.add("bbb");
+ items.add("ccc");
+ items.add("111");
+ items.add("222");
+ items.add("333");
+ }
+
+ private MultiSelectManager mManager;
+ private TestAdapter mAdapter;
+ private TestCallback mCallback;
+ private TestSelectionEnvironment mEnv;
+
+ public void setUp() throws Exception {
+ mAdapter = new TestAdapter(items);
+ mCallback = new TestCallback();
+ mEnv = new TestSelectionEnvironment();
+ mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_MULTIPLE);
+ mManager.addCallback(mCallback);
+ }
+
+ public void testMouseClick_StartsSelectionMode() {
+ click(7);
+ assertSelection(7);
+ }
+
+ public void testMouseClick_NotifiesSelectionChanged() {
+ click(7);
+ mCallback.assertSelectionChanged();
+ }
+
+ public void testMouseClick_ShiftClickExtendsSelection() {
+ longPress(7);
+ shiftClick(11);
+ assertRangeSelection(7, 11);
+ }
+
+ public void testMouseClick_NoPosition_ClearsSelection() {
+ longPress(7);
+ click(11);
+ click(RecyclerView.NO_POSITION);
+ assertSelection();
+ }
+
+ public void testSetSelectionFocusBegin() {
+ mManager.setItemSelected(7, true);
+ mManager.setSelectionFocusBegin(7);
+ shiftClick(11);
+ assertRangeSelection(7, 11);
+ }
+
+ public void testLongPress_StartsSelectionMode() {
+ longPress(7);
+ assertSelection(7);
+ }
+
+ public void testLongPress_SecondPressExtendsSelection() {
+ longPress(7);
+ longPress(99);
+ assertSelection(7, 99);
+ }
+
+ public void testSingleTapUp_UnselectsSelectedItem() {
+ longPress(7);
+ tap(7);
+ assertSelection();
+ }
+
+ public void testSingleTapUp_NoPosition_ClearsSelection() {
+ longPress(7);
+ tap(11);
+ tap(RecyclerView.NO_POSITION);
+ assertSelection();
+ }
+
+ public void testSingleTapUp_ExtendsSelection() {
+ longPress(99);
+ tap(7);
+ tap(13);
+ tap(129899);
+ assertSelection(7, 99, 13, 129899);
+ }
+
+ public void testSingleTapUp_ShiftCreatesRangeSelection() {
+ longPress(7);
+ shiftTap(17);
+ assertRangeSelection(7, 17);
+ }
+
+ public void testSingleTapUp_ShiftCreatesRangeSeletion_Backwards() {
+ longPress(17);
+ shiftTap(7);
+ assertRangeSelection(7, 17);
+ }
+
+ public void testSingleTapUp_SecondShiftClickExtendsSelection() {
+ longPress(7);
+ shiftTap(11);
+ shiftTap(17);
+ assertRangeSelection(7, 17);
+ }
+
+ public void testSingleTapUp_MultipleContiguousRangesSelected() {
+ longPress(7);
+ shiftTap(11);
+ tap(20);
+ shiftTap(25);
+ assertRangeSelected(7, 11);
+ assertRangeSelected(20, 25);
+ assertSelectionSize(11);
+ }
+
+ public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick() {
+ longPress(7);
+ shiftTap(17);
+ shiftTap(10);
+ assertRangeSelection(7, 10);
+ }
+
+ public void testSingleTapUp_ShiftReducesSelectionRange_FromPreviousShiftClick_Backwards() {
+ mManager.onLongPress(TestInputEvent.tap(17));
+ shiftTap(7);
+ shiftTap(14);
+ assertRangeSelection(14, 17);
+ }
+
+ public void testSingleTapUp_ShiftReversesSelectionDirection() {
+ longPress(7);
+ shiftTap(17);
+ shiftTap(0);
+ assertRangeSelection(0, 7);
+ }
+
+ public void testSingleSelectMode() {
+ mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
+ mManager.addCallback(mCallback);
+ longPress(20);
+ tap(13);
+ assertSelection(13);
+ }
+
+ public void testSingleSelectMode_ShiftTap() {
+ mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
+ mManager.addCallback(mCallback);
+ longPress(13);
+ shiftTap(20);
+ assertSelection(20);
+ }
+
+ public void testSingleSelectMode_ShiftDoesNotExtendSelection() {
+ mManager = new MultiSelectManager(mAdapter, mEnv, MultiSelectManager.MODE_SINGLE);
+ mManager.addCallback(mCallback);
+ longPress(20);
+ keyToPosition(22, true);
+ assertSelection(22);
+ }
+
+ public void testProvisionalSelection() {
+ Selection s = mManager.getSelection();
+ assertSelection();
+
+ SparseBooleanArray provisional = new SparseBooleanArray();
+ provisional.append(1, true);
+ provisional.append(2, true);
+ s.setProvisionalSelection(provisional);
+ assertSelection(1, 2);
+
+ provisional.delete(1);
+ provisional.append(3, true);
+ s.setProvisionalSelection(provisional);
+ assertSelection(2, 3);
+
+ s.applyProvisionalSelection();
+ assertSelection(2, 3);
+
+ provisional.clear();
+ provisional.append(3, true);
+ provisional.append(4, true);
+ s.setProvisionalSelection(provisional);
+ assertSelection(2, 3, 4);
+
+ provisional.delete(3);
+ s.setProvisionalSelection(provisional);
+ assertSelection(2, 3, 4);
+ }
+
+ private void longPress(int position) {
+ mManager.onLongPress(TestInputEvent.tap(position));
+ }
+
+ private void tap(int position) {
+ mManager.onSingleTapUp(TestInputEvent.tap(position));
+ }
+
+ private void shiftTap(int position) {
+ mManager.onSingleTapUp(TestInputEvent.shiftTap(position));
+ }
+
+ private void click(int position) {
+ mManager.onSingleTapUp(TestInputEvent.click(position));
+ }
+
+ private void shiftClick(int position) {
+ mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
+ }
+
+ private void keyToPosition(int position, boolean shift) {
+ mManager.attemptChangePosition(position, shift);
+ }
+
+ private void assertSelected(int... expected) {
+ for (int i = 0; i < expected.length; i++) {
+ Selection selection = mManager.getSelection();
+ String err = String.format(
+ "Selection %s does not contain %d", selection, expected[i]);
+ assertTrue(err, selection.contains(expected[i]));
+ }
+ }
+
+ private void assertSelection(int... expected) {
+ assertSelectionSize(expected.length);
+ assertSelected(expected);
+ }
+
+ private void assertRangeSelected(int begin, int end) {
+ for (int i = begin; i <= end; i++) {
+ assertSelected(i);
+ }
+ }
+
+ private void assertRangeSelection(int begin, int end) {
+ assertSelectionSize(end - begin + 1);
+ assertRangeSelected(begin, end);
+ }
+
+ private void assertSelectionSize(int expected) {
+ Selection selection = mManager.getSelection();
+ assertEquals(selection.toString(), expected, selection.size());
+ }
+
+ private static final class TestCallback implements MultiSelectManager.Callback {
+
+ Set<Integer> ignored = new HashSet<>();
+ private boolean mSelectionChanged = false;
+
+ @Override
+ public void onItemStateChanged(int position, boolean selected) {}
+
+ @Override
+ public boolean onBeforeItemStateChange(int position, boolean selected) {
+ return !ignored.contains(position);
+ }
+
+ @Override
+ public void onSelectionChanged() {
+ mSelectionChanged = true;
+ }
+
+ void assertSelectionChanged() {
+ assertTrue(mSelectionChanged);
+ }
+ }
+
+ private static final class TestHolder extends RecyclerView.ViewHolder {
+ // each data item is just a string in this case
+ public TestHolder(View view) {
+ super(view);
+ }
+ }
+
+ private static final class TestAdapter extends RecyclerView.Adapter<TestHolder> {
+
+ private List<String> mItems;
+
+ public TestAdapter(List<String> items) {
+ mItems = items;
+ }
+
+ @Override
+ public TestHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new TestHolder(Mockito.mock(ViewGroup.class));
+ }
+
+ @Override
+ public void onBindViewHolder(TestHolder holder, int position) {}
+
+ @Override
+ public int getItemCount() {
+ return mItems.size();
+ }
+ }
+}
diff --git a/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java b/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
new file mode 100644
index 0000000..c856b22
--- /dev/null
+++ b/tests/src/com/android/documentsui/dirlist/MultiSelectManager_GridModelTest.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.SparseBooleanArray;
+import android.view.View;
+
+import com.android.documentsui.dirlist.MultiSelectManager.GridModel;
+
+@SmallTest
+public class MultiSelectManager_GridModelTest extends AndroidTestCase {
+
+ private static final int VIEW_PADDING_PX = 5;
+ private static final int CHILD_VIEW_EDGE_PX = 100;
+ private static final int VIEWPORT_HEIGHT = 500;
+
+ private static GridModel model;
+ private static TestEnvironment env;
+ private static SparseBooleanArray lastSelection;
+ private static int viewWidth;
+
+ private static void setUp(int numChildren, int numColumns) {
+ env = new TestEnvironment(numChildren, numColumns);
+ viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
+ model = new GridModel(env);
+ model.addOnSelectionChangedListener(
+ new GridModel.OnSelectionChangedListener() {
+ @Override
+ public void onSelectionChanged(SparseBooleanArray updatedSelection) {
+ lastSelection = updatedSelection;
+ }
+ });
+ }
+
+ @Override
+ public void tearDown() {
+ model = null;
+ env = null;
+ lastSelection = null;
+ }
+
+ public void testSelectionLeftOfItems() {
+ setUp(20, 5);
+ model.startSelection(new Point(0, 10));
+ model.resizeSelection(new Point(1, 11));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testSelectionRightOfItems() {
+ setUp(20, 4);
+ model.startSelection(new Point(viewWidth - 1, 10));
+ model.resizeSelection(new Point(viewWidth - 2, 11));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testSelectionAboveItems() {
+ setUp(20, 4);
+ model.startSelection(new Point(10, 0));
+ model.resizeSelection(new Point(11, 1));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testSelectionBelowItems() {
+ setUp(5, 4);
+ model.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
+ model.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testVerticalSelectionBetweenItems() {
+ setUp(20, 4);
+ model.startSelection(new Point(106, 0));
+ model.resizeSelection(new Point(107, 200));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testHorizontalSelectionBetweenItems() {
+ setUp(20, 4);
+ model.startSelection(new Point(0, 105));
+ model.resizeSelection(new Point(200, 106));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testGrowingAndShrinkingSelection() {
+ setUp(20, 4);
+ model.startSelection(new Point(0, 0));
+ model.resizeSelection(new Point(5, 5));
+ assertSelected(new int[] {0});
+ model.resizeSelection(new Point(109, 109));
+ assertSelected(new int[] {0});
+ model.resizeSelection(new Point(110, 109));
+ assertSelected(new int[] {0, 1});
+ model.resizeSelection(new Point(110, 110));
+ assertSelected(new int[] {0, 1, 4, 5});
+ model.resizeSelection(new Point(214, 214));
+ assertSelected(new int[] {0, 1, 4, 5});
+ model.resizeSelection(new Point(215, 214));
+ assertSelected(new int[] {0, 1, 2, 4, 5, 6});
+ model.resizeSelection(new Point(214, 214));
+ assertSelected(new int[] {0, 1, 4, 5});
+ model.resizeSelection(new Point(110, 110));
+ assertSelected(new int[] {0, 1, 4, 5});
+ model.resizeSelection(new Point(110, 109));
+ assertSelected(new int[] {0, 1});
+ model.resizeSelection(new Point(109, 109));
+ assertSelected(new int[] {0});
+ model.resizeSelection(new Point(5, 5));
+ assertSelected(new int[] {0});
+ model.resizeSelection(new Point(0, 0));
+ assertSelected(new int[0]);
+ assertEquals(GridModel.NOT_SET, model.getPositionNearestOrigin());
+ }
+
+ public void testSelectionMovingAroundOrigin() {
+ setUp(16, 4);
+ model.startSelection(new Point(210, 210));
+ model.resizeSelection(new Point(viewWidth - 1, 0));
+ assertSelected(new int[] {2, 3, 6, 7});
+ model.resizeSelection(new Point(0, 0));
+ assertSelected(new int[] {0, 1, 4, 5});
+ model.resizeSelection(new Point(0, 420));
+ assertSelected(new int[] {8, 9, 12, 13});
+ model.resizeSelection(new Point(viewWidth - 1, 420));
+ assertSelected(new int[] {10, 11, 14, 15});
+ assertEquals(10, model.getPositionNearestOrigin());
+ }
+
+ public void testScrollingBandSelect() {
+ setUp(40, 4);
+ model.startSelection(new Point(0, 0));
+ model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 4, 8, 12, 16});
+ scroll(CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 4, 8, 12, 16, 20});
+ model.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21});
+ scroll(CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25});
+ scroll(-2 * CHILD_VIEW_EDGE_PX);
+ assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17});
+ model.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+ assertSelected(new int[] {0, 4, 8, 12, 16});
+ assertEquals(0, model.getPositionNearestOrigin());
+ }
+
+ private static void assertSelected(int[] selectedPositions) {
+ assertEquals(selectedPositions.length, lastSelection.size());
+ for (int position : selectedPositions) {
+ assertTrue(lastSelection.get(position));
+ }
+ }
+
+ private static void scroll(int dy) {
+ assertTrue(env.verticalOffset + VIEWPORT_HEIGHT + dy <= env.getTotalHeight());
+ env.verticalOffset += dy;
+ model.onScrolled(null, 0, dy);
+ }
+
+ private static final class TestEnvironment implements MultiSelectManager.SelectionEnvironment {
+
+ public int horizontalOffset = 0;
+ public int verticalOffset = 0;
+ private final int mNumColumns;
+ private final int mNumRows;
+ private final int mNumChildren;
+
+ public TestEnvironment(int numChildren, int numColumns) {
+ mNumChildren = numChildren;
+ mNumColumns = numColumns;
+ mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
+ }
+
+ private int getTotalHeight() {
+ return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
+ }
+
+ private int getFirstVisibleRowIndex() {
+ return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ }
+
+ private int getLastVisibleRowIndex() {
+ int lastVisibleRowUncapped =
+ (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ return Math.min(lastVisibleRowUncapped, mNumRows - 1);
+ }
+
+ private int getNumItemsInRow(int index) {
+ assertTrue(index >= 0 && index < mNumRows);
+ if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
+ return mNumChildren % mNumColumns;
+ }
+
+ return mNumColumns;
+ }
+
+ @Override
+ public void addOnScrollListener(OnScrollListener listener) {}
+
+ @Override
+ public void removeOnScrollListener(OnScrollListener listener) {}
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return new Point(
+ relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ int childCount = 0;
+ for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
+ childCount += getNumItemsInRow(i);
+ }
+ return childCount;
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ return index + mNumColumns * (getFirstVisibleRowIndex());
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ int adapterPosition = getAdapterPositionAt(index);
+ int rowIndex = adapterPosition / mNumColumns;
+ int columnIndex = adapterPosition % mNumColumns;
+
+ Rect rect = new Rect();
+ rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
+ rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+ rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
+ return rect;
+ }
+
+ @Override
+ public int getChildCount() {
+ return mNumChildren;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return mNumColumns;
+ }
+
+ @Override
+ public int getRowCount() {
+ return mNumRows;
+ }
+
+ @Override
+ public void showBand(Rect rect) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void hideBand() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void scrollBy(int dy) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getHeight() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void invalidateView() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void runAtNextFrame(Runnable r) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeCallback(Runnable r) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getAdapterPositionForChildView(View view) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void focusItem(int i) {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java b/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java
new file mode 100644
index 0000000..030ac6c
--- /dev/null
+++ b/tests/src/com/android/documentsui/dirlist/MultiSelectManager_SelectionTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.documentsui.dirlist.MultiSelectManager.Selection;
+
+@SmallTest
+public class MultiSelectManager_SelectionTest extends AndroidTestCase {
+
+ private Selection selection;
+
+ @Override
+ public void setUp() throws Exception {
+ selection = new Selection();
+ selection.add(3);
+ selection.add(5);
+ selection.add(9);
+ }
+
+ public void testAdd() {
+ // We added in setUp.
+ assertEquals(3, selection.size());
+ assertContains(3);
+ assertContains(5);
+ assertContains(9);
+ }
+
+ public void testRemove() {
+ selection.remove(3);
+ selection.remove(5);
+ assertEquals(1, selection.size());
+ assertContains(9);
+ }
+
+ public void testClear() {
+ selection.clear();
+ assertEquals(0, selection.size());
+ }
+
+ public void testIsEmpty() {
+ assertTrue(new Selection().isEmpty());
+ selection.clear();
+ assertTrue(selection.isEmpty());
+ }
+
+ public void testSizeAndGet() {
+ Selection other = new Selection();
+ for (int i = 0; i < selection.size(); i++) {
+ other.add(selection.get(i));
+ }
+ assertEquals(selection.size(), other.size());
+ }
+
+ public void testEqualsSelf() {
+ assertEquals(selection, selection);
+ }
+
+ public void testEqualsOther() {
+ Selection other = new Selection();
+ other.add(3);
+ other.add(5);
+ other.add(9);
+ assertEquals(selection, other);
+ assertEquals(selection.hashCode(), other.hashCode());
+ }
+
+ public void testEqualsCopy() {
+ Selection other = new Selection();
+ other.copyFrom(selection);
+ assertEquals(selection, other);
+ assertEquals(selection.hashCode(), other.hashCode());
+ }
+
+ public void testNotEquals() {
+ Selection other = new Selection();
+ other.add(789);
+ assertFalse(selection.equals(other));
+ }
+
+ public void testExpandBefore() {
+ selection.expand(2, 10);
+ assertEquals(3, selection.size());
+ assertContains(13);
+ assertContains(15);
+ assertContains(19);
+ }
+
+ public void testExpandAfter() {
+ selection.expand(10, 10);
+ assertEquals(3, selection.size());
+ assertContains(3);
+ assertContains(5);
+ assertContains(9);
+ }
+
+ public void testExpandSplit() {
+ selection.expand(5, 10);
+ assertEquals(3, selection.size());
+ assertContains(3);
+ assertContains(15);
+ assertContains(19);
+ }
+
+ public void testExpandEncompased() {
+ selection.expand(2, 10);
+ assertEquals(3, selection.size());
+ assertContains(13);
+ assertContains(15);
+ assertContains(19);
+ }
+
+ public void testCollapseBefore() {
+ selection.collapse(0, 2);
+ assertEquals(3, selection.size());
+ assertContains(1);
+ assertContains(3);
+ assertContains(7);
+ }
+
+ public void testCollapseAfter() {
+ selection.collapse(10, 10);
+ assertEquals(3, selection.size());
+ assertContains(3);
+ assertContains(5);
+ assertContains(9);
+ }
+
+ public void testCollapseAcross() {
+ selection.collapse(0, 10);
+ assertEquals(0, selection.size());
+ }
+
+ private void assertContains(int i) {
+ String err = String.format("Selection %s does not contain %d", selection, i);
+ assertTrue(err, selection.contains(i));
+ }
+}
diff --git a/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java b/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
new file mode 100644
index 0000000..b4324a8
--- /dev/null
+++ b/tests/src/com/android/documentsui/dirlist/TestSelectionEnvironment.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.dirlist;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.view.View;
+
+import com.android.documentsui.dirlist.MultiSelectManager.SelectionEnvironment;
+
+public class TestSelectionEnvironment implements SelectionEnvironment {
+
+ @Override
+ public void showBand(Rect rect) {
+ }
+
+ @Override
+ public void hideBand() {
+ }
+
+ @Override
+ public void addOnScrollListener(OnScrollListener listener) {
+ }
+
+ @Override
+ public void removeOnScrollListener(OnScrollListener listener) {
+ }
+
+ @Override
+ public void scrollBy(int dy) {
+ }
+
+ @Override
+ public int getHeight() {
+ return 0;
+ }
+
+ @Override
+ public void invalidateView() {
+ }
+
+ @Override
+ public void runAtNextFrame(Runnable r) {
+ }
+
+ @Override
+ public void removeCallback(Runnable r) {
+ }
+
+ @Override
+ public Point createAbsolutePoint(Point relativePoint) {
+ return null;
+ }
+
+ @Override
+ public Rect getAbsoluteRectForChildViewAt(int index) {
+ return null;
+ }
+
+ @Override
+ public int getAdapterPositionAt(int index) {
+ return 0;
+ }
+
+ @Override
+ public int getAdapterPositionForChildView(View view) {
+ return 0;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return 0;
+ }
+
+ @Override
+ public int getRowCount() {
+ return 0;
+ }
+
+ @Override
+ public int getChildCount() {
+ return 0;
+ }
+
+ @Override
+ public int getVisibleChildCount() {
+ return 0;
+ }
+
+ @Override
+ public void focusItem(int position) {
+ }
+}
diff --git a/tests/src/com/android/documentsui/model/DocumentInfoTest.java b/tests/src/com/android/documentsui/model/DocumentInfoTest.java
new file mode 100644
index 0000000..a6aba7b
--- /dev/null
+++ b/tests/src/com/android/documentsui/model/DocumentInfoTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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
+ *
+ * http://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.
+ */
+
+package com.android.documentsui.model;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+@SmallTest
+public class DocumentInfoTest extends AndroidTestCase {
+
+ public void testEquals() throws Exception {
+ DocumentInfo doc = createDocInfo("authority.a", "doc.1", "text/plain");
+ assertEquals(doc, doc);
+ }
+
+ public void testNotEquals_differentAuthority() throws Exception {
+ DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
+ DocumentInfo docB = createDocInfo("authority.b", "doc.1", "text/plain");
+ assertFalse(docA.equals(docB));
+ }
+
+ public void testNotEquals_differentDocId() throws Exception {
+ DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
+ DocumentInfo docB = createDocInfo("authority.a", "doc.2", "text/plain");
+ assertFalse(docA.equals(docB));
+ }
+
+ public void testNotEquals_differentMimetype() throws Exception {
+ DocumentInfo docA = createDocInfo("authority.a", "doc.1", "text/plain");
+ DocumentInfo docB = createDocInfo("authority.a", "doc.1", "image/png");
+ assertFalse(docA.equals(docB));
+ }
+
+ private DocumentInfo createDocInfo(String authority, String docId, String mimeType) {
+ DocumentInfo doc = new DocumentInfo();
+ doc.authority = authority;
+ doc.documentId = docId;
+ doc.mimeType = mimeType;
+ doc.deriveFields();
+ return doc;
+ }
+}