diff --git a/build.gradle b/build.gradle index 3bafdbb9..102bbfa0 100644 --- a/build.gradle +++ b/build.gradle @@ -97,6 +97,7 @@ dependencies { implementation('io.reactivex.rxjava2:rxjavafx:2.2.2') implementation('org.apache.commons:commons-lang3:3.7') implementation('net.sourceforge.streamsupport:streamsupport:1.7.0') + implementation('com.github.librepdf:openpdf:1.3.27') testImplementation('junit:junit:4.12') } diff --git a/src/main/java/com/sparrowwallet/sparrow/control/DescriptorQRDisplayDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/DescriptorQRDisplayDialog.java new file mode 100644 index 00000000..c846ca0d --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/DescriptorQRDisplayDialog.java @@ -0,0 +1,73 @@ +package com.sparrowwallet.sparrow.control; + +import com.lowagie.text.*; +import com.lowagie.text.Font; +import com.lowagie.text.Image; +import com.lowagie.text.pdf.PdfWriter; +import com.sparrowwallet.hummingbird.UR; +import com.sparrowwallet.hummingbird.UREncoder; +import com.sparrowwallet.sparrow.AppServices; +import javafx.embed.swing.SwingFXUtils; +import javafx.event.ActionEvent; +import javafx.scene.control.*; +import javafx.scene.control.Button; +import javafx.stage.FileChooser; +import javafx.stage.Stage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +import java.io.File; +import java.io.FileOutputStream; + +public class DescriptorQRDisplayDialog extends QRDisplayDialog { + private static final Logger log = LoggerFactory.getLogger(DescriptorQRDisplayDialog.class); + + public DescriptorQRDisplayDialog(String walletName, String outputDescriptor, UR ur) { + super(ur); + + DialogPane dialogPane = getDialogPane(); + final ButtonType pdfButtonType = new javafx.scene.control.ButtonType("Save PDF...", ButtonBar.ButtonData.HELP_2); + dialogPane.getButtonTypes().add(pdfButtonType); + + Button pdfButton = (Button)dialogPane.lookupButton(pdfButtonType); + pdfButton.addEventFilter(ActionEvent.ACTION, event -> { + savePdf(walletName, outputDescriptor, ur); + event.consume(); + }); + } + + private void savePdf(String walletName, String outputDescriptor, UR ur) { + Stage window = new Stage(); + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("Save PDF"); + fileChooser.setInitialFileName(walletName + ".pdf"); + AppServices.moveToActiveWindowScreen(window, 800, 450); + File file = fileChooser.showSaveDialog(window); + if(file != null) { + try(Document document = new Document()) { + document.setMargins(36, 36, 48, 36); + PdfWriter.getInstance(document, new FileOutputStream(file)); + document.open(); + + Font titleFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 16, Color.BLACK); + Chunk title = new Chunk("Output descriptor for " + walletName, titleFont); + document.add(title); + + UREncoder urEncoder = new UREncoder(ur, 2000, 10, 0); + String fragment = urEncoder.nextPart(); + if(urEncoder.isSinglePart()) { + Image image = Image.getInstance(SwingFXUtils.fromFXImage(getQrCode(fragment), null), Color.WHITE); + document.add(image); + } + + Font descriptorFont = FontFactory.getFont(FontFactory.COURIER, 14, Color.BLACK); + Paragraph descriptor = new Paragraph(outputDescriptor, descriptorFont); + document.add(descriptor); + } catch(Exception e) { + log.error("Error creating descriptor PDF", e); + AppServices.showErrorDialog("Error creating PDF", e.getMessage()); + } + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/control/QRDisplayDialog.java b/src/main/java/com/sparrowwallet/sparrow/control/QRDisplayDialog.java index 92b4f0c3..8fcd4ccf 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/QRDisplayDialog.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/QRDisplayDialog.java @@ -137,7 +137,7 @@ public class QRDisplayDialog extends Dialog { } } - private Image getQrCode(String fragment) { + protected Image getQrCode(String fragment) { try { QRCodeWriter qrCodeWriter = new QRCodeWriter(); BitMatrix qrMatrix = qrCodeWriter.encode(fragment, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT); diff --git a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java index c6c20fca..3e45efd4 100644 --- a/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java @@ -324,6 +324,7 @@ public class SettingsController extends WalletFormController implements Initiali return; } + OutputDescriptor outputDescriptor = OutputDescriptor.getOutputDescriptor(walletForm.getWallet(), KeyPurpose.DEFAULT_PURPOSES, null); List scriptExpressions = getScriptExpressions(walletForm.getWallet().getScriptType()); CryptoOutput cryptoOutput; @@ -341,7 +342,7 @@ public class SettingsController extends WalletFormController implements Initiali } UR cryptoOutputUR = cryptoOutput.toUR(); - QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(cryptoOutputUR); + QRDisplayDialog qrDisplayDialog = new DescriptorQRDisplayDialog(walletForm.getWallet().getFullDisplayName(), outputDescriptor.toString(true), cryptoOutputUR); qrDisplayDialog.showAndWait(); } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index cb233e22..d24f4122 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -44,4 +44,5 @@ open module com.sparrowwallet.sparrow { requires org.apache.commons.lang3; requires net.sourceforge.streamsupport; requires co.nstant.in.cbor; + requires com.github.librepdf.openpdf; } \ No newline at end of file