1717import android .provider .Settings ;
1818import android .util .Log ;
1919
20+ import androidx .annotation .NonNull ;
21+ import androidx .core .app .ActivityCompat ;
22+ import androidx .core .content .ContextCompat ;
23+
2024import com .pspdfkit .PSPDFKit ;
21- import com .pspdfkit .ui .PdfActivity ;
25+ import com .pspdfkit .document .PdfDocumentLoader ;
26+ import com .pspdfkit .forms .ChoiceFormElement ;
27+ import com .pspdfkit .forms .EditableButtonFormElement ;
28+ import com .pspdfkit .forms .SignatureFormElement ;
29+ import com .pspdfkit .forms .TextFormElement ;
30+ import com .pspdfkit .ui .PdfActivityIntentBuilder ;
2231
32+ import java .util .ArrayList ;
2333import java .util .HashMap ;
34+ import java .util .Iterator ;
35+ import java .util .List ;
2436import java .util .concurrent .atomic .AtomicReference ;
2537
26- import androidx .annotation .NonNull ;
27- import androidx .core .app .ActivityCompat ;
28- import androidx .core .content .ContextCompat ;
29-
3038import io .flutter .plugin .common .MethodCall ;
3139import io .flutter .plugin .common .MethodChannel ;
3240import io .flutter .plugin .common .MethodChannel .MethodCallHandler ;
3341import io .flutter .plugin .common .MethodChannel .Result ;
3442import io .flutter .plugin .common .PluginRegistry ;
3543import io .flutter .plugin .common .PluginRegistry .Registrar ;
44+ import io .reactivex .android .schedulers .AndroidSchedulers ;
45+ import io .reactivex .schedulers .Schedulers ;
3646
3747import static com .pspdfkit .flutter .pspdfkit .util .Preconditions .requireNotNullNotEmpty ;
3848
@@ -44,10 +54,10 @@ public class PspdfkitPlugin implements MethodCallHandler, PluginRegistry.Request
4454 private static final String FILE_SCHEME = "file:///" ;
4555 private final Context context ;
4656 private final Registrar registrar ;
47- /** Atomic reference that prevents sending twice the permission result and throw exception. */
57+ /** Atomic reference that prevents sending twice the permission result and throwing exception. */
4858 private AtomicReference <Result > permissionRequestResult ;
4959
50- public PspdfkitPlugin (Registrar registrar ) {
60+ private PspdfkitPlugin (Registrar registrar ) {
5161 this .context = registrar .activeContext ();
5262 this .registrar = registrar ;
5363 this .permissionRequestResult = new AtomicReference <>();
@@ -65,7 +75,8 @@ public static void registerWith(Registrar registrar) {
6575
6676 @ Override
6777 public void onMethodCall (@ NonNull MethodCall call , @ NonNull Result result ) {
68- String permission ;
78+ String fullyQualifiedName ;
79+ FlutterPdfActivity flutterPdfActivity ;
6980
7081 switch (call .method ) {
7182 case "frameworkVersion" :
@@ -76,44 +87,198 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
7687 requireNotNullNotEmpty (licenseKey , "License key" );
7788 PSPDFKit .initialize (context , licenseKey );
7889 break ;
90+ case "open" :
91+ String documentPathToOpen = call .argument ("document" );
92+ requireNotNullNotEmpty (documentPathToOpen , "Document path" );
93+
94+ final String documentPathToOpenFixedScheme = addFileSchemeIfMissing (documentPathToOpen );
95+
96+ //noinspection ResultOfMethodCallIgnored
97+ PdfDocumentLoader .openDocumentAsync (context , Uri .parse (documentPathToOpenFixedScheme ))
98+ .subscribeOn (Schedulers .computation ())
99+ .observeOn (AndroidSchedulers .mainThread ())
100+ .subscribe (
101+ pdfDocument -> result .success (pdfDocument .getUid ()),
102+ throwable -> result .error (LOG_TAG ,
103+ String .format ("Error while opening document %s" , documentPathToOpenFixedScheme ),
104+ throwable .getMessage ())
105+ );
106+ break ;
79107 case "present" :
80108 String documentPath = call .argument ("document" );
81109 requireNotNullNotEmpty (documentPath , "Document path" );
82110
83111 HashMap <String , Object > configurationMap = call .argument ("configuration" );
84112 ConfigurationAdapter configurationAdapter = new ConfigurationAdapter (context , configurationMap );
85- if (Uri .parse (documentPath ).getScheme () == null ) {
86- if (documentPath .startsWith ("/" )) {
87- documentPath = documentPath .substring (1 );
88- }
89- documentPath = FILE_SCHEME + documentPath ;
90- }
113+
114+ documentPath = addFileSchemeIfMissing (documentPath );
115+
116+ FlutterPdfActivity .setLoadedDocumentResult (result );
91117 boolean imageDocument = isImageDocument (documentPath );
92118 if (imageDocument ) {
93- PdfActivity .showImage (context , Uri .parse (documentPath ), configurationAdapter .build ());
119+ Intent intent = PdfActivityIntentBuilder .fromImageUri (context , Uri .parse (documentPath ))
120+ .activityClass (FlutterPdfActivity .class )
121+ .configuration (configurationAdapter .build ())
122+ .build ();
123+ context .startActivity (intent );
124+
94125 } else {
95- PdfActivity .showDocument (context , Uri .parse (documentPath ), configurationAdapter .getPassword (), configurationAdapter .build ());
126+ Intent intent = PdfActivityIntentBuilder .fromUri (context , Uri .parse (documentPath ))
127+ .activityClass (FlutterPdfActivity .class )
128+ .configuration (configurationAdapter .build ())
129+ .passwords (configurationAdapter .getPassword ())
130+ .build ();
131+ context .startActivity (intent );
96132 }
97133 break ;
98134 case "checkPermission" :
99- permission = call .argument ("permission" );
100- result .success (checkPermission (permission ));
135+ final String permissionToCheck ;
136+ permissionToCheck = call .argument ("permission" );
137+ result .success (checkPermission (permissionToCheck ));
101138 break ;
102139 case "requestPermission" :
103- permission = call .argument ("permission" );
104- this .permissionRequestResult .set (result );
105- requestPermission (permission );
140+ final String permissionToRequest ;
141+ permissionToRequest = call .argument ("permission" );
142+ permissionRequestResult .set (result );
143+ requestPermission (permissionToRequest );
106144 break ;
107145 case "openSettings" :
108146 openSettings ();
109147 result .success (true );
110148 break ;
149+ case "setFormFieldValue" :
150+ String value = call .argument ("value" );
151+ fullyQualifiedName = call .argument ("fullyQualifiedName" );
152+
153+ requireNotNullNotEmpty (value , "Value" );
154+ requireNotNullNotEmpty (fullyQualifiedName , "Fully qualified name" );
155+ flutterPdfActivity = FlutterPdfActivity .getCurrentActivity ();
156+ if (flutterPdfActivity == null ) {
157+ throw new IllegalStateException ("Before using \" Pspdfkit.setFormFieldValue()\" " +
158+ "the document needs to be presented by calling \" Pspdfkit.present()\" ." );
159+ }
160+
161+ //noinspection ResultOfMethodCallIgnored,ConstantConditions
162+ flutterPdfActivity .getPdfFragment ().getDocument ().getFormProvider ()
163+ .getFormElementWithNameAsync (fullyQualifiedName )
164+ .subscribeOn (Schedulers .computation ())
165+ .observeOn (AndroidSchedulers .mainThread ())
166+ .subscribe (
167+ formElement -> {
168+ if (formElement instanceof TextFormElement ) {
169+ ((TextFormElement ) formElement ).setText (value );
170+ result .success (true );
171+ } else if (formElement instanceof EditableButtonFormElement ) {
172+ if (value .equals ("selected" )) {
173+ ((EditableButtonFormElement ) formElement ).select ();
174+ result .success (true );
175+ } else if (value .equals ("deselected" )) {
176+ ((EditableButtonFormElement ) formElement ).deselect ();
177+ result .success (true );
178+ } else {
179+ result .success (false );
180+ }
181+ } else if (formElement instanceof ChoiceFormElement ) {
182+ List <Integer > selectedIndexes = new ArrayList <>();
183+ if (areValidIndexes (value , selectedIndexes )) {
184+ ((ChoiceFormElement ) formElement ).setSelectedIndexes (selectedIndexes );
185+ result .success (true );
186+ } else {
187+ result .error (LOG_TAG , "\" value\" argument needs a list of " +
188+ "integers to set selected indexes for a choice " +
189+ "form element (e.g.: \" 1, 3, 5\" )." , null );
190+ }
191+ } else if (formElement instanceof SignatureFormElement ) {
192+ result .error ("Signature form elements are not supported." , null , null );
193+ } else {
194+ result .success (false );
195+ }
196+ },
197+ throwable -> result .error (LOG_TAG ,
198+ String .format ("Error while searching for a form element with name %s" , fullyQualifiedName ),
199+ throwable .getMessage ()),
200+ // Form element for the given name not found.
201+ () -> result .success (false )
202+ );
203+ break ;
204+ case "getFormFieldValue" :
205+ fullyQualifiedName = call .argument ("fullyQualifiedName" );
206+
207+ requireNotNullNotEmpty (fullyQualifiedName , "Fully qualified name" );
208+ flutterPdfActivity = FlutterPdfActivity .getCurrentActivity ();
209+ if (flutterPdfActivity == null ) {
210+ throw new IllegalStateException ("Before using \" Pspdfkit.setFormFieldValue()\" " +
211+ "the document needs to be presented by calling \" Pspdfkit.present()\" ." );
212+ }
213+
214+ //noinspection ResultOfMethodCallIgnored,ConstantConditions
215+ flutterPdfActivity .getPdfFragment ().getDocument ().getFormProvider ()
216+ .getFormElementWithNameAsync (fullyQualifiedName )
217+ .subscribeOn (Schedulers .computation ())
218+ .observeOn (AndroidSchedulers .mainThread ())
219+ .subscribe (
220+ formElement -> {
221+ if (formElement instanceof TextFormElement ) {
222+ String text = ((TextFormElement ) formElement ).getText ();
223+ result .success (text );
224+ } else if (formElement instanceof EditableButtonFormElement ) {
225+ boolean isSelected = ((EditableButtonFormElement ) formElement ).isSelected ();
226+ result .success (isSelected ? "selected" : "deselected" );
227+ } else if (formElement instanceof ChoiceFormElement ) {
228+ List <Integer > selectedIndexes = ((ChoiceFormElement ) formElement ).getSelectedIndexes ();
229+ StringBuilder stringBuilder = new StringBuilder ();
230+ Iterator <Integer > iterator = selectedIndexes .iterator ();
231+ while (iterator .hasNext ()) {
232+ stringBuilder .append (iterator .next ());
233+ if (iterator .hasNext ()) {
234+ stringBuilder .append ("," );
235+ }
236+ }
237+ result .success (stringBuilder .toString ());
238+ } else if (formElement instanceof SignatureFormElement ) {
239+ result .error ("Signature form elements are not supported." , null , null );
240+ } else {
241+ result .success (false );
242+ }
243+ },
244+ throwable -> result .error (LOG_TAG ,
245+ String .format ("Error while searching for a form element with name %s" , fullyQualifiedName ),
246+ throwable .getMessage ()),
247+ // Form element for the given name not found.
248+ () -> result .error (LOG_TAG ,
249+ String .format ("Form element not found with name %s" , fullyQualifiedName ),
250+ null )
251+ );
252+ break ;
111253 default :
112254 result .notImplemented ();
113255 break ;
114256 }
115257 }
116258
259+ private boolean areValidIndexes (String value , List <Integer > selectedIndexes ) {
260+ String [] indexes = value .split ("," );
261+ try {
262+ for (String index : indexes ) {
263+ if (index .trim ().isEmpty ()) continue ;
264+ selectedIndexes .add (Integer .parseInt (index .trim ()));
265+ }
266+ } catch (NumberFormatException e ) {
267+ return false ;
268+ }
269+ return true ;
270+ }
271+
272+ private String addFileSchemeIfMissing (String documentPath ) {
273+ if (Uri .parse (documentPath ).getScheme () == null ) {
274+ if (documentPath .startsWith ("/" )) {
275+ documentPath = documentPath .substring (1 );
276+ }
277+ documentPath = FILE_SCHEME + documentPath ;
278+ }
279+ return documentPath ;
280+ }
281+
117282 private void requestPermission (String permission ) {
118283 Activity activity = registrar .activity ();
119284 permission = getManifestPermission (permission );
0 commit comments