Skip to content

Commit 4d53995

Browse files
author
PSPDFKit
committed
Release 3.10.0
1 parent dfe418c commit 4d53995

33 files changed

+766
-63
lines changed

CHANGELOG.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
## Newest Release
22

3+
### 3.10.0 - 03 May 2024
4+
- Adds APIs to get page information such as size, rotation and label. (J#HYB-195)
5+
- Adds document load callbacks to `PspdfkitWidget`. (J#HYB-195)
6+
- Adds page change callback to `PspdfkitWidget`. (J#HYB-195)
7+
- Adds support for exporting document as binary data. (J#HYB-337)
8+
- Updates for PSPDFKit 2024.2.1 for Android.
9+
- Updates for PSPDFKit 13.4.1 for iOS.
10+
11+
## Previous Releases
12+
313
### 3.9.1 - 12 Apr 2024
414
- Downgrades to AGP 7.* for backward compatibility (J#HYB-290)
515
- Allow null value for `Pspdfkit.setLicenseKey` (J#HYB-294)
616
- Updates for PSPDFKit 2024.2.1 for Android (J#HYB-303)
717

8-
## Previous Releases
9-
1018
### 3.9.0 - 22 Mar 2024
1119

1220
- Adds annotation toolbar customization for iOS and Android. (J#HYB-209)

android/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,9 @@ dependencies {
6161
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
6262
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
6363
implementation "androidx.compose.material:material:1.6.5"
64+
implementation "androidx.compose.material:material:1.6.3"
65+
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
66+
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
67+
implementation "androidx.compose.foundation:foundation:1.6.3"
68+
implementation "androidx.compose.ui:ui:1.6.3"
6469
}

android/src/main/java/com/pspdfkit/flutter/pspdfkit/FlutterPdfUiFragmentCallbacks.kt

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,59 @@ package com.pspdfkit.flutter.pspdfkit
33
import android.content.Context
44
import androidx.fragment.app.Fragment
55
import androidx.fragment.app.FragmentManager
6-
import com.pspdfkit.annotations.measurements.MeasurementValueConfiguration
76
import com.pspdfkit.document.PdfDocument
87
import com.pspdfkit.flutter.pspdfkit.util.MeasurementHelper
98
import com.pspdfkit.listeners.SimpleDocumentListener
109
import com.pspdfkit.ui.PdfFragment
10+
import io.flutter.plugin.common.MethodChannel
11+
12+
class FlutterPdfUiFragmentCallbacks(val methodChannel: MethodChannel,val measurementConfigurations: List<Map<String, Any>>?): FragmentManager.FragmentLifecycleCallbacks() {
13+
14+
var pdfFragment: PdfFragment? = null
1115

12-
class FlutterPdfUiFragmentCallbacks(val measurementConfigurations: List<Map<String, Any>>?): FragmentManager.FragmentLifecycleCallbacks() {
13-
final
1416
override fun onFragmentAttached(
1517
fm: FragmentManager,
1618
f: Fragment,
1719
context: Context
1820
) {
1921
if (f.tag?.contains("PSPDFKit.Fragment") == true) {
2022
EventDispatcher.getInstance().notifyPdfFragmentAdded()
21-
val pdfFragment = f as PdfFragment
22-
23-
pdfFragment.addDocumentListener( object : SimpleDocumentListener() {
23+
if (f !is PdfFragment) {
24+
return
25+
}
26+
if (pdfFragment != null) {
27+
return
28+
}
29+
pdfFragment = f as PdfFragment
30+
pdfFragment?.addDocumentListener( object : SimpleDocumentListener() {
2431
override fun onDocumentLoaded(document: PdfDocument) {
25-
if (measurementConfigurations == null) return
26-
measurementConfigurations.forEach {
27-
MeasurementHelper.addMeasurementConfiguration(pdfFragment, it)
32+
measurementConfigurations?.forEach {
33+
MeasurementHelper.addMeasurementConfiguration(pdfFragment!!, it)
2834
}
35+
methodChannel.invokeMethod("onDocumentLoaded", mapOf(
36+
"documentId" to document.uid
37+
))
38+
}
39+
40+
override fun onPageChanged(document: PdfDocument, pageIndex: Int) {
41+
super.onPageChanged(document, pageIndex)
42+
methodChannel.invokeMethod(
43+
"onPageChanged",
44+
mapOf(
45+
"documentId" to document.uid,
46+
"pageIndex" to pageIndex
47+
)
48+
)
49+
}
50+
51+
override fun onDocumentLoadFailed(exception: Throwable) {
52+
super.onDocumentLoadFailed(exception)
53+
methodChannel.invokeMethod(
54+
"onDocumentLoadFailed",
55+
mapOf(
56+
"error" to exception.message
57+
)
58+
)
2959
}
3060
})
3161
}

android/src/main/java/com/pspdfkit/flutter/pspdfkit/PSPDFKitView.kt

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.pspdfkit.flutter.pspdfkit
22

3+
import android.annotation.SuppressLint
34
import android.content.Context
45
import android.content.MutableContextWrapper
56
import android.net.Uri
7+
import android.util.Log
68
import android.view.View
79
import androidx.fragment.app.Fragment
810
import androidx.fragment.app.FragmentActivity
@@ -11,19 +13,21 @@ import androidx.fragment.app.FragmentManager
1113
import androidx.fragment.app.commit
1214
import androidx.fragment.app.commitNow
1315
import com.pspdfkit.document.formatters.DocumentJsonFormatter
16+
import com.pspdfkit.document.processor.PdfProcessor
17+
import com.pspdfkit.document.processor.PdfProcessorTask
1418
import com.pspdfkit.flutter.pspdfkit.AnnotationConfigurationAdaptor.Companion.convertAnnotationConfigurations
1519
import com.pspdfkit.flutter.pspdfkit.toolbar.FlutterMenuGroupingRule
1620
import com.pspdfkit.flutter.pspdfkit.toolbar.FlutterViewModeController
1721
import com.pspdfkit.flutter.pspdfkit.util.DocumentJsonDataProvider
1822
import com.pspdfkit.flutter.pspdfkit.util.Preconditions.requireNotNullNotEmpty
23+
import com.pspdfkit.flutter.pspdfkit.util.ProcessorHelper
1924
import com.pspdfkit.flutter.pspdfkit.util.addFileSchemeIfMissing
2025
import com.pspdfkit.flutter.pspdfkit.util.areValidIndexes
2126
import com.pspdfkit.flutter.pspdfkit.util.isImageDocument
2227
import com.pspdfkit.forms.ChoiceFormElement
2328
import com.pspdfkit.forms.EditableButtonFormElement
2429
import com.pspdfkit.forms.SignatureFormElement
2530
import com.pspdfkit.forms.TextFormElement
26-
import com.pspdfkit.ui.PdfFragment
2731
import com.pspdfkit.ui.PdfUiFragment
2832
import com.pspdfkit.ui.PdfUiFragmentBuilder
2933
import io.flutter.plugin.common.BinaryMessenger
@@ -34,17 +38,20 @@ import io.flutter.plugin.common.StandardMessageCodec
3438
import io.flutter.plugin.platform.PlatformView
3539
import io.flutter.plugin.platform.PlatformViewFactory
3640
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
41+
import io.reactivex.rxjava3.disposables.Disposable
3742
import io.reactivex.rxjava3.schedulers.Schedulers
3843
import org.json.JSONObject
3944
import java.io.ByteArrayOutputStream
45+
import java.io.File
46+
import java.io.FileOutputStream
47+
4048

4149
internal class PSPDFKitView(
4250
val context: Context,
4351
id: Int,
4452
messenger: BinaryMessenger,
4553
documentPath: String? = null,
4654
configurationMap: HashMap<String, Any>? = null,
47-
4855
) : PlatformView, MethodCallHandler {
4956

5057
private var fragmentContainerView: FragmentContainerView? = FragmentContainerView(context)
@@ -84,9 +91,7 @@ internal class PSPDFKitView(
8491
.build()
8592
}
8693
}
87-
88-
getFragmentActivity(context).supportFragmentManager.registerFragmentLifecycleCallbacks(FlutterPdfUiFragmentCallbacks(measurementValueConfigurations), true)
89-
94+
getFragmentActivity(context).supportFragmentManager.registerFragmentLifecycleCallbacks(FlutterPdfUiFragmentCallbacks(methodChannel,measurementValueConfigurations), true)
9095
getFragmentActivity(context).supportFragmentManager.registerFragmentLifecycleCallbacks( object : FragmentManager.FragmentLifecycleCallbacks() {
9196
override fun onFragmentAttached(
9297
fm: FragmentManager,
@@ -131,6 +136,7 @@ internal class PSPDFKitView(
131136
fragmentContainerView = null
132137
}
133138

139+
@SuppressLint("CheckResult")
134140
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
135141
// Return if the fragment or the document
136142
// are not ready.
@@ -445,6 +451,35 @@ internal class PSPDFKitView(
445451
result.error("AnnotationException", e.message, null)
446452
}
447453
}
454+
"getPageInfo" -> {
455+
try {
456+
val pageIndex:Int = requireNotNull(call.argument("pageIndex"))
457+
val pageInfo = mapOf(
458+
"width" to document.getPageSize(pageIndex).width,
459+
"height" to document.getPageSize(pageIndex).height,
460+
"label" to document.getPageLabel(pageIndex,false),
461+
"index" to pageIndex,
462+
"rotation" to document.getPageRotation(pageIndex)
463+
)
464+
result.success(pageInfo)
465+
}catch (e:Exception){
466+
result.error("DocumentException",e.message,null)
467+
}
468+
}
469+
"exportPdf" -> {
470+
try {
471+
val fileUrl = document.documentSource.fileUri?.path
472+
if (fileUrl == null) {
473+
result.error("DocumentException", "Document source is not a file", null)
474+
return
475+
}
476+
val data:ByteArray = fileUrl.let { File(it).readBytes() }
477+
result.success(data)
478+
} catch (e: Exception) {
479+
Log.e(LOG_TAG, "Error while exporting PDF", e)
480+
result.error("DocumentException", e.message, null)
481+
}
482+
}
448483
else -> result.notImplemented()
449484
}
450485
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.pspdfkit.flutter.pspdfkit.util
2+
3+
import com.pspdfkit.document.DocumentPermissions
4+
import com.pspdfkit.document.DocumentSaveOptions
5+
import com.pspdfkit.document.PdfVersion
6+
import java.util.EnumSet
7+
8+
object ProcessorHelper {
9+
fun extractSaveOptions( options: Map<String, Any>): DocumentSaveOptions {
10+
val password: String? = options["password"] as String?
11+
val permissionsList = options["permissions"]as List<String>??: emptyList()
12+
val incremental = options["incremental"] as Boolean? ?: false
13+
val pdfVersion = options["pdfVersion"] as String?
14+
val saveOptions = DocumentSaveOptions(
15+
password,
16+
extractPermissions(permissionsList ),
17+
incremental,
18+
extractPdfVersion(pdfVersion)
19+
)
20+
return saveOptions
21+
}
22+
23+
private fun extractPermissions(permissions: List<String>): EnumSet<DocumentPermissions> {
24+
val documentPermissions = EnumSet.noneOf(DocumentPermissions::class.java)
25+
for (permission in permissions) {
26+
when (permission) {
27+
"printing" -> documentPermissions.add(DocumentPermissions.PRINTING)
28+
"annotationsAndForms" -> documentPermissions.add(DocumentPermissions.ANNOTATIONS_AND_FORMS)
29+
"extractAccessibility" -> documentPermissions.add(DocumentPermissions.EXTRACT_ACCESSIBILITY)
30+
"fillForms" -> documentPermissions.add(DocumentPermissions.FILL_FORMS)
31+
"extract" -> documentPermissions.add(DocumentPermissions.EXTRACT)
32+
"assemble" -> documentPermissions.add(DocumentPermissions.ASSEMBLE)
33+
"printHighQuality" -> documentPermissions.add(DocumentPermissions.PRINT_HIGH_QUALITY)
34+
"modification" -> documentPermissions.add(DocumentPermissions.MODIFICATION)
35+
}
36+
}
37+
return documentPermissions
38+
}
39+
40+
private fun extractPdfVersion(pdfVersion: String?): PdfVersion? {
41+
return when (pdfVersion) {
42+
"pdf_1_0" -> PdfVersion.PDF_1_0
43+
"pdf_1_1" -> PdfVersion.PDF_1_1
44+
"pdf_1_2" -> PdfVersion.PDF_1_2
45+
"pdf_1_3" -> PdfVersion.PDF_1_3
46+
"pdf_1_4" -> PdfVersion.PDF_1_4
47+
"pdf_1_5" -> PdfVersion.PDF_1_5
48+
"pdf_1_6" -> PdfVersion.PDF_1_6
49+
"pdf_1_7" -> PdfVersion.PDF_1_7
50+
else -> null
51+
}
52+
}
53+
54+
fun reversePdfVersion(pdfVersion: PdfVersion): String? {
55+
return when (pdfVersion) {
56+
PdfVersion.PDF_1_0 -> "pdf_1_0"
57+
PdfVersion.PDF_1_1 -> "pdf_1_1"
58+
PdfVersion.PDF_1_2 -> "pdf_1_2"
59+
PdfVersion.PDF_1_3 -> "pdf_1_3"
60+
PdfVersion.PDF_1_4 -> "pdf_1_4"
61+
PdfVersion.PDF_1_5 -> "pdf_1_5"
62+
PdfVersion.PDF_1_6 -> "pdf_1_6"
63+
PdfVersion.PDF_1_7 -> "pdf_1_7"
64+
}
65+
}
66+
67+
fun reversePermissions(permissions: EnumSet<DocumentPermissions>): List<String> {
68+
val permissionsList = mutableListOf<String>()
69+
for (permission in permissions) {
70+
when (permission) {
71+
DocumentPermissions.PRINTING -> permissionsList.add("printing")
72+
DocumentPermissions.ANNOTATIONS_AND_FORMS -> permissionsList.add("annotationsAndForms")
73+
DocumentPermissions.EXTRACT_ACCESSIBILITY -> permissionsList.add("extractAccessibility")
74+
DocumentPermissions.FILL_FORMS -> permissionsList.add("fillForms")
75+
DocumentPermissions.EXTRACT -> permissionsList.add("extract")
76+
DocumentPermissions.ASSEMBLE -> permissionsList.add("assemble")
77+
DocumentPermissions.PRINT_HIGH_QUALITY -> permissionsList.add("printHighQuality")
78+
DocumentPermissions.MODIFICATION -> permissionsList.add("modification")
79+
else -> permissionsList.add("printing")
80+
}
81+
}
82+
return permissionsList
83+
}
84+
85+
}

example/ios/Podfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ host_cpu = RbConfig::CONFIG["host_cpu"]
3232

3333
target "Runner" do
3434
flutter_install_all_ios_pods __dir__
35-
# # PSPDFKit iOS SDK version specified by PSPDFKit Flutter Plugin. Do not remove this line.
36-
# # Instant iOS SDK version specified by PSPDFKit Flutter Plugin. Do not remove this line.
35+
# PSPDFKit iOS SDK version specified by PSPDFKit Flutter Plugin. Do not remove this line.
36+
# Instant iOS SDK version specified by PSPDFKit Flutter Plugin. Do not remove this line.
3737
use_modular_headers!
3838
end
3939

example/lib/examples.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import 'package:pspdfkit_example/models/papsdkit_example_item.dart';
1515
import 'package:pspdfkit_example/pspdfkit_toolbar_customization.dart';
1616

1717
import 'pspdfkit_annotation_preset_customisation.dart';
18+
import 'pspdfkit_document_example.dart';
1819
import 'pspdfkit_event_listeners_example.dart';
1920
import 'utils/file_utils.dart';
2021
import 'utils/platform_utils.dart';
@@ -67,6 +68,13 @@ List<PspdfkitExampleItem> examples(BuildContext context) => [
6768
description: 'Opens an image document.',
6869
onTap: () => showImage(context),
6970
),
71+
PspdfkitExampleItem(
72+
title: 'Document Example',
73+
description: 'Shows how to get document properties after loading.',
74+
onTap: () async {
75+
await extractAsset(context, _documentPath).then((value) => goTo(
76+
PspdfkitDocumentExample(documentPath: value.path), context));
77+
}),
7078
PspdfkitExampleItem(
7179
title: 'Dark Theme',
7280
description: 'Opens a document in night mode with a custom dark theme.',

example/lib/main.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ void main() {
3232
//
3333
// To set the license key for the currently running platform, use:
3434
// Pspdfkit.setLicenseKey(null);
35-
3635
Pspdfkit.setLicenseKey(null);
3736
runApp(const MyApp());
3837
}

example/lib/pspdfkit_basic_example.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ class PspdfkitBasicExample extends StatelessWidget {
3030
padding: PlatformUtils.isAndroid()
3131
? const EdgeInsets.only(top: kToolbarHeight)
3232
: null,
33-
child: PspdfkitWidget(documentPath: documentPath))));
33+
child: PspdfkitWidget(
34+
documentPath: documentPath,
35+
))));
3436
}
3537
}

0 commit comments

Comments
 (0)