1import 'dart:async';
2import 'dart:io' show Platform;
3
4import 'package:flutter/material.dart';
5import 'package:flutter/services.dart';
6import 'package:pdftron_flutter/pdftron_flutter.dart';
7// If you are using local files, add the permission_handler
8// dependency to pubspec.yaml and uncomment the line below.
9// import 'package:permission_handler/permission_handler.dart';
10
11void main() => runApp(MyApp());
12
13class MyApp extends StatelessWidget {
14 @override
15 Widget build(BuildContext context) {
16 return MaterialApp(
17 home: Viewer(),
18 );
19 }
20}
21
22class Viewer extends StatefulWidget {
23 @override
24 _ViewerState createState() => _ViewerState();
25}
26
27class _ViewerState extends State<Viewer> {
28 String _version = 'Unknown';
29 String _document =
30 "https://pdftron.s3.amazonaws.com/downloads/pl/PDFTRON_mobile_about.pdf";
31 bool _showViewer = true;
32
33 @override
34 void initState() {
35 super.initState();
36 initPlatformState();
37
38 showViewer();
39
40 // If you are using local files:
41 // * Remove the above line `showViewer();`.
42 // * Change the _document field to your local filepath.
43 // * Uncomment the section below, including launchWithPermission().
44 // if (Platform.isIOS) {
45 // showViewer(); // Permission not required for iOS.
46 // } else {
47 // launchWithPermission(); // Permission required for Android.
48 // }
49 }
50
51 // Uncomment this if you are using local files:
52 // Future<void> launchWithPermission() async {
53 // PermissionStatus permission = await Permission.storage.request();
54 // if (permission.isGranted) {
55 // showViewer();
56 // }
57 // }
58
59 // Platform messages are asynchronous, so initialize in an async method.
60 Future<void> initPlatformState() async {
61 String version;
62 // Platform messages may fail, so use a try/catch PlatformException.
63 try {
64 // Initializes the Apryse SDK, it must be called before you can use
65 // any functionality.
66 PdftronFlutter.initialize("your_pdftron_license_key");
67
68 version = await PdftronFlutter.version;
69 } on PlatformException {
70 version = 'Failed to get platform version.';
71 }
72
73 // If the widget was removed from the tree while the asynchronous platform
74 // message was in flight, we want to discard the reply rather than calling
75 // setState to update our non-existent appearance.
76 if (!mounted) return;
77
78 setState(() {
79 _version = version;
80 });
81 }
82
83 void showViewer() async {
84 // Opening without a config file will have all functionality enabled.
85 // await PdftronFlutter.openDocument(_document);
86
87 var config = Config();
88 // How to disable functionality:
89 // config.disabledElements = [Buttons.shareButton, Buttons.searchButton];
90 // config.disabledTools = [Tools.annotationCreateLine, Tools.annotationCreateRectangle];
91 // Other viewer configurations:
92 // config.multiTabEnabled = true;
93 // config.customHeaders = {'headerName': 'headerValue'};
94
95 // An event listener for document loading.
96 var documentLoadedCancel = startDocumentLoadedListener((filePath) {
97 print("document loaded: $filePath");
98 });
99
100 await PdftronFlutter.openDocument(_document, config: config);
101
102 try {
103 // The imported command is in XFDF format and tells whether to add,
104 // modify or delete annotations in the current document.
105 PdftronFlutter.importAnnotationCommand(
106 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
107 " <xfdf xmlns=\"http://ns.adobe.com/xfdf/\" xml:space=\"preserve\">\n" +
108 " <add>\n" +
109 " <square style=\"solid\" width=\"5\" color=\"#E44234\" opacity=\"1\" creationdate=\"D:20200619203211Z\" flags=\"print\" date=\"D:20200619203211Z\" name=\"c684da06-12d2-4ccd-9361-0a1bf2e089e3\" page=\"1\" rect=\"113.312,277.056,235.43,350.173\" title=\"\" />\n" +
110 " </add>\n" +
111 " <modify />\n" +
112 " <delete />\n" +
113 " <pdf-info import-version=\"3\" version=\"2\" xmlns=\"http://www.pdftron.com/pdfinfo\" />\n" +
114 " </xfdf>");
115 } on PlatformException catch (e) {
116 print("Failed to importAnnotationCommand '${e.message}'.");
117 }
118
119 try {
120 PdftronFlutter.importBookmarkJson('{"0":"Page 1"}');
121 } on PlatformException catch (e) {
122 print("Failed to importBookmarkJson '${e.message}'.");
123 }
124
125 // An event listener for when local annotation changes are committed to the document.
126 // xfdfCommand is the XFDF Command of the annotation that was last changed.
127 var annotCancel = startExportAnnotationCommandListener((xfdfCommand) {
128 String command = xfdfCommand;
129 print("flutter xfdfCommand:\n");
130 // Dart limits how many characters are printed onto the console.
131 // The code below ensures that all of the XFDF command is printed.
132 if (command.length > 1024) {
133 int start = 0;
134 int end = 1023;
135 while (end < command.length) {
136 print(command.substring(start, end) + "\n");
137 start += 1024;
138 end += 1024;
139 }
140 print(command.substring(start));
141 } else {
142 print("flutter xfdfCommand:\n $command");
143 }
144 });
145
146 // An event listener for when local bookmark changes are committed to
147 // the document. bookmarkJson is the JSON string containing all the
148 // bookmarks that exist when the change was made.
149 var bookmarkCancel = startExportBookmarkListener((bookmarkJson) {
150 print("flutter bookmark: $bookmarkJson");
151 });
152
153 var path = await PdftronFlutter.saveDocument();
154 print("flutter save: $path");
155
156 // To cancel event:
157 // annotCancel();
158 // bookmarkCancel();
159 // documentLoadedCancel();
160 }
161
162 @override
163 Widget build(BuildContext context) {
164 return Scaffold(
165 body: Container(
166 width: double.infinity,
167 height: double.infinity,
168 child:
169 // Uncomment this to use Widget version of the viewer:
170 // _showViewer
171 // ? DocumentView(
172 // onCreated: _onDocumentViewCreated,
173 // ):
174 Container(),
175 ),
176 );
177 }
178
179 // This function is used to control the DocumentView widget after it
180 // has been created. The widget will not work without a void
181 // Function(DocumentViewController controller) being passed to it.
182 void _onDocumentViewCreated(DocumentViewController controller) async {
183 Config config = new Config();
184
185 var leadingNavCancel = startLeadingNavButtonPressedListener(() {
186 // Uncomment this to quit viewer when leading navigation button is pressed:
187 // this.setState(() {
188 // _showViewer = !_showViewer;
189 // });
190
191 // Show a dialog when leading navigation button is pressed.
192 _showMyDialog();
193 });
194
195 controller.openDocument(_document, config: config);
196 }
197
198 Future<void> _showMyDialog() async {
199 print('hello');
200 return showDialog<void>(
201 context: context,
202 barrierDismissible: false, // User must tap button!
203 builder: (BuildContext context) {
204 return AlertDialog(
205 title: Text('AlertDialog'),
206 content: SingleChildScrollView(
207 child: Text('Leading navigation button has been pressed.'),
208 ),
209 actions: <Widget>[
210 TextButton(
211 child: Text('OK'),
212 onPressed: () {
213 Navigator.of(context).pop();
214 },
215 ),
216 ],
217 );
218 },
219 );
220 }
221}