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 .forms .ChoiceFormElement ;
26+ import com .pspdfkit .forms .EditableButtonFormElement ;
27+ import com .pspdfkit .forms .SignatureFormElement ;
28+ import com .pspdfkit .forms .TextFormElement ;
29+ import com .pspdfkit .ui .PdfActivityIntentBuilder ;
2230
31+ import java .util .ArrayList ;
2332import java .util .HashMap ;
33+ import java .util .Iterator ;
34+ import java .util .List ;
2435import java .util .concurrent .atomic .AtomicReference ;
2536
26- import androidx .annotation .NonNull ;
27- import androidx .core .app .ActivityCompat ;
28- import androidx .core .content .ContextCompat ;
29-
3037import io .flutter .plugin .common .MethodCall ;
3138import io .flutter .plugin .common .MethodChannel ;
3239import io .flutter .plugin .common .MethodChannel .MethodCallHandler ;
3340import io .flutter .plugin .common .MethodChannel .Result ;
3441import io .flutter .plugin .common .PluginRegistry ;
3542import io .flutter .plugin .common .PluginRegistry .Registrar ;
43+ import io .reactivex .android .schedulers .AndroidSchedulers ;
44+ import io .reactivex .schedulers .Schedulers ;
3645
3746import static com .pspdfkit .flutter .pspdfkit .util .Preconditions .requireNotNullNotEmpty ;
3847
@@ -44,10 +53,10 @@ public class PspdfkitPlugin implements MethodCallHandler, PluginRegistry.Request
4453 private static final String FILE_SCHEME = "file:///" ;
4554 private final Context context ;
4655 private final Registrar registrar ;
47- /** Atomic reference that prevents sending twice the permission result and throw exception. */
56+ /** Atomic reference that prevents sending twice the permission result and throwing exception. */
4857 private AtomicReference <Result > permissionRequestResult ;
4958
50- public PspdfkitPlugin (Registrar registrar ) {
59+ private PspdfkitPlugin (Registrar registrar ) {
5160 this .context = registrar .activeContext ();
5261 this .registrar = registrar ;
5362 this .permissionRequestResult = new AtomicReference <>();
@@ -65,7 +74,8 @@ public static void registerWith(Registrar registrar) {
6574
6675 @ Override
6776 public void onMethodCall (@ NonNull MethodCall call , @ NonNull Result result ) {
68- String permission ;
77+ String fullyQualifiedName ;
78+ FlutterPdfActivity flutterPdfActivity ;
6979
7080 switch (call .method ) {
7181 case "frameworkVersion" :
@@ -82,38 +92,188 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
8292
8393 HashMap <String , Object > configurationMap = call .argument ("configuration" );
8494 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- }
95+
96+ documentPath = addFileSchemeIfMissing (documentPath );
97+
98+ FlutterPdfActivity .setLoadedDocumentResult (result );
9199 boolean imageDocument = isImageDocument (documentPath );
92100 if (imageDocument ) {
93- PdfActivity .showImage (context , Uri .parse (documentPath ), configurationAdapter .build ());
101+ Intent intent = PdfActivityIntentBuilder .fromImageUri (context , Uri .parse (documentPath ))
102+ .activityClass (FlutterPdfActivity .class )
103+ .configuration (configurationAdapter .build ())
104+ .build ();
105+ context .startActivity (intent );
106+
94107 } else {
95- PdfActivity .showDocument (context , Uri .parse (documentPath ), configurationAdapter .getPassword (), configurationAdapter .build ());
108+ Intent intent = PdfActivityIntentBuilder .fromUri (context , Uri .parse (documentPath ))
109+ .activityClass (FlutterPdfActivity .class )
110+ .configuration (configurationAdapter .build ())
111+ .passwords (configurationAdapter .getPassword ())
112+ .build ();
113+ context .startActivity (intent );
96114 }
97115 break ;
98116 case "checkPermission" :
99- permission = call .argument ("permission" );
100- result .success (checkPermission (permission ));
117+ final String permissionToCheck ;
118+ permissionToCheck = call .argument ("permission" );
119+ result .success (checkPermission (permissionToCheck ));
101120 break ;
102121 case "requestPermission" :
103- permission = call .argument ("permission" );
104- this .permissionRequestResult .set (result );
105- requestPermission (permission );
122+ final String permissionToRequest ;
123+ permissionToRequest = call .argument ("permission" );
124+ permissionRequestResult .set (result );
125+ requestPermission (permissionToRequest );
106126 break ;
107127 case "openSettings" :
108128 openSettings ();
109129 result .success (true );
130+ break ;
131+ case "setFormFieldValue" :
132+ String value = call .argument ("value" );
133+ fullyQualifiedName = call .argument ("fullyQualifiedName" );
134+
135+ requireNotNullNotEmpty (value , "Value" );
136+ requireNotNullNotEmpty (fullyQualifiedName , "Fully qualified name" );
137+ flutterPdfActivity = FlutterPdfActivity .getCurrentActivity ();
138+ if (flutterPdfActivity == null ) {
139+ throw new IllegalStateException ("Before using \" Pspdfkit.setFormFieldValue()\" " +
140+ "the document needs to be presented by calling \" Pspdfkit.present()\" ." );
141+ }
142+
143+ //noinspection ResultOfMethodCallIgnored,ConstantConditions
144+ flutterPdfActivity .getPdfFragment ().getDocument ().getFormProvider ()
145+ .getFormElementWithNameAsync (fullyQualifiedName )
146+ .subscribeOn (Schedulers .computation ())
147+ .observeOn (AndroidSchedulers .mainThread ())
148+ .subscribe (
149+ formElement -> {
150+ if (formElement instanceof TextFormElement ) {
151+ ((TextFormElement ) formElement ).setText (value );
152+ result .success (true );
153+ } else if (formElement instanceof EditableButtonFormElement ) {
154+ if (value .equals ("selected" )) {
155+ ((EditableButtonFormElement ) formElement ).select ();
156+ result .success (true );
157+ } else if (value .equals ("deselected" )) {
158+ ((EditableButtonFormElement ) formElement ).deselect ();
159+ result .success (true );
160+ } else {
161+ result .success (false );
162+ }
163+ } else if (formElement instanceof ChoiceFormElement ) {
164+ List <Integer > selectedIndexes = new ArrayList <>();
165+ if (areValidIndexes (value , selectedIndexes )) {
166+ ((ChoiceFormElement ) formElement ).setSelectedIndexes (selectedIndexes );
167+ result .success (true );
168+ } else {
169+ result .error (LOG_TAG , "\" value\" argument needs a list of " +
170+ "integers to set selected indexes for a choice " +
171+ "form element (e.g.: \" 1, 3, 5\" )." , null );
172+ }
173+ } else if (formElement instanceof SignatureFormElement ) {
174+ result .error ("Signature form elements are not supported." , null , null );
175+ } else {
176+ result .success (false );
177+ }
178+ },
179+ throwable -> result .error (LOG_TAG ,
180+ String .format ("Error while searching for a form element with name %s" , fullyQualifiedName ),
181+ throwable .getMessage ()),
182+ // Form element for the given name not found.
183+ () -> result .success (false )
184+ );
185+ break ;
186+ case "getFormFieldValue" :
187+ fullyQualifiedName = call .argument ("fullyQualifiedName" );
188+
189+ requireNotNullNotEmpty (fullyQualifiedName , "Fully qualified name" );
190+ flutterPdfActivity = FlutterPdfActivity .getCurrentActivity ();
191+ if (flutterPdfActivity == null ) {
192+ throw new IllegalStateException ("Before using \" Pspdfkit.setFormFieldValue()\" " +
193+ "the document needs to be presented by calling \" Pspdfkit.present()\" ." );
194+ }
195+
196+ //noinspection ResultOfMethodCallIgnored,ConstantConditions
197+ flutterPdfActivity .getPdfFragment ().getDocument ().getFormProvider ()
198+ .getFormElementWithNameAsync (fullyQualifiedName )
199+ .subscribeOn (Schedulers .computation ())
200+ .observeOn (AndroidSchedulers .mainThread ())
201+ .subscribe (
202+ formElement -> {
203+ if (formElement instanceof TextFormElement ) {
204+ String text = ((TextFormElement ) formElement ).getText ();
205+ result .success (text );
206+ } else if (formElement instanceof EditableButtonFormElement ) {
207+ boolean isSelected = ((EditableButtonFormElement ) formElement ).isSelected ();
208+ result .success (isSelected ? "selected" : "deselected" );
209+ } else if (formElement instanceof ChoiceFormElement ) {
210+ List <Integer > selectedIndexes = ((ChoiceFormElement ) formElement ).getSelectedIndexes ();
211+ StringBuilder stringBuilder = new StringBuilder ();
212+ Iterator <Integer > iterator = selectedIndexes .iterator ();
213+ while (iterator .hasNext ()) {
214+ stringBuilder .append (iterator .next ());
215+ if (iterator .hasNext ()) {
216+ stringBuilder .append ("," );
217+ }
218+ }
219+ result .success (stringBuilder .toString ());
220+ } else if (formElement instanceof SignatureFormElement ) {
221+ result .error ("Signature form elements are not supported." , null , null );
222+ } else {
223+ result .success (false );
224+ }
225+ },
226+ throwable -> result .error (LOG_TAG ,
227+ String .format ("Error while searching for a form element with name %s" , fullyQualifiedName ),
228+ throwable .getMessage ()),
229+ // Form element for the given name not found.
230+ () -> result .error (LOG_TAG ,
231+ String .format ("Form element not found with name %s" , fullyQualifiedName ),
232+ null )
233+ );
234+ break ;
235+ case "save" :
236+ flutterPdfActivity = FlutterPdfActivity .getCurrentActivity ();
237+ if (flutterPdfActivity == null ) {
238+ throw new IllegalStateException ("Before using \" Pspdfkit.save()\" " +
239+ "the document needs to be presented by calling \" Pspdfkit.present()\" ." );
240+ }
241+ //noinspection ResultOfMethodCallIgnored,ConstantConditions
242+ flutterPdfActivity .getPdfFragment ().getDocument ().saveIfModifiedAsync ()
243+ .subscribeOn (Schedulers .computation ())
244+ .observeOn (AndroidSchedulers .mainThread ())
245+ .subscribe (result ::success );
246+
110247 break ;
111248 default :
112249 result .notImplemented ();
113250 break ;
114251 }
115252 }
116253
254+ private boolean areValidIndexes (String value , List <Integer > selectedIndexes ) {
255+ String [] indexes = value .split ("," );
256+ try {
257+ for (String index : indexes ) {
258+ if (index .trim ().isEmpty ()) continue ;
259+ selectedIndexes .add (Integer .parseInt (index .trim ()));
260+ }
261+ } catch (NumberFormatException e ) {
262+ return false ;
263+ }
264+ return true ;
265+ }
266+
267+ private String addFileSchemeIfMissing (String documentPath ) {
268+ if (Uri .parse (documentPath ).getScheme () == null ) {
269+ if (documentPath .startsWith ("/" )) {
270+ documentPath = documentPath .substring (1 );
271+ }
272+ documentPath = FILE_SCHEME + documentPath ;
273+ }
274+ return documentPath ;
275+ }
276+
117277 private void requestPermission (String permission ) {
118278 Activity activity = registrar .activity ();
119279 permission = getManifestPermission (permission );
0 commit comments