17
17
*/
18
18
package com.infomaniak.drive.ui.fileList.preview
19
19
20
+ import android.content.Context
20
21
import android.content.Intent
21
22
import android.net.Uri
22
23
import android.os.Bundle
24
+ import android.os.CancellationSignal
25
+ import android.os.ParcelFileDescriptor
26
+ import android.print.*
27
+ import android.view.View
23
28
import androidx.appcompat.app.AppCompatActivity
24
29
import androidx.core.view.ViewCompat
25
30
import androidx.core.view.WindowInsetsCompat
26
31
import androidx.navigation.NavController
27
32
import androidx.navigation.fragment.NavHostFragment
33
+ import com.google.android.material.bottomsheet.BottomSheetBehavior
28
34
import com.infomaniak.drive.R
35
+ import com.infomaniak.drive.data.models.ExtensionType
36
+ import com.infomaniak.drive.data.models.File
29
37
import com.infomaniak.drive.databinding.ActivityPreviewPdfBinding
30
38
import com.infomaniak.drive.ui.SaveExternalFilesActivity
31
39
import com.infomaniak.drive.ui.SaveExternalFilesActivityArgs
32
40
import com.infomaniak.drive.utils.AccountUtils
41
+ import com.infomaniak.drive.utils.IOFile
42
+ import com.infomaniak.drive.utils.SyncUtils.uploadFolder
43
+ import com.infomaniak.drive.utils.Utils.ROOT_ID
44
+ import com.infomaniak.drive.utils.Utils.openWithIntent
33
45
import com.infomaniak.drive.utils.setupTransparentStatusBar
46
+ import com.infomaniak.drive.utils.shareFile
47
+ import com.infomaniak.drive.views.ExternalFileInfoActionsView
48
+ import com.infomaniak.lib.core.utils.context
49
+ import com.infomaniak.lib.core.utils.getFileNameAndSize
34
50
import com.infomaniak.lib.core.utils.setMargins
51
+ import java.io.FileInputStream
52
+ import java.io.FileOutputStream
53
+ import java.io.InputStream
54
+ import java.io.OutputStream
35
55
36
- class PreviewPDFActivity : AppCompatActivity () {
56
+ class PreviewPDFActivity : AppCompatActivity (), ExternalFileInfoActionsView.OnItemClickListener {
57
+
58
+ private val navController by lazy { setupNavController() }
59
+ private val navHostFragment by lazy { supportFragmentManager.findFragmentById(R .id.hostFragment) as NavHostFragment }
37
60
38
61
private val binding: ActivityPreviewPdfBinding by lazy { ActivityPreviewPdfBinding .inflate(layoutInflater) }
39
62
63
+ private val externalPDFUri: Uri by lazy { Uri .parse(intent.dataString) }
64
+ private val fileNameAndSize: Pair <String , Long >? by lazy { getFileNameAndSize(Uri .parse(intent.dataString!! )) }
65
+ private val fileName: String by lazy { fileNameAndSize?.first ? : " Document to print" }
66
+ private val fileSize: Long? by lazy { fileNameAndSize?.second }
67
+
68
+ private lateinit var bottomSheetBehavior: BottomSheetBehavior <View >
69
+
40
70
override fun onCreate (savedInstanceState : Bundle ? ) {
41
71
super .onCreate(savedInstanceState)
42
72
setContentView(binding.root)
43
- setupNavController() .navigate(R .id.previewPDFFragment)
73
+ navController .navigate(R .id.previewPDFFragment)
44
74
45
- binding.backButton.setOnClickListener { finish() }
46
- binding.saveToKDrive.setOnClickListener { saveToKDrive(Uri .parse(intent.dataString)) }
75
+ with (binding) {
76
+ backButton.setOnClickListener { finish() }
77
+ intent.dataString?.let {
78
+ bottomSheetFileInfos.updateWithExternalFile(getFile())
79
+ bottomSheetFileInfos.init (this @PreviewPDFActivity)
80
+ bottomSheetBehavior = BottomSheetBehavior .from(bottomSheetFileInfos)
81
+ }
82
+ }
47
83
}
48
84
49
85
override fun onStart () {
@@ -52,6 +88,38 @@ class PreviewPDFActivity : AppCompatActivity() {
52
88
setupTransparentStatusBar()
53
89
}
54
90
91
+ override fun openWithClicked (context : Context ) {
92
+ super .openWithClicked(context)
93
+ startActivity(openWithIntent(externalPDFUri))
94
+ }
95
+
96
+ override fun shareFile (context : Context ) {
97
+ super .shareFile(context)
98
+ shareFile { externalPDFUri }
99
+ }
100
+
101
+ override fun saveToKDriveClicked (context : Context ) {
102
+ super .saveToKDriveClicked(context)
103
+ saveToKDrive(externalPDFUri)
104
+ }
105
+
106
+ override fun printClicked (context : Context ) {
107
+ super .printClicked(context)
108
+ val printManager = getSystemService(Context .PRINT_SERVICE ) as PrintManager
109
+ val printAdapter = PDFDocumentAdapter (fileName, getOutputFile(externalPDFUri))
110
+ printManager.print (fileName, printAdapter, PrintAttributes .Builder ().build())
111
+ }
112
+
113
+ private fun getFile (): File {
114
+ return File ().apply {
115
+ name = fileName
116
+ size = fileSize
117
+ id = ROOT_ID
118
+ extensionType = ExtensionType .PDF .value
119
+ type = " "
120
+ }
121
+ }
122
+
55
123
private fun saveToKDrive (uri : Uri ) {
56
124
Intent (this , SaveExternalFilesActivity ::class .java).apply {
57
125
action = Intent .ACTION_SEND
@@ -70,17 +138,82 @@ class PreviewPDFActivity : AppCompatActivity() {
70
138
private fun setupWindowInsetsListener () = with (binding) {
71
139
ViewCompat .setOnApplyWindowInsetsListener(root) { _, windowInsets ->
72
140
with (windowInsets.getInsets(WindowInsetsCompat .Type .systemBars())) {
73
- header.setMargins(left = left, top = top, right = right)
141
+ val defaultMargin = context.resources.getDimension(R .dimen.marginStandardMedium).toInt()
142
+ backButton.setMargins(top = top + defaultMargin)
143
+ /* Add padding to the bottom to allow the last element of the list to be displayed right over the
144
+ android navigation bar */
145
+ bottomSheetFileInfos.setPadding(0 , 0 , 0 , bottom)
74
146
}
75
147
windowInsets
76
148
}
77
149
}
78
150
79
- private fun getNavHostFragment () = supportFragmentManager.findFragmentById(R .id.hostFragment) as NavHostFragment
80
-
81
151
private fun setupNavController (): NavController {
82
- return getNavHostFragment().navController.apply {
83
- setGraph(R .navigation.view_pdf, PreviewPDFFragmentArgs (fileURI = intent.dataString).toBundle())
152
+ return navHostFragment.navController.apply {
153
+ intent.dataString?.let {
154
+ setGraph(R .navigation.view_pdf, PreviewPDFFragmentArgs (fileURI = it).toBundle())
155
+ }
156
+ }
157
+ }
158
+
159
+ private fun getOutputFile (uri : Uri ): IOFile {
160
+ return IOFile (uploadFolder, uri.hashCode().toString()).apply {
161
+ if (exists()) delete()
162
+ createNewFile()
163
+ contentResolver?.openInputStream(uri)?.use { inputStream ->
164
+ outputStream().use { inputStream.copyTo(it) }
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ class PDFDocumentAdapter (private val fileName : String , private val file : java.io.File ) : PrintDocumentAdapter() {
171
+
172
+ override fun onLayout (
173
+ oldAttributes : PrintAttributes ? ,
174
+ newAttributes : PrintAttributes ? ,
175
+ cancellationSignal : CancellationSignal ,
176
+ callback : LayoutResultCallback ,
177
+ extras : Bundle ?
178
+ ) {
179
+ if (cancellationSignal.isCanceled) {
180
+ callback.onLayoutCancelled()
181
+ return
182
+ }
183
+
184
+ val info = PrintDocumentInfo .Builder (fileName)
185
+ .setContentType(PrintDocumentInfo .CONTENT_TYPE_DOCUMENT )
186
+ .setPageCount(PrintDocumentInfo .PAGE_COUNT_UNKNOWN )
187
+ .build()
188
+
189
+ callback.onLayoutFinished(info, oldAttributes != newAttributes)
190
+ }
191
+
192
+ override fun onWrite (
193
+ pages : Array <out PageRange >,
194
+ destination : ParcelFileDescriptor ,
195
+ cancellationSignal : CancellationSignal ,
196
+ callback : WriteResultCallback
197
+ ) {
198
+ var inputStream: InputStream ? = null
199
+ var outputStream: OutputStream ? = null
200
+
201
+ try {
202
+ inputStream = FileInputStream (file)
203
+ outputStream = FileOutputStream (destination.fileDescriptor)
204
+
205
+ inputStream.copyTo(outputStream)
206
+
207
+ if (cancellationSignal.isCanceled) {
208
+ callback.onWriteCancelled()
209
+ } else {
210
+ callback.onWriteFinished(arrayOf(PageRange .ALL_PAGES ))
211
+ }
212
+ } catch (ex: Exception ) {
213
+ callback.onWriteFailed(ex.message)
214
+ } finally {
215
+ inputStream?.close()
216
+ outputStream?.close()
84
217
}
85
218
}
86
219
}
0 commit comments