Develop and Download Open Source Software

Browse Subversion Repository

Contents of /jpki-pdf-signer/trunk/src/main/java/net/osdn/jpki/pdf_signer/MainApp.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 68 - (show annotations) (download) (as text)
Mon Jan 9 00:38:35 2023 UTC (14 months, 1 week ago) by hirukawa_ryo
File MIME type: text/x-java
File size: 28849 byte(s)
JPKI PDF SIGNER 1.2.7
スプラッシュスクリーンを廃止しました。
画面の一部が再描画されずに白くなってしまうバグの回避策 prism.dirtyopts=false を追加しました。
広域例外ハンドラーを設定しました。
1 package net.osdn.jpki.pdf_signer;
2
3 import javafx.application.Platform;
4 import javafx.beans.binding.Bindings;
5 import javafx.beans.binding.ObjectBinding;
6 import javafx.beans.binding.StringBinding;
7 import javafx.beans.property.BooleanProperty;
8 import javafx.beans.property.ObjectProperty;
9 import javafx.beans.property.SimpleBooleanProperty;
10 import javafx.beans.property.SimpleObjectProperty;
11 import javafx.event.ActionEvent;
12 import javafx.fxml.FXML;
13 import javafx.fxml.Initializable;
14 import javafx.geometry.Rectangle2D;
15 import javafx.scene.Cursor;
16 import javafx.scene.Parent;
17 import javafx.scene.Scene;
18 import javafx.scene.control.Button;
19 import javafx.scene.control.ButtonType;
20 import javafx.scene.control.ListCell;
21 import javafx.scene.control.ListView;
22 import javafx.scene.control.MenuItem;
23 import javafx.scene.control.ProgressIndicator;
24 import javafx.scene.image.Image;
25 import javafx.scene.image.ImageView;
26 import javafx.scene.input.DragEvent;
27 import javafx.scene.input.MouseButton;
28 import javafx.scene.input.MouseEvent;
29 import javafx.scene.input.TransferMode;
30 import javafx.stage.FileChooser;
31 import javafx.stage.Stage;
32 import net.osdn.jpki.pdf_signer.control.LicenseDialog;
33 import net.osdn.jpki.pdf_signer.control.Toast;
34 import net.osdn.jpki.wrapper.JpkiException;
35 import net.osdn.jpki.wrapper.JpkiWrapper;
36 import net.osdn.util.javafx.Unchecked;
37 import net.osdn.util.javafx.application.SingletonApplication;
38 import net.osdn.util.javafx.concurrent.AsyncTask;
39 import net.osdn.util.javafx.fxml.Fxml;
40 import net.osdn.util.javafx.scene.SceneUtil;
41 import net.osdn.util.javafx.scene.control.Dialogs;
42 import net.osdn.util.javafx.scene.control.pdf.Pager;
43 import net.osdn.util.javafx.scene.control.pdf.PdfView;
44 import net.osdn.util.javafx.stage.StageUtil;
45 import org.apache.pdfbox.pdmodel.PDDocument;
46 import org.apache.pdfbox.pdmodel.common.PDRectangle;
47 import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
48 import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSigProperties;
49 import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleSignDesigner;
50
51 import javax.imageio.ImageIO;
52 import java.awt.Desktop;
53 import java.awt.Graphics2D;
54 import java.awt.image.BufferedImage;
55 import java.io.ByteArrayInputStream;
56 import java.io.ByteArrayOutputStream;
57 import java.io.File;
58 import java.io.FileInputStream;
59 import java.io.FileOutputStream;
60 import java.io.IOException;
61 import java.io.InputStream;
62 import java.io.OutputStream;
63 import java.io.UncheckedIOException;
64 import java.net.URI;
65 import java.net.URL;
66 import java.nio.file.Files;
67 import java.nio.file.StandardCopyOption;
68 import java.util.List;
69 import java.util.ResourceBundle;
70 import java.util.concurrent.ExecutorService;
71 import java.util.concurrent.Executors;
72 import java.util.prefs.Preferences;
73
74 public class MainApp extends SingletonApplication implements Initializable {
75
76 public static final String APPLICATION_NAME = "JPKI PDF SIGNER";
77 public static final String APPLICATION_VERSION;
78
79 public static ExecutorService serialExecutor = Executors.newSingleThreadExecutor();
80
81 static {
82 System.setProperty(
83 "org.apache.commons.logging.LogFactory", "net.osdn.jpki.pdf_signer.LogFilter");
84 LogFilter.setLevel("org.apache.pdfbox", LogFilter.Level.ERROR);
85 LogFilter.setLevel("org.apache.fontbox", LogFilter.Level.ERROR);
86
87 int[] version = Datastore.getApplicationVersion();
88 if(version != null) {
89 if (version[2] == 0) {
90 APPLICATION_VERSION = String.format("%d.%d", version[0], version[1]);
91 } else {
92 APPLICATION_VERSION = String.format("%d.%d.%d", version[0], version[1], version[2]);
93 }
94 } else {
95 APPLICATION_VERSION = "";
96 }
97 }
98
99 @Override
100 public void start(Stage primaryStage) throws Exception {
101 primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("/img/app-icon-48px.png")));
102 primaryStage.titleProperty().bind(new StringBinding() {
103 {
104 bind(inputFileProperty);
105 }
106 @Override
107 protected String computeValue() {
108 try {
109 return (inputFileProperty.get() != null ? inputFileProperty.get().getCanonicalPath() + " - " : "")
110 + APPLICATION_NAME + " " + APPLICATION_VERSION;
111 } catch(IOException e) {
112 throw new UncheckedIOException(e);
113 }
114 }
115 });
116
117 primaryStage.showingProperty().addListener((observable, oldValue, newValue) -> {
118 if(oldValue == true && newValue == false) {
119 Platform.exit();
120 }
121 });
122
123 Parent root = Fxml.load(this);
124
125 Scene scene = new Scene(root);
126 scene.setOnDragOver(event -> Unchecked.execute(() -> {
127 scene_onDragOver(event);
128 }));
129 scene.setOnDragDropped(event -> Unchecked.execute(() -> {
130 scene_onDragDropped(event);
131 }));
132 scene.getAccelerators().putAll(pager.createDefaultAccelerators());
133
134 StageUtil.setRestorable(primaryStage, Preferences.userNodeForPackage(getClass()));
135 primaryStage.setOnShown(event -> SceneUtil.invokeAfterLayout(root, Unchecked.runnable(() -> {
136 stage_onReady();
137 })));
138 primaryStage.setMinWidth(448.0);
139 primaryStage.setMinHeight(396.0);
140 primaryStage.setOpacity(0.0);
141 primaryStage.setScene(scene);
142 primaryStage.show();
143
144 //
145 // ������������������������������������
146 //
147 Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> Unchecked.execute(() -> {
148 onCaughtException(thread, exception);
149 }));
150 }
151
152 /** ���������������������������������������������������������������������������������������������
153 *
154 * @param thread ������������������������������������
155 * @param exception ������������������������
156 */
157 protected void onCaughtException(Thread thread, Throwable exception) {
158 exception.printStackTrace();
159
160 Platform.runLater(() -> {
161 try {
162 String title;
163 if(exception instanceof JpkiException) {
164 title = "���������";
165 } else {
166 title = exception.getClass().getName();
167 }
168 String message = exception.getLocalizedMessage();
169 if(message != null) {
170 message = message.trim();
171 }
172 toast.show(Toast.COLOR_ERROR, title, message);
173 } catch(Throwable t) {
174 t.printStackTrace();
175 System.exit(0);
176 }
177 });
178 }
179
180 @FXML Toast toast;
181 @FXML MenuItem menuFileOpen;
182 @FXML MenuItem menuFileSave;
183 @FXML MenuItem menuFileExit;
184 @FXML MenuItem menuHelpAbout;
185 @FXML Pager pager;
186 @FXML PdfView pdfView;
187 @FXML ImageView ivCursor;
188 @FXML ProgressIndicator piSign;
189 @FXML Button btnRemoveSignature;
190 @FXML Button btnEditSignature;
191 @FXML Button btnAddSignature;
192 @FXML ListView<Signature> lvSignature;
193 ObjectBinding<Signature> signatureBinding;
194 ObjectProperty<File> inputFileProperty = new SimpleObjectProperty<File>();
195 ObjectProperty<File> signedTemporaryFileProperty = new SimpleObjectProperty<File>();
196 BooleanProperty busyProperty = new SimpleBooleanProperty();
197
198 @Override
199 public void initialize(URL location, ResourceBundle resources) {
200 lvSignature.setCellFactory(new SignatureListCell.Factory(this));
201
202 //
203 // event handlers
204 //
205 menuFileOpen.setOnAction(event -> Unchecked.execute(() -> {
206 menuFileOpen_onAction(event);
207 }));
208 menuFileSave.setOnAction(event -> Unchecked.execute(() -> {
209 menuFileSave_onAction(event);
210 }));
211 menuFileExit.setOnAction(event -> Unchecked.execute(() -> {
212 menuFileExit_onAction(event);
213 }));
214 menuHelpAbout.setOnAction(event -> Unchecked.execute(() -> {
215 menuHelpAbout_onAction(event);
216 }));
217 pdfView.setOnMouseMoved(event -> Unchecked.execute(() -> {
218 pdfView_onMouseMoved(event);
219 }));
220 pdfView.setOnMouseClicked(event -> Unchecked.execute(() -> {
221 pdfView_onMouseClicked(event);
222 }));
223 btnRemoveSignature.setOnAction(event -> Unchecked.execute(() -> {
224 btnRemoveSignature_onAction(event);
225 }));
226 btnEditSignature.setOnAction(event -> Unchecked.execute(() -> {
227 btnEditSignature_onAction(event);
228 }));
229 btnAddSignature.setOnAction(event -> Unchecked.execute(() -> {
230 btnAddSignature_onAction(event);
231 }));
232
233 //
234 // bindings
235 //
236 signatureBinding = Bindings
237 .when(lvSignature.getSelectionModel().selectedItemProperty().isNotNull())
238 .then(lvSignature.getSelectionModel().selectedItemProperty())
239 .otherwise(Signature.EMPTY);
240
241 menuFileSave.disableProperty().bind(signedTemporaryFileProperty.isNull());
242
243 pager.maxPageIndexProperty().bind(pdfView.maxPageIndexProperty());
244 pager.pageIndexProperty().bindBidirectional(pdfView.pageIndexProperty());
245
246 pdfView.cursorProperty().bind(Bindings
247 .when(pdfView.documentProperty().isNotNull()
248 .and(ivCursor.visibleProperty())
249 .and(ivCursor.imageProperty().isNotNull()))
250 .then(Cursor.NONE)
251 .otherwise(Cursor.DEFAULT));
252
253 ivCursor.imageProperty().bind(Bindings.select(signatureBinding, "image"));
254 ivCursor.scaleXProperty().bind(
255 pdfView.renderScaleProperty().multiply(Bindings.selectDouble(signatureBinding, "imageScaleX")));
256 ivCursor.scaleYProperty().bind(
257 pdfView.renderScaleProperty().multiply(Bindings.selectDouble(signatureBinding, "imageScaleY")));
258 ivCursor.visibleProperty().bind(Bindings
259 .selectBoolean(signatureBinding, "visible")
260 .and(pdfView.hoverProperty()));
261
262 btnRemoveSignature.disableProperty().bind(
263 Bindings.not(Bindings.selectBoolean(signatureBinding, "visible")));
264 btnEditSignature.disableProperty().bind(
265 Bindings.not(Bindings.selectBoolean(signatureBinding, "visible")));
266
267 piSign.visibleProperty().bind(busyProperty);
268
269 toast.maxWidthProperty().bind(getPrimaryStage().widthProperty().subtract(32));
270 toast.maxHeightProperty().bind(getPrimaryStage().heightProperty().subtract(32));
271 }
272
273 void stage_onReady() {
274 getPrimaryStage().setOpacity(1.0);
275
276 lvSignature.getItems().clear();
277 lvSignature.getItems().add(Signature.INVISIBLE);
278 MainApp.serialExecutor.execute(AsyncTask.create(() -> {
279 return Datastore.loadSignatures();
280 }).onSucceeded(signatures -> {
281 for (Signature signature : signatures) {
282 lvSignature.getItems().add(signature);
283 }
284 checkJpkiAvailability();
285 }));
286 }
287
288 void scene_onDragOver(DragEvent event) {
289 if(isAcceptable(getFile(event))) {
290 event.acceptTransferModes(TransferMode.COPY);
291 } else {
292 event.consume();
293 }
294 }
295
296 void scene_onDragDropped(DragEvent event) {
297 File file = getFile(event);
298 if(isAcceptable(file)) {
299 getPrimaryStage().toFront();
300 toast.hide();
301 signedTemporaryFileProperty.set(null);
302 inputFileProperty.set(file);
303 pdfView.load(file);
304 event.setDropCompleted(true);
305 }
306 event.consume();
307 }
308
309 void menuFileOpen_onAction(ActionEvent event) {
310 toast.hide();
311 Preferences preferences = Preferences.userNodeForPackage(getClass());
312
313 FileChooser fc = new FileChooser();
314 fc.setTitle("������");
315 fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF", "*.pdf"));
316
317 String lastOpenDirectory = preferences.get("lastOpenDirectory", null);
318 if(lastOpenDirectory != null) {
319 File dir = new File(lastOpenDirectory);
320 if(dir.isDirectory()) {
321 fc.setInitialDirectory(dir);
322 }
323 }
324 File file = fc.showOpenDialog(getPrimaryStage());
325 if(file != null) {
326 preferences.put("lastOpenDirectory", file.getParentFile().getAbsolutePath());
327 if(isAcceptable(file)) {
328 signedTemporaryFileProperty.set(null);
329 inputFileProperty.set(file);
330 pdfView.load(file);
331 }
332 }
333 }
334
335 void menuFileSave_onAction(ActionEvent event) throws IOException {
336 toast.hide();
337 String defaultName = inputFileProperty.get().getName();
338 int i = defaultName.lastIndexOf('.');
339 if(i > 0) {
340 defaultName = defaultName.substring(0, i);
341 }
342 defaultName += "-signed.pdf";
343
344 FileChooser fc = new FileChooser();
345 fc.setTitle("������������������������");
346 fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF", "*.pdf"));
347 fc.setInitialDirectory(inputFileProperty.get().getParentFile());
348 fc.setInitialFileName(defaultName);
349
350 File file = fc.showSaveDialog(getPrimaryStage());
351 if(file != null) {
352 Files.copy(signedTemporaryFileProperty.get().toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
353 toast.show(Toast.COLOR_SUCCESS, "������������������", file.getPath());
354 }
355 }
356
357 void menuFileExit_onAction(ActionEvent event) {
358 getPrimaryStage().close();
359 }
360
361 void menuHelpAbout_onAction(ActionEvent event) throws IOException {
362 String license = Datastore.getLicense();
363 LicenseDialog dialog = new LicenseDialog(getPrimaryStage(), APPLICATION_NAME + " " + APPLICATION_VERSION, license);
364 dialog.showAndWait();
365 }
366
367 void btnAddSignature_onAction(ActionEvent event) throws IOException {
368 toast.hide();
369 SignatureDialog dialog = new SignatureDialog(getPrimaryStage(), null);
370 Signature newSignature = dialog.showAndWait().orElse(null);
371 if(newSignature == null) {
372 return;
373 }
374 lvSignature.getItems().add(newSignature);
375 Datastore.saveSignatures(lvSignature.getItems().subList(0, lvSignature.getItems().size()));
376 }
377
378 void btnEditSignature_onAction(ActionEvent event) throws IOException {
379 toast.hide();
380 Signature currentSignature = lvSignature.getSelectionModel().getSelectedItem();
381 if(currentSignature == null || currentSignature.getImage() == null) {
382 return;
383 }
384 SignatureDialog dialog = new SignatureDialog(getPrimaryStage(), currentSignature);
385 Signature newSignature = dialog.showAndWait().orElse(null);
386 if(newSignature == null) {
387 return;
388 }
389 lvSignature.getItems().add(lvSignature.getSelectionModel().getSelectedIndex(), newSignature);
390 lvSignature.getItems().remove(lvSignature.getSelectionModel().getSelectedIndex());
391 Datastore.saveSignatures(lvSignature.getItems().subList(0, lvSignature.getItems().size()));
392 }
393
394 void btnRemoveSignature_onAction(ActionEvent event) throws IOException {
395 toast.hide();
396 Signature currentSignature = lvSignature.getSelectionModel().getSelectedItem();
397 if(currentSignature == null || currentSignature.getImage() == null) {
398 return;
399 }
400 ButtonType result = Dialogs.showConfirmation(getPrimaryStage(),
401 "���������������",
402 currentSignature.getTitle() + " ������������������������");
403 if(result != ButtonType.YES) {
404 return;
405 }
406
407 lvSignature.getItems().remove(lvSignature.getSelectionModel().getSelectedIndex());
408 lvSignature.getSelectionModel().clearSelection();
409 Datastore.saveSignatures(lvSignature.getItems().subList(0, lvSignature.getItems().size()));
410 }
411
412 public void lvSignature_cell_onMousePressed(MouseEvent event) throws JpkiException, IOException, ReflectiveOperationException {
413 toast.hide();
414 @SuppressWarnings("unchecked")
415 ListCell<Signature> cell = (ListCell<Signature>)event.getSource();
416
417 //������������������������������������������������������������������������������������������
418 if(cell.isEmpty()) {
419 lvSignature.getSelectionModel().clearSelection();
420 return;
421 }
422
423 Signature signature = cell.getItem();
424 if(signature != Signature.INVISIBLE) {
425 return;
426 }
427
428 try {
429 if(!event.isPrimaryButtonDown()) {
430 return;
431 } else if(pdfView.getDocument() == null) {
432 toast.show(Toast.COLOR_SUCCESS,
433 "������������",
434 "PDF���������������������������������������������������&������������������������������������������");
435 } else if(checkJpkiAvailability()) {
436 ButtonType result = Dialogs.showConfirmation(getPrimaryStage(),
437 APPLICATION_NAME + " " + APPLICATION_VERSION,
438 "������������������������������������������������");
439 if(result == ButtonType.YES) {
440 PDDocument document = pdfView.getDocument();
441 int pageIndex = pdfView.getPageIndex();
442 SignatureOptions options = null;
443
444 busyProperty.set(true);
445 MainApp.serialExecutor.execute(AsyncTask.create(() -> {
446 return sign(document, null, APPLICATION_NAME, APPLICATION_VERSION);
447 }).onSucceeded(tmpFile -> {
448 if(tmpFile != null) {
449 signedTemporaryFileProperty.set(tmpFile);
450 pdfView.load(tmpFile, pageIndex);
451 busyProperty.set(false);
452
453 if(ButtonType.YES == Dialogs.showConfirmation(getPrimaryStage(),
454 APPLICATION_NAME + " " + APPLICATION_VERSION,
455 "������������������������������\n������������������������������������������������������")) {
456 menuFileSave.fire();
457 }
458 }
459 }).onFinished(state -> {
460 busyProperty.set(false);
461 }));
462 }
463 }
464 } finally {
465 lvSignature.getSelectionModel().clearSelection();
466 }
467 }
468
469 public void lvSignature_cell_onMouseClicked(MouseEvent event) {
470 // ������������������������������������������������������������
471 if(event.getButton() != MouseButton.PRIMARY || event.getClickCount() != 2) {
472 return;
473 }
474
475 @SuppressWarnings("unchecked")
476 ListCell<Signature> cell = (ListCell<Signature>)event.getSource();
477
478 // ���������������������������������������
479 Signature signature = cell.getItem();
480 if(signature == Signature.INVISIBLE) {
481 return;
482 }
483
484 if(cell.isEmpty()) {
485 // ���������������������������������������������������������������������������������������������
486 btnAddSignature.fire();
487 } else {
488 // ���������������������������������������������������������������������������������������������
489 btnEditSignature.fire();
490 }
491 }
492
493 void pdfView_onMouseMoved(MouseEvent event) {
494 Image image = ivCursor.getImage();
495 if(image != null) {
496 ivCursor.setLayoutX(event.getX() - (int)(image.getWidth() / 2.0));
497 ivCursor.setLayoutY(event.getY() - (int)(image.getHeight() / 2.0));
498 }
499 }
500
501 void pdfView_onMouseClicked(MouseEvent event) throws JpkiException, IOException, ReflectiveOperationException {
502 toast.hide();
503
504 // ������������������������������������������������������������������������������
505
506 if(event.getButton() != MouseButton.PRIMARY) {
507 return;
508 }
509
510 Rectangle2D renderBounds = pdfView.getRenderBounds();
511 double x = event.getX() - renderBounds.getMinX();
512 double y = event.getY() - renderBounds.getMinY();
513 if(x < 0.0 || y < 0.0 || x > renderBounds.getWidth() || y > renderBounds.getHeight()) {
514 return;
515 }
516
517 Signature signature = signatureBinding.get();
518 if(!signature.isVisible()) {
519 return;
520 }
521
522 if(!checkJpkiAvailability()) {
523 return;
524 }
525
526 PDDocument document = pdfView.getDocument();
527 int pageIndex = pdfView.getPageIndex();
528 int rotation = document.getPage(pageIndex).getRotation();
529 PDRectangle pageMediaBox = document.getPage(pageIndex).getMediaBox();
530
531 PDVisibleSignDesigner designer;
532 try(InputStream is = new FileInputStream(signature.getFile())) {
533 if(rotation == 0) {
534 designer = new PDVisibleSignDesigner(is);
535 designer.width((float)mm2px(signature.getWidthMillis()));
536 designer.height((float)mm2px(signature.getHeightMillis()));
537 double xPt = x * pageMediaBox.getWidth() / renderBounds.getWidth();
538 double yPt = y * pageMediaBox.getHeight() / renderBounds.getHeight();
539 designer.xAxis((float)xPt - designer.getWidth() / 2);
540 designer.yAxis((float)yPt - designer.getHeight() / 2 - pageMediaBox.getHeight());
541 } else {
542 ByteArrayOutputStream buf = new ByteArrayOutputStream();
543 BufferedImage image = ImageIO.read(is);
544 int w1 = image.getWidth();
545 int h1 = image.getHeight();
546 int w2 = (rotation % 180 == 0) ? w1 : h1;
547 int h2 = (rotation % 180 == 0) ? h1 : w1;
548 BufferedImage rotated = new BufferedImage(w2, h2, image.getType());
549 Graphics2D g2d = rotated.createGraphics();
550 g2d.translate((w2 - w1) / 2, (h2 - h1) / 2);
551 g2d.rotate(Math.toRadians(rotation * -1), w1 / 2, h1 / 2);
552 g2d.drawImage(image, null, 0, 0);
553 g2d.dispose();
554 ImageIO.write(rotated, "PNG", buf);
555
556 try(InputStream is2 = new ByteArrayInputStream(buf.toByteArray())) {
557 designer = new PDVisibleSignDesigner(is2);
558 }
559 double xPt;
560 double yPt;
561 switch(rotation) {
562 case 90:
563 designer.width((float)mm2px(signature.getHeightMillis()));
564 designer.height((float)mm2px(signature.getWidthMillis()));
565 xPt = x * pageMediaBox.getHeight() / renderBounds.getWidth();
566 yPt = y * pageMediaBox.getWidth() / renderBounds.getHeight();
567 designer.xAxis((float)yPt - designer.getWidth() / 2);
568 designer.yAxis(- (float)xPt - designer.getHeight() / 2);
569 break;
570 case 180:
571 designer.width((float)mm2px(signature.getWidthMillis()));
572 designer.height((float)mm2px(signature.getHeightMillis()));
573 xPt = x * pageMediaBox.getWidth() / renderBounds.getWidth();
574 yPt = y * pageMediaBox.getHeight() / renderBounds.getHeight();
575 designer.xAxis(- (float)xPt - designer.getWidth() / 2 + pageMediaBox.getWidth());
576 designer.yAxis(- (float)yPt - designer.getHeight() / 2);
577 break;
578 case 270:
579 designer.width((float)mm2px(signature.getHeightMillis()));
580 designer.height((float)mm2px(signature.getWidthMillis()));
581 xPt = x * pageMediaBox.getHeight() / renderBounds.getWidth();
582 yPt = y * pageMediaBox.getWidth() / renderBounds.getHeight();
583 designer.xAxis(- (float)yPt - designer.getWidth() / 2 + pageMediaBox.getWidth());
584 designer.yAxis((float)xPt - designer.getHeight() / 2 - pageMediaBox.getHeight());
585 break;
586 }
587 }
588 }
589
590 PDVisibleSigProperties props = new PDVisibleSigProperties();
591 props.setPdVisibleSignature(designer);
592 props.visualSignEnabled(true);
593 props.page(pageIndex + 1);
594 props.buildSignature();
595
596 SignatureOptions options = new SignatureOptions();
597 options.setPage(pageIndex);
598 options.setVisualSignature(props);
599
600 lvSignature.getSelectionModel().clearSelection();
601 busyProperty.set(true);
602 MainApp.serialExecutor.execute(AsyncTask.create(() -> {
603 return sign(document, options, APPLICATION_NAME, APPLICATION_VERSION);
604 }).onSucceeded(tmpFile -> {
605 if(tmpFile != null) {
606 signedTemporaryFileProperty.set(tmpFile);
607 pdfView.load(tmpFile, pageIndex);
608 busyProperty.set(false);
609
610 if(ButtonType.YES == Dialogs.showConfirmation(getPrimaryStage(), APPLICATION_NAME + " " + APPLICATION_VERSION,
611 "������������������������������\n������������������������������������������������������")) {
612 menuFileSave.fire();
613 }
614 lvSignature.getSelectionModel().clearSelection();
615 }
616 }).onFinished(state -> {
617 busyProperty.set(false);
618 }));
619 }
620
621 protected File getFile(DragEvent event) {
622 if(event.getDragboard().hasFiles()) {
623 List<File> files = event.getDragboard().getFiles();
624 if(files.size() == 1) {
625 return files.get(0);
626 }
627 }
628 return null;
629 }
630
631 protected boolean isAcceptable(File file) {
632 return file != null && file.getName().matches("(?i).+(\\.pdf)");
633 }
634
635 protected boolean checkJpkiAvailability() {
636 boolean isAvailable = JpkiWrapper.isAvailable();
637 if(!isAvailable) {
638 toast.show(
639 Toast.COLOR_SUCCESS,
640 "������������",
641 "JPKI ������������������������������������������������������������������������������\n" +
642 "���������������������������������������������������������������������������������������������",
643 Unchecked.runnable(() -> {
644 toast.hide();
645 Desktop.getDesktop().browse(URI.create("https://www.jpki.go.jp/download/win.html"));
646 }));
647 }
648 return isAvailable;
649 }
650
651 protected File sign(PDDocument document, SignatureOptions options, String applicationName, String applicationVersion) throws JpkiException, IOException, ReflectiveOperationException {
652 File tmpFile = Datastore.getMyDataDirectory(true).resolve("output.tmp").toFile();
653 try (OutputStream output = new FileOutputStream(tmpFile)) {
654 output.flush();
655 JpkiWrapper jpki = new JpkiWrapper();
656 jpki.setApplicationName(applicationName);
657 jpki.setApplicationVersion(applicationVersion);
658 jpki.addSignature(output, document, options);
659 return tmpFile;
660 } catch(JpkiException e) {
661 //���������������������������������������������������������������������������������������������
662 if(e.getWinErrorCode() != JpkiException.SCARD_W_CANCELLED_BY_USER) {
663 throw e;
664 }
665 }
666 return null;
667 }
668
669 public static double mm2px(double mm) {
670 return mm * 72.0 / 25.4;
671 }
672 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26