diff --git a/drongo b/drongo index 2f565570..14767c32 160000 --- a/drongo +++ b/drongo @@ -1 +1 @@ -Subproject commit 2f5655708df1b7722dfb4098cd9c79aad1a35886 +Subproject commit 14767c3250281d52c1b7da21c1ab0dc83076fda8 diff --git a/src/main/java/com/sparrowwallet/sparrow/control/AddressLabel.java b/src/main/java/com/sparrowwallet/sparrow/control/AddressLabel.java new file mode 100644 index 00000000..9965bfcf --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/AddressLabel.java @@ -0,0 +1,79 @@ +package com.sparrowwallet.sparrow.control; + +import com.sparrowwallet.drongo.Utils; +import com.sparrowwallet.drongo.address.Address; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Tooltip; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; + +public class AddressLabel extends IdLabel { + private final ObjectProperty
addressProperty = new SimpleObjectProperty<>(); + + private Tooltip tooltip; + private AddressContextMenu contextMenu; + + public AddressLabel() { + this(""); + } + + public AddressLabel(String text) { + super(text); + addressProperty().addListener((observable, oldValue, newValue) -> { + setAddressAsText(newValue); + contextMenu.copyHex.setText("Copy " + newValue.getOutputScriptDataType()); + }); + + tooltip = new Tooltip(); + contextMenu = new AddressContextMenu(); + } + + public final ObjectProperty
addressProperty() { + return addressProperty; + } + + public final Address getAddress() { + return addressProperty.get(); + } + + public final void setAddress(Address value) { + this.addressProperty.set(value); + } + + private void setAddressAsText(Address address) { + if(address != null) { + tooltip.setText(address.getScriptType() + " " + Utils.bytesToHex(address.getOutputScriptData())); + setTooltip(tooltip); + setContextMenu(contextMenu); + setText(address.toString()); + } + } + + private class AddressContextMenu extends ContextMenu { + private MenuItem copyAddress; + private MenuItem copyHex; + + public AddressContextMenu() { + copyAddress = new MenuItem("Copy Address"); + copyAddress.setOnAction(AE -> { + hide(); + ClipboardContent content = new ClipboardContent(); + content.putString(getAddress().toString()); + Clipboard.getSystemClipboard().setContent(content); + }); + + copyHex = new MenuItem("Copy Script Output Bytes"); + copyHex.setOnAction(AE -> { + hide(); + ClipboardContent content = new ClipboardContent(); + content.putString(Utils.bytesToHex(getAddress().getOutputScriptData())); + Clipboard.getSystemClipboard().setContent(content); + }); + + getItems().addAll(copyAddress, copyHex); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java new file mode 100644 index 00000000..ac70c9cb --- /dev/null +++ b/src/main/java/com/sparrowwallet/sparrow/control/CoinLabel.java @@ -0,0 +1,88 @@ +package com.sparrowwallet.sparrow.control; + +import com.sparrowwallet.drongo.protocol.Transaction; +import javafx.beans.property.LongProperty; +import javafx.beans.property.SimpleLongProperty; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.MenuItem; +import javafx.scene.control.Tooltip; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +public class CoinLabel extends CopyableLabel { + public static final int MAX_SATS_SHOWN = 1000000; + + private DecimalFormat btcFormat = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + + private final LongProperty value = new SimpleLongProperty(); + private Tooltip tooltip; + private CoinContextMenu contextMenu; + + public CoinLabel() { + this("Unknown"); + } + + public CoinLabel(String text) { + super(text); + btcFormat.setMaximumFractionDigits(8); + valueProperty().addListener((observable, oldValue, newValue) -> setValueAsText((Long)newValue)); + tooltip = new Tooltip(); + contextMenu = new CoinContextMenu(); + } + + public final LongProperty valueProperty() { + return value; + } + + public final long getValue() { + return value.get(); + } + + public final void setValue(long value) { + this.value.set(value); + } + + private void setValueAsText(Long value) { + setTooltip(tooltip); + setContextMenu(contextMenu); + + String satsValue = String.format(Locale.ENGLISH, "%,d",value) + " sats"; + String btcValue = btcFormat.format(value.doubleValue() / Transaction.SATOSHIS_PER_BITCOIN) + " BTC"; + if(value > MAX_SATS_SHOWN) { + tooltip.setText(satsValue); + setText(btcValue); + } else { + tooltip.setText(btcValue); + setText(satsValue); + } + } + + private class CoinContextMenu extends ContextMenu { + private MenuItem copySatsValue; + private MenuItem copyBtcValue; + + public CoinContextMenu() { + copySatsValue = new MenuItem("Copy Value in Satoshis"); + copySatsValue.setOnAction(AE -> { + hide(); + ClipboardContent content = new ClipboardContent(); + content.putString(Long.toString(getValue())); + Clipboard.getSystemClipboard().setContent(content); + }); + + copyBtcValue = new MenuItem("Copy Value in BTC"); + copyBtcValue.setOnAction(AE -> { + hide(); + ClipboardContent content = new ClipboardContent(); + content.putString(btcFormat.format((double)getValue() / Transaction.SATOSHIS_PER_BITCOIN)); + Clipboard.getSystemClipboard().setContent(content); + }); + + getItems().addAll(copySatsValue, copyBtcValue); + } + } +} diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java index 16a97013..cc64268c 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.sparrow.EventManager; +import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.IdLabel; import com.sparrowwallet.sparrow.control.CopyableLabel; import com.sparrowwallet.sparrow.event.TransactionChangedEvent; @@ -71,7 +72,7 @@ public class HeadersController extends TransactionFormController implements Init private CopyableLabel virtualSize; @FXML - private CopyableLabel fee; + private CoinLabel fee; @FXML private CopyableLabel feeRate; @@ -178,11 +179,9 @@ public class HeadersController extends TransactionFormController implements Init } if(feeAmt != null) { - fee.setText(feeAmt + " sats"); + fee.setValue(feeAmt); double feeRateAmt = feeAmt.doubleValue() / tx.getVirtualSize(); feeRate.setText(String.format("%.2f", feeRateAmt) + " sats/vByte"); - } else { - fee.setText("Unknown"); } } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java index c7b1c065..f590d447 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputController.java @@ -6,9 +6,7 @@ import com.sparrowwallet.drongo.crypto.ECKey; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBTInput; import com.sparrowwallet.sparrow.EventManager; -import com.sparrowwallet.sparrow.control.IdLabel; -import com.sparrowwallet.sparrow.control.CopyableLabel; -import com.sparrowwallet.sparrow.control.RelativeTimelockSpinner; +import com.sparrowwallet.sparrow.control.*; import com.sparrowwallet.sparrow.event.TransactionChangedEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -40,13 +38,13 @@ public class InputController extends TransactionFormController implements Initia private Button outpointSelect; @FXML - private CopyableLabel spends; + private CoinLabel spends; @FXML private CopyableLabel from; @FXML - private IdLabel address; + private AddressLabel address; @FXML private CodeArea scriptSigArea; @@ -127,7 +125,6 @@ public class InputController extends TransactionFormController implements Initia inputFieldset.setText("Input #" + txInput.getIndex()); outpoint.setText(txInput.getOutpoint().getHash().toString() + ":" + txInput.getOutpoint().getIndex()); - spends.setText("Unknown"); from.setVisible(false); if(psbtInput != null) { TransactionOutput output = null; @@ -138,12 +135,12 @@ public class InputController extends TransactionFormController implements Initia } if(output != null) { - spends.setText(output.getValue() + " sats"); + spends.setValue(output.getValue()); try { Address[] addresses = output.getScript().getToAddresses(); from.setVisible(true); if(addresses.length == 1) { - address.setText(addresses[0].getAddress()); + address.setAddress(addresses[0]); } else { address.setText("multiple addresses"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java index e4c73575..ae3c0a5b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/InputsController.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.protocol.*; import com.sparrowwallet.drongo.psbt.PSBTInput; +import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CopyableLabel; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -19,7 +20,7 @@ public class InputsController extends TransactionFormController implements Initi private CopyableLabel count; @FXML - private CopyableLabel total; + private CoinLabel total; @FXML private CopyableLabel signatures; @@ -41,7 +42,6 @@ public class InputsController extends TransactionFormController implements Initi Transaction tx = inputsForm.getTransaction(); count.setText(Integer.toString(tx.getInputs().size())); - total.setText("Unknown"); signatures.setText("Unknown"); if(inputsForm.getPsbt() != null) { @@ -84,7 +84,7 @@ public class InputsController extends TransactionFormController implements Initi for(TransactionOutput output : outputs) { totalAmt += output.getValue(); } - total.setText(totalAmt + " sats"); + total.setValue(totalAmt); if(showDenominator) { signatures.setText(foundSigs + "/" + reqSigs); } else { diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java index 5e31502d..2b256b1a 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputController.java @@ -3,7 +3,8 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.address.Address; import com.sparrowwallet.drongo.protocol.NonStandardScriptException; import com.sparrowwallet.drongo.protocol.TransactionOutput; -import com.sparrowwallet.sparrow.control.IdLabel; +import com.sparrowwallet.sparrow.control.AddressLabel; +import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CopyableLabel; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -20,13 +21,13 @@ public class OutputController extends TransactionFormController implements Initi private Fieldset outputFieldset; @FXML - private CopyableLabel value; + private CoinLabel value; @FXML private CopyableLabel to; @FXML - private IdLabel address; + private AddressLabel address; @FXML private CodeArea scriptPubKeyArea; @@ -41,13 +42,13 @@ public class OutputController extends TransactionFormController implements Initi outputFieldset.setText("Output #" + txOutput.getIndex()); - value.setText(txOutput.getValue() + " sats"); + value.setValue(txOutput.getValue()); to.setVisible(false); try { Address[] addresses = txOutput.getScript().getToAddresses(); to.setVisible(true); if(addresses.length == 1) { - address.setText(addresses[0].getAddress()); + address.setAddress(addresses[0]); } else { address.setText("multiple addresses"); } diff --git a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputsController.java b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputsController.java index 89f50057..155d0274 100644 --- a/src/main/java/com/sparrowwallet/sparrow/transaction/OutputsController.java +++ b/src/main/java/com/sparrowwallet/sparrow/transaction/OutputsController.java @@ -2,6 +2,7 @@ package com.sparrowwallet.sparrow.transaction; import com.sparrowwallet.drongo.protocol.Transaction; import com.sparrowwallet.drongo.protocol.TransactionOutput; +import com.sparrowwallet.sparrow.control.CoinLabel; import com.sparrowwallet.sparrow.control.CopyableLabel; import javafx.fxml.FXML; import javafx.fxml.Initializable; @@ -17,7 +18,7 @@ public class OutputsController extends TransactionFormController implements Init private CopyableLabel count; @FXML - private CopyableLabel total; + private CoinLabel total; @FXML private PieChart outputsPie; @@ -40,7 +41,7 @@ public class OutputsController extends TransactionFormController implements Init for(TransactionOutput output : tx.getOutputs()) { totalAmt += output.getValue(); } - total.setText(totalAmt + " sats"); + total.setValue(totalAmt); if(totalAmt > 0) { addPieData(outputsPie, tx.getOutputs()); diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml index e349b9ce..b3b65b88 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/headers.fxml @@ -13,6 +13,7 @@ + @@ -92,7 +93,7 @@
- + diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml index 98d7ecd2..7ba40827 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/input.fxml @@ -14,6 +14,8 @@ + + @@ -40,9 +42,9 @@ - + - +
diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml index 04660a8f..32e5dda1 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/inputs.fxml @@ -6,6 +6,7 @@ + @@ -26,7 +27,7 @@ - + diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml index c33a55d1..1692dd5c 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/output.fxml @@ -12,7 +12,8 @@ - + + @@ -31,9 +32,9 @@
- + - +
diff --git a/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml b/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml index bae25fcc..33838d4e 100644 --- a/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml +++ b/src/main/resources/com/sparrowwallet/sparrow/transaction/outputs.fxml @@ -6,6 +6,7 @@ + @@ -26,7 +27,7 @@ - +