mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-25 13:16:44 +00:00
change qr code density for ur encoding via qr dialog button
This commit is contained in:
parent
e39a2cb944
commit
c9288ab25b
5 changed files with 106 additions and 14 deletions
|
@ -0,0 +1,22 @@
|
||||||
|
package com.sparrowwallet.sparrow.control;
|
||||||
|
|
||||||
|
public enum QRDensity {
|
||||||
|
NORMAL("Normal", 250),
|
||||||
|
LOW("Low", 80);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final int maxFragmentLength;
|
||||||
|
|
||||||
|
QRDensity(String name, int maxFragmentLength) {
|
||||||
|
this.name = name;
|
||||||
|
this.maxFragmentLength = maxFragmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxFragmentLength() {
|
||||||
|
return maxFragmentLength;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import com.sparrowwallet.hummingbird.LegacyUREncoder;
|
||||||
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
import com.sparrowwallet.hummingbird.registry.RegistryType;
|
||||||
import com.sparrowwallet.sparrow.AppServices;
|
import com.sparrowwallet.sparrow.AppServices;
|
||||||
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
import com.sparrowwallet.sparrow.glyphfont.FontAwesome5;
|
||||||
|
import com.sparrowwallet.sparrow.io.Config;
|
||||||
import com.sparrowwallet.sparrow.io.ImportException;
|
import com.sparrowwallet.sparrow.io.ImportException;
|
||||||
import com.sparrowwallet.hummingbird.UR;
|
import com.sparrowwallet.hummingbird.UR;
|
||||||
import com.sparrowwallet.hummingbird.UREncoder;
|
import com.sparrowwallet.hummingbird.UREncoder;
|
||||||
|
@ -28,13 +29,13 @@ import org.slf4j.LoggerFactory;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class QRDisplayDialog extends Dialog<UR> {
|
public class QRDisplayDialog extends Dialog<UR> {
|
||||||
private static final Logger log = LoggerFactory.getLogger(QRDisplayDialog.class);
|
private static final Logger log = LoggerFactory.getLogger(QRDisplayDialog.class);
|
||||||
|
|
||||||
private static final int MIN_FRAGMENT_LENGTH = 10;
|
private static final int MIN_FRAGMENT_LENGTH = 10;
|
||||||
private static final int MAX_FRAGMENT_LENGTH = 250;
|
|
||||||
|
|
||||||
private static final int ANIMATION_PERIOD_MILLIS = 200;
|
private static final int ANIMATION_PERIOD_MILLIS = 200;
|
||||||
|
|
||||||
|
@ -42,17 +43,20 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
private static final int QR_HEIGHT = 480;
|
private static final int QR_HEIGHT = 480;
|
||||||
|
|
||||||
private final UR ur;
|
private final UR ur;
|
||||||
private final UREncoder encoder;
|
private UREncoder encoder;
|
||||||
|
|
||||||
private final ImageView qrImageView;
|
private final ImageView qrImageView;
|
||||||
|
|
||||||
private AnimateQRService animateQRService;
|
private AnimateQRService animateQRService;
|
||||||
private String currentPart;
|
private String currentPart;
|
||||||
|
|
||||||
|
private boolean addLegacyEncodingOption;
|
||||||
private boolean useLegacyEncoding;
|
private boolean useLegacyEncoding;
|
||||||
private String[] legacyParts;
|
private String[] legacyParts;
|
||||||
private int legacyPartIndex;
|
private int legacyPartIndex;
|
||||||
|
|
||||||
|
private static boolean initialDensityChange;
|
||||||
|
|
||||||
public QRDisplayDialog(String type, byte[] data, boolean addLegacyEncodingOption) throws UR.URException {
|
public QRDisplayDialog(String type, byte[] data, boolean addLegacyEncodingOption) throws UR.URException {
|
||||||
this(UR.fromBytes(type, data), addLegacyEncodingOption);
|
this(UR.fromBytes(type, data), addLegacyEncodingOption);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +67,8 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
|
|
||||||
public QRDisplayDialog(UR ur, boolean addLegacyEncodingOption) {
|
public QRDisplayDialog(UR ur, boolean addLegacyEncodingOption) {
|
||||||
this.ur = ur;
|
this.ur = ur;
|
||||||
this.encoder = new UREncoder(ur, MAX_FRAGMENT_LENGTH, MIN_FRAGMENT_LENGTH, 0);
|
this.addLegacyEncodingOption = addLegacyEncodingOption;
|
||||||
|
this.encoder = new UREncoder(ur, Config.get().getQrDensity().getMaxFragmentLength(), MIN_FRAGMENT_LENGTH, 0);
|
||||||
|
|
||||||
final DialogPane dialogPane = new QRDisplayDialogPane();
|
final DialogPane dialogPane = new QRDisplayDialogPane();
|
||||||
setDialogPane(dialogPane);
|
setDialogPane(dialogPane);
|
||||||
|
@ -88,6 +93,9 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
if(addLegacyEncodingOption) {
|
if(addLegacyEncodingOption) {
|
||||||
final ButtonType legacyEncodingButtonType = new javafx.scene.control.ButtonType("Use Legacy Encoding (Cobo Vault)", ButtonBar.ButtonData.LEFT);
|
final ButtonType legacyEncodingButtonType = new javafx.scene.control.ButtonType("Use Legacy Encoding (Cobo Vault)", ButtonBar.ButtonData.LEFT);
|
||||||
dialogPane.getButtonTypes().add(legacyEncodingButtonType);
|
dialogPane.getButtonTypes().add(legacyEncodingButtonType);
|
||||||
|
} else {
|
||||||
|
final ButtonType densityButtonType = new javafx.scene.control.ButtonType("Change Density", ButtonBar.ButtonData.LEFT);
|
||||||
|
dialogPane.getButtonTypes().add(densityButtonType);
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogPane.setPrefWidth(40 + QR_WIDTH + 40);
|
dialogPane.setPrefWidth(40 + QR_WIDTH + 40);
|
||||||
|
@ -201,6 +209,20 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void changeQRDensity() {
|
||||||
|
if(animateQRService != null) {
|
||||||
|
animateQRService.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.encoder = new UREncoder(ur, Config.get().getQrDensity().getMaxFragmentLength(), MIN_FRAGMENT_LENGTH, 0);
|
||||||
|
nextPart();
|
||||||
|
if(encoder.isSinglePart()) {
|
||||||
|
qrImageView.setImage(getQrCode(currentPart));
|
||||||
|
} else {
|
||||||
|
createAnimateQRService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class AnimateQRService extends ScheduledService<Boolean> {
|
private class AnimateQRService extends ScheduledService<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
protected Task<Boolean> createTask() {
|
protected Task<Boolean> createTask() {
|
||||||
|
@ -220,6 +242,7 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
@Override
|
@Override
|
||||||
protected Node createButton(ButtonType buttonType) {
|
protected Node createButton(ButtonType buttonType) {
|
||||||
if(buttonType.getButtonData() == ButtonBar.ButtonData.LEFT) {
|
if(buttonType.getButtonData() == ButtonBar.ButtonData.LEFT) {
|
||||||
|
if(addLegacyEncodingOption) {
|
||||||
ToggleButton legacy = new ToggleButton(buttonType.getText());
|
ToggleButton legacy = new ToggleButton(buttonType.getText());
|
||||||
legacy.setGraphicTextGap(5);
|
legacy.setGraphicTextGap(5);
|
||||||
setLegacyGraphic(legacy, false);
|
setLegacyGraphic(legacy, false);
|
||||||
|
@ -232,6 +255,31 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
});
|
});
|
||||||
|
|
||||||
return legacy;
|
return legacy;
|
||||||
|
} else {
|
||||||
|
Button density = new Button(buttonType.getText());
|
||||||
|
density.setPrefWidth(160);
|
||||||
|
density.setGraphicTextGap(5);
|
||||||
|
updateDensityButton(density);
|
||||||
|
|
||||||
|
final ButtonBar.ButtonData buttonData = buttonType.getButtonData();
|
||||||
|
ButtonBar.setButtonData(density, buttonData);
|
||||||
|
density.setOnAction(event -> {
|
||||||
|
if(!initialDensityChange && !encoder.isSinglePart()) {
|
||||||
|
Optional<ButtonType> optButtonType = AppServices.showWarningDialog("Discard progress?", "Changing the QR code density means any progress on the receiving device must be discarded. Proceed?", ButtonType.NO, ButtonType.YES);
|
||||||
|
if(optButtonType.isPresent() && optButtonType.get() == ButtonType.YES) {
|
||||||
|
initialDensityChange = true;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.get().setQrDensity(Config.get().getQrDensity() == QRDensity.NORMAL ? QRDensity.LOW : QRDensity.NORMAL);
|
||||||
|
updateDensityButton(density);
|
||||||
|
changeQRDensity();
|
||||||
|
});
|
||||||
|
|
||||||
|
return density;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.createButton(buttonType);
|
return super.createButton(buttonType);
|
||||||
|
@ -244,6 +292,15 @@ public class QRDisplayDialog extends Dialog<UR> {
|
||||||
legacy.setGraphic(getGlyph(FontAwesome5.Glyph.BAN));
|
legacy.setGraphic(getGlyph(FontAwesome5.Glyph.BAN));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateDensityButton(Button density) {
|
||||||
|
density.setText(Config.get().getQrDensity() == QRDensity.NORMAL ? "Decrease Density" : "Increase Density");
|
||||||
|
if(Config.get().getQrDensity() == QRDensity.NORMAL) {
|
||||||
|
density.setGraphic(getGlyph(FontAwesome5.Glyph.MAGNIFYING_GLASS_PLUS));
|
||||||
|
} else {
|
||||||
|
density.setGraphic(getGlyph(FontAwesome5.Glyph.MAGNIFYING_GLASS_MINUS));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Glyph getGlyph(FontAwesome5.Glyph glyphName) {
|
protected static Glyph getGlyph(FontAwesome5.Glyph glyphName) {
|
||||||
|
|
|
@ -49,6 +49,8 @@ public class FontAwesome5 extends GlyphFont {
|
||||||
LINK('\uf0c1'),
|
LINK('\uf0c1'),
|
||||||
LOCK('\uf023'),
|
LOCK('\uf023'),
|
||||||
LOCK_OPEN('\uf3c1'),
|
LOCK_OPEN('\uf3c1'),
|
||||||
|
MAGNIFYING_GLASS_PLUS('\uf00e'),
|
||||||
|
MAGNIFYING_GLASS_MINUS('\uf010'),
|
||||||
MINUS_CIRCLE('\uf056'),
|
MINUS_CIRCLE('\uf056'),
|
||||||
PEN_FANCY('\uf5ac'),
|
PEN_FANCY('\uf5ac'),
|
||||||
PLUS('\uf067'),
|
PLUS('\uf067'),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.BitcoinUnit;
|
||||||
import com.sparrowwallet.sparrow.UnitFormat;
|
import com.sparrowwallet.sparrow.UnitFormat;
|
||||||
import com.sparrowwallet.sparrow.Mode;
|
import com.sparrowwallet.sparrow.Mode;
|
||||||
import com.sparrowwallet.sparrow.Theme;
|
import com.sparrowwallet.sparrow.Theme;
|
||||||
|
import com.sparrowwallet.sparrow.control.QRDensity;
|
||||||
import com.sparrowwallet.sparrow.net.*;
|
import com.sparrowwallet.sparrow.net.*;
|
||||||
import com.sparrowwallet.sparrow.wallet.FeeRatesSelection;
|
import com.sparrowwallet.sparrow.wallet.FeeRatesSelection;
|
||||||
import com.sparrowwallet.sparrow.wallet.OptimizationStrategy;
|
import com.sparrowwallet.sparrow.wallet.OptimizationStrategy;
|
||||||
|
@ -53,6 +54,7 @@ public class Config {
|
||||||
private long dustAttackThreshold = DUST_ATTACK_THRESHOLD_SATS;
|
private long dustAttackThreshold = DUST_ATTACK_THRESHOLD_SATS;
|
||||||
private File hwi;
|
private File hwi;
|
||||||
private int enumerateHwPeriod = ENUMERATE_HW_PERIOD_SECS;
|
private int enumerateHwPeriod = ENUMERATE_HW_PERIOD_SECS;
|
||||||
|
private QRDensity qrDensity;
|
||||||
private Boolean hdCapture;
|
private Boolean hdCapture;
|
||||||
private String webcamDevice;
|
private String webcamDevice;
|
||||||
private ServerType serverType;
|
private ServerType serverType;
|
||||||
|
@ -354,6 +356,15 @@ public class Config {
|
||||||
return enumerateHwPeriod;
|
return enumerateHwPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public QRDensity getQrDensity() {
|
||||||
|
return qrDensity == null ? QRDensity.NORMAL : qrDensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQrDensity(QRDensity qrDensity) {
|
||||||
|
this.qrDensity = qrDensity;
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean getHdCapture() {
|
public Boolean getHdCapture() {
|
||||||
return hdCapture;
|
return hdCapture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -841,7 +841,7 @@ public class HeadersController extends TransactionFormController implements Init
|
||||||
toggleButton.setSelected(false);
|
toggleButton.setSelected(false);
|
||||||
|
|
||||||
//TODO: Remove once Cobo Vault has upgraded to UR2.0
|
//TODO: Remove once Cobo Vault has upgraded to UR2.0
|
||||||
boolean addLegacyEncodingOption = headersForm.getSigningWallet().getKeystores().stream().anyMatch(keystore -> keystore.getWalletModel().equals(WalletModel.COBO_VAULT) || keystore.getWalletModel().equals(WalletModel.SPARROW));
|
boolean addLegacyEncodingOption = headersForm.getSigningWallet().getKeystores().stream().anyMatch(keystore -> keystore.getWalletModel().equals(WalletModel.COBO_VAULT));
|
||||||
|
|
||||||
CryptoPSBT cryptoPSBT = new CryptoPSBT(headersForm.getPsbt().serialize());
|
CryptoPSBT cryptoPSBT = new CryptoPSBT(headersForm.getPsbt().serialize());
|
||||||
QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(cryptoPSBT.toUR(), addLegacyEncodingOption);
|
QRDisplayDialog qrDisplayDialog = new QRDisplayDialog(cryptoPSBT.toUR(), addLegacyEncodingOption);
|
||||||
|
|
Loading…
Reference in a new issue